MediaRecorder 捕获的音频文件在使用 Retrofit 2 发送到服务器后被破坏

2024-01-08

我的应用程序录制一个音频片段,并在录制完成后使用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)

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


Your setAudioEncodingBitRate非常低。

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

尝试使用 16000 或 32000setAudioEncodingBitRate value

在这里评论是否有效,我会尽力帮助你

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MediaRecorder 捕获的音频文件在使用 Retrofit 2 发送到服务器后被破坏 的相关文章

随机推荐