即时音频输入和输出Android

在我的Android应用程序中,我想从智能手机的麦克风中获取一些音频并立即播放,像麦克风一样直播,没有延迟。 我目前正在考虑使用AudioRecordAudioTrack类(从我读过的内容),但我不太清楚如何继续。

我查看了Stack Overflow上的其他一些问题,但是他们并没有完全回答我想做的事情。 大多数是2012年。

那么如何使用这些类同时输入和输出音频呢?

另外:我看过MediaRecorder API ,但是根据我的阅读,这需要你将音频保存到文件中,我不想这样做。 可以通过tweek来满足我的要求吗? 或者我最好只使用AudioRecord

谢谢

编辑:

以下是我在@Pradip Pramanick建议的更新代码:

 final Thread record = new Thread(new Runnable() { @Override public void run() { while (!Thread.interrupted()) { MediaRecorder microphone = new MediaRecorder(); microphone.setAudioSource(MediaRecorder.AudioSource.MIC); microphone.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); microphone.setOutputFile(filename); microphone.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); try { microphone.prepare(); } catch (IOException e) { e.printStackTrace(); } microphone.start(); } } }); final Thread play = new Thread(new Runnable() { @Override public void run() { while (!Thread.interrupted()) { player = new MediaPlayer(); try { player.setDataSource(filename); player.prepare(); player.start(); } catch (IOException e) { e.printStackTrace(); } } } }); 

我得到了Illegal State Exception | Start failed: -38 Illegal State Exception | Start failed: -38 。 但我在使用microphone.start之后调用了microphone.start 。启动……这似乎是什么问题? 我搜索了其他线程,说可能有其他背景应用程序使用麦克风。 我搜索了我的设备:Moto X Play(第三代)并没有find。 (我甚至关闭了“Ok Google”语音识别,但错误不断出现)。

错误日志:

这是显示最新错误的log-cat:

 01-31 09:37:21.064 344-3339/? E/MediaPlayerService: offset error 01-31 09:37:21.065 1835-1922/com.synerflow.testapp E/MediaPlayer: Unable to create media player 01-31 09:37:21.065 1835-1922/com.synerflow.testapp I/Player: player.prepare() has failed 01-31 09:37:21.065 1835-1922/com.synerflow.testapp W/System.err: java.io.IOException: setDataSourceFD failed.: status=0x80000000 

IO Exception似乎在player.setDataSource(filename) ,filenamevariables是一个字符串: Environment.getExternalStorageDirectory().getAbsolutePath() + "\voice.3gp"

据我所知,它可以用一种非常简单的方式完成。 我没试过,但你试试看。 我认为它会起作用:

创建两个线程,用于录制另一个用于播放。 假设线程是TRecord和TPlay。

在TRecord的run方法中执行以下操作:

 public void run(){ MediaRecorder mRecorder = null; mRecorder = new MediaRecorder(); mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mRecorder.setOutputFile(mFileName); mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); try { mRecorder.prepare(); } catch (IOException e) { //todo } mRecorder.start(); } 

而TPlay的run方法做到了这一点:

 public void run() { MediaPlayer mPlayer = null; mPlayer = new MediaPlayer(); try { mPlayer.setDataSource(mFileName); mPlayer.prepare(); mPlayer.start(); } catch (IOException e) { //todo } } 

现在,在mainactivity上只需创建两个线程。 首先启动TRecord线程,然后启动Tplay。 尝试一下。

这是文件扩展名的代码:

 mFileName = Environment.getExternalStorageDirectory().getAbsolutePath(); mFileName += "/audiorecordtest.3gp"; 

这在Android上实际上非常棘手。 谷歌自己有一个非常好(但略长)的video来解释这些问题。

他们还有一个页面,解释了各种设备的延迟测试方法和基准 。

从本质上讲,股票Android不能做零延迟音频,但没有什么能阻止硬件合作伙伴添加所需的硬件和平台扩展。

尝试这个。 我还没跑过这个。

  recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSize * BytesPerElement); recorder.startRecording(); isRecording = true; recordingThread = new Thread(new Runnable() { public void run() { try { int intSize = android.media.AudioTrack.getMinBufferSize(RECORDER_SAMPLERATE,AudioFormat.CHANNEL_OUT_MONO , RECORDER_AUDIO_ENCODING); byte[] sData = new byte[bufferSize]; AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, RECORDER_SAMPLERATE, AudioFormat.CHANNEL_OUT_MONO, RECORDER_AUDIO_ENCODING, intSize, AudioTrack.MODE_STREAM); while(isRecording){ recorder.read(sData, 0, bufferSize); //isRecording = false; onStop button if (at!=null) { at.play(); // Write the byte array to the track at.write(sData, 0, sData.length); at.stop(); at.release(); } } } catch (IOException e) { e.printStackTrace(); } } }, "AudioRecorder Thread"); recordingThread.start();