【问题标题】:Audio file captured by MediaRecorder is broken after it is sent to server using Retrofit 2MediaRecorder 捕获的音频文件在使用 Retrofit 2 发送到服务器后被破坏
【发布时间】:2018-04-03 14:54:14
【问题描述】:

我的应用程序录制了一个音频剪辑,并在录制完成后使用 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();
    }
}

这是音频文件的文件路径:

/storage/emulated/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.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 和网站的相同音频..

有人请给点建议。在此先感谢

编辑:

我尝试使用MediaPlayer播放录制的音频文件,文件路径是这样的

/storage/emulated/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:没有内容提供者: /storage/emulated/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)

那么我在这里做错了什么?

【问题讨论】:

  • 你的音频文件可以在你的安卓手机上播放吗?
  • @HarisQureshi 嘿兄弟,我只是测试使用MediaPlayer 播放音频文件,但它抛出了异常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
  • @HarisQureshi 嘿兄弟,我更新了问题,请看一下
  • 尝试分别去掉比特和采样率并检查。
  • 我删除了比特和采样率,但是当我尝试播放它时,异常仍然相同

标签: android audio retrofit2 android-mediacodec mediarecorder


【解决方案1】:

您的setAudioEncodingBitRate 很低。

16hz 应该是 16000 而不仅仅是 16

setAudioEncodingBitRate 值中尝试 16000 或 32000

在此评论是否有效,我会尽力为您提供更多帮助

【讨论】:

  • 我将值更改为 16000 和 32000 并使用模拟器进行测试..但它仍然无法工作,无法在我分配给它的 URL 中播放
  • Emulator 大多失败,MediaRecorder 在真机上试试!在 Android 开发人员指南中说明 注意:目前,MediaRecorder 不适用于模拟器。 developer.android.com/reference/android/media/…
  • 好的好兄弟..这很好..让我再测试一次,让你..真的谢谢你
  • @ken 如果您在录制时也有任何质量问题,请告诉我。如果它有帮助,如果您能评价答案,我将不胜感激。干杯!
  • 嘿兄弟,我用真机测试过,按照你说的设置值,但是在服务器上,我还是不能播放音频文件..
猜你喜欢
  • 2019-10-04
  • 2011-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
  • 2023-04-10
相关资源
最近更新 更多