我的应用程序录制一个音频片段,并在录制完成后使用Retrofit2将片段发送到服务器。服务器收到文件,但文件已损坏,我所说的损坏是指无法播放。我使用以下 URL(示例 url:mydomain.co/audio/myaudio.mp4
)播放音频剪辑,我尝试使用另一个音频文件postman
,音频文件可以成功播放。此外,甚至可以通过下载android捕获的音频片段Filezilla
也有相同的损坏文件。
这就是我录制音频的方式:
private void startRecordingAudio() {
Log.d("audiorecording","recording sound");
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setAudioEncodingBitRate(16);
recorder.setAudioSamplingRate(44100);
MediaFileHelper fileHelper = new MediaFileHelper();
audioOutputFile = fileHelper.getOutputAudioFile();
recorder.setOutputFile(audioOutputFile.getAbsolutePath());
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
}
这是音频文件的文件路径:
/存储/模拟/0/DCIM/myapp/AUDIO_20171023143717.mp4
为了解决这个问题,我尝试使用不同的编解码器和不同的输出格式,如下
recorder.setOutputFormat(MediaRecorder.OutputFormat.THERE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THERE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);
我还尝试将文件扩展名更改为.mp3
, .mp4
and .3gpp
同样,但它们似乎都不能在服务器端工作。
为了清楚起见,我附加了用于将音频文件发送到服务器的代码Retrofit2
:
private void sendAudioToServer( final String audioFilePath,final String api_key){
Log.d("AUDIO FILE PATH",audioFilePath);
File audioFile = new File(audioFilePath);
RequestBody audioBody = RequestBody.create(MediaType.parse("audio/*"), audioFilePath);
MultipartBody.Part aFile = MultipartBody.Part.createFormData("audio", audioFile.getName(), audioBody);
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.Request.Builder ongoing = chain.request().newBuilder();
ongoing.addHeader("authorization", api_key);
return chain.proceed(ongoing.build());
}
})
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(AppConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
AudioInterface audioInterface = retrofit.create(AudioInterface.class);
Call<ResultObject> serverCom = audioInterface.sendAudioToServer(aFile);
serverCom.enqueue(new Callback<ResultObject>() {
@Override
public void onResponse(Call<ResultObject> call, retrofit2.Response<ResultObject> response) {
ResultObject result = response.body();
if(!TextUtils.isEmpty(result.getSuccess())){
Log.d("audio Result " , result.getSuccess());
}
}
@Override
public void onFailure(Call<ResultObject> call, Throwable t) {
Log.d("audio error",t.toString());
}
});
}
我的问题是:
1)从android发送音频文件到服务器的正确方法是什么?
2)如果问题与录音机的编解码器有关,那么音频文件的正确编解码器是什么?因为稍后我也需要支持 Ios 和网站相同的音频..
有人请给一些建议。提前致谢
Edit:
我尝试使用播放录制的音频文件MediaPlayer
,文件路径是这样的
/存储/模拟/0/DCIM/Myapp/AUDIO_20171026135950.mp4
这是我播放上面音频文件的代码
String audioFile = " /storage/emulated/0/DCIM/Myapp/AUDIO_20171026135950.mp4";
audioButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaPlayer mp = new MediaPlayer();
Uri uri = Uri.parse(audioFile);
try{
mp.setDataSource(mContext,uri);
mp.prepare();
mp.start();
}catch (IOException E){
E.printStackTrace();
}
}
});
但当我播放本地音频文件时,它会引发以下异常:
W/MediaPlayer:无法在客户端打开文件;尝试服务器端:
java.io.FileNotFoundException:没有内容提供者:
/存储/模拟/0/DCIM/Myapp/AUDIO_20171026135950.mp4
如果我从服务器播放 URL,它会抛出此异常:
10-26 14:06:05.551 8806-8806/? W/System.err: java.io.IOException: Prepare failed.: status=0x1
10-26 14:06:05.552 8806-8806/? W/System.err: at android.media.MediaPlayer._prepare(Native Method)
10-26 14:06:05.552 8806-8806/? W/System.err: at android.media.MediaPlayer.prepare(MediaPlayer.java:1163)
10-26 14:06:05.552 8806-8806/? W/System.err: at android.view.View.performClick(View.java:5198)
10-26 14:06:05.552 8806-8806/? W/System.err: at android.view.View$PerformClick.run(View.java:21147)
10-26 14:06:05.552 8806-8806/? W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
10-26 14:06:05.552 8806-8806/? W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
10-26 14:06:05.552 8806-8806/? W/System.err: at android.os.Looper.loop(Looper.java:148)
10-26 14:06:05.552 8806-8806/? W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
10-26 14:06:05.552 8806-8806/? W/System.err: at java.lang.reflect.Method.invoke(Native Method)
10-26 14:06:05.552 8806-8806/? W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
10-26 14:06:05.552 8806-8806/? W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
那么我在这里做错了什么?