使用Retrofit 2将MediaRecorder捕获的音频文件发送到服务器后,该文件损坏了 [英] Audio file captured by MediaRecorder is broken after it is sent to server using Retrofit 2

查看:97
本文介绍了使用Retrofit 2将MediaRecorder捕获的音频文件发送到服务器后,该文件损坏了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序录制了音频剪辑,并在录制完成后使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆