如何从录音机流式传输音频并同时另存为音频文件?

问题描述

在audioRecorder使用OkHttp录制时,我想将音频流传输到服务器。同时,我想将音频记录为Android设备本地的音频文件

这是我尝试的方法

我如何录制音频:

private void startRecordAudio() {
        audioRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC,SAMPLE_RATE,CHANNEL,AUdio_FORMAT,BUFFER_SIZE);
        audioRecorder.startRecording();
        recordingProgress.set(true);
        recordingThread = new Thread(new StreamRecordingRunnable(),"Stream Recording");
        recordingThread.start();
}

然后在StreamRecordingRunnable()中这样做:

private class StreamRecordingRunnable implements  Runnable{

        @Override
        public void run() {
            final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);

            RequestBody requestBody = new RequestBody() {
                @Nullable
                @Override
                public MediaType contentType() {
                    return MediaType.parse("audio/raw;encoding=signed-integer;bits=16;rate=8000;endian=little;");
                }

                @Override
                public void writeto(@NonNull BufferedSink sink) throws IOException {
                    while(recordingProgress.get()){
                        int result = audioRecorder.read(buffer,BUFFER_SIZE);

                        if(result < 0){
                            Log.d(LOG_TAG," Some streaming error here");

                        }else{
                            Log.d(LOG_TAG," No problem here");
                            writeAudioDataToFile(); // Here I want to save the audio file before it send to server.
                            sink.write(buffer);
                            buffer.clear();
                        }

                    }
                }
            };
        

            Request request = httpRequestBuilder.post(requestBody).build();
            try(Response response = httpClient.newCall(request).execute()){
                if(response.isSuccessful()){
                    Log.v("OKHTTP",response.body().string());
                }else{
                    Log.d("http not successful",String.valueOf(response.body()));
                }

            }catch (IOException e){
                Log.d("HTTP",e.getMessage());
            }


        }
    }

完成上述所有代码后,我可以在录音机开始录音的同时发送音频文件。我可以在服务器中获取音频文件

我现在要做的是:

制作一个writeAudioDataToFile()函数,希望它可以将音频(将发送到服务器)存储到本地Android设备中的本地文件中。

这是我为writeAudioDataToFile()尝试的内容,应该存储在名为audiotest12345.wav文件中:

    int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
    int BytesPerElement = 2;
    String filePath;

    private void writeAudioDataToFile() {
        // Write the output audio in byte

        filePath = getExternalCacheDir().getAbsolutePath();
        filePath += "/audiorecordtest12345.wav";

        short sData[] = new short[BufferElements2Rec];

        FileOutputStream os = null;
        try {
            os = new FileOutputStream(filePath);
        } catch (FileNotFoundException e) {
            e.printstacktrace();
        }

        while (recordingProgress.get()) {
            // gets the voice output from microphone to byte format

            audioRecorder.read(sData,BufferElements2Rec);
            System.out.println("Short wirting to file" + sData.toString());
            try {
                // // writes the data to file from buffer
                // // stores the voice buffer
                byte bData[] = short2byte(sData);
                os.write(bData,BufferElements2Rec * BytesPerElement);

                Log.d("file name",filePath);
            } catch (IOException e) {
                e.printstacktrace();
            }
        }
        try {
            os.close();
        } catch (IOException e) {
            e.printstacktrace();
        }
    }

    private byte[] short2byte(short[] sData) {
        int shortArrsize = sData.length;
        byte[] bytes = new byte[shortArrsize * 2];
        for (int i = 0; i < shortArrsize; i++) {
            bytes[i * 2] = (byte) (sData[i] & 0x00FF);
            bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
            sData[i] = 0;
        }
        return bytes;

    } 

结果:

但是,这样做不仅没有在本地保存文件,而且还无法发送到服务器。在那里,我也尝试过:

private class StreamRecordingRunnable implements  Runnable{

        @Override
        public void run() {
            writeAudioDataToFile();
            final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);

            //..all the RequestBody and networking call same as above
        }
}

如果我只执行1个操作就意味着仅保存文件或仅发送到服务器,则该代码有效。但是,当我同时执行此操作时,将无法正常工作。

然后我从audiotest12345.wav签入了文件路径adb shell,该文件存在,但是当使用mediaPlayer播放时,文件路径为空。

这应该是因为1台设备中只能有1支麦克风。但是我不知道该怎么做才能同时完成两个操作

因此这是我的问题:

  1. 如何从录音机保存音频文件并将其同时发送到服务器?

  2. 我现在想的是,应该保存BufferedSink值中的数据吗?但是我不知道该怎么做,因为我是Okio的BufferedSink的新手,所以不太了解它的含义。

  3. 因此,请尽可能说明BufferedSink的用途

请为我指出正确的方向。预先感谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)