使用Retrofit 2将MediaRecorder捕获的音频文件发送到服务器后,该文件损坏了 [英] Audio file captured by MediaRecorder is broken after it is sent to server using Retrofit 2
问题描述
我的应用程序录制了音频剪辑,并在录制完成后使用Retrofit2将剪辑发送到服务器.该文件已在服务器中接收到,但文件已损坏,我的意思是无法播放.我使用以下URL(例如url:mydomain.co/audio/myaudio.mp4
)播放音频片段,我尝试使用postman
与另一个音频文件一起播放,音频文件可以成功播放.此外,甚至可以通过以下方式下载android捕获的音频片段Filezilla
也具有相同的损坏文件.
My app records an audio clip and send the clip to the server using Retrofit2 after the recording is completed.The file is received in server,but the file is broken,what I mean by broken is that it cannot be played. I use the following URL(example url:mydomain.co/audio/myaudio.mp4
) to play the audio clip,which I tried with another audio file using postman
,the audio file can be played successfully.Besides,even downloading the audio clip captured by android via Filezilla
also has the same broken file.
这是我录制音频的方式:
This is how I record the audio:
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();
}
}
这是音频文件的文件路径:
Here is the file path of the audio files:
/storage/emulated/0/DCIM/myapp/AUDIO_20171023143717.mp4
/storage/emulated/0/DCIM/myapp/AUDIO_20171023143717.mp4
为解决此问题,我尝试使用不同的编解码器和不同的输出格式,如下所示
To solve this,I tried using different codec and different output format,as follows
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
和.3gpp
,但是它们似乎都无法在服务器端工作.
为了清楚起见,我附加了用于使用Retrofit2
将音频文件发送到服务器的代码:
I have also tried to change the file extension to .mp3
, .mp4
and .3gpp
as well,but none of them seem to work on the server side.
To make things clear, I've attach the code which I used to send the audio file to server using 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将音频文件发送到服务器的正确方法是什么?
1)what is the correct way to send the audio file to server from android?
2)如果问题与录音机的编解码器有关,什么是正确的音频文件编解码器?稍后导致相同的音频,我也需要支持Ios和网站.
2) if the problem is about the codec for the audio recorder,what is the correct codec for audio file? Cause later the same audio I need to support Ios and website as well..
请有人提出建议.谢谢!
Somebody please give some suggestion.Thanks in advance
我尝试使用MediaPlayer
播放录制的音频文件,文件路径如下
I try to play the recorded audio file using MediaPlayer
,the file path is like this
/storage/emulated/0/DCIM/Myapp/AUDIO_20171026135950.mp4
/storage/emulated/0/DCIM/Myapp/AUDIO_20171026135950.mp4
这是我的代码,可以播放上面的音频文件
Here is my code to play the audio file above
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();
}
}
});
但是,当我播放本地音频文件时,它引发了以下异常:
But it throws me the following exception, when I play the local audio file:
W/MediaPlayer:无法在客户端打开文件;尝试服务器端: java.io.FileNotFoundException:没有内容提供者: /storage/emulated/0/DCIM/Myapp/AUDIO_20171026135950.mp4
W/MediaPlayer: Couldn't open file on client side; trying server side: java.io.FileNotFoundException: No content provider: /storage/emulated/0/DCIM/Myapp/AUDIO_20171026135950.mp4
如果我播放服务器中的URL,则会抛出此异常:
If I play the URL from server,it throw this exception:
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)
那我在做什么错了?
推荐答案
您的setAudioEncodingBitRate
非常低.
在16hz时应为16000,而不仅仅是16h
使用setAudioEncodingBitRate
值的16000或32000尝试
try it with 16000 or 32000 in setAudioEncodingBitRate
value
在这里评论是否可行,我会尽力帮助您
comment here if it works or not, i'll try to help you out more
这篇关于使用Retrofit 2将MediaRecorder捕获的音频文件发送到服务器后,该文件损坏了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!