Android MediaCodec 录制系统音频功能实现完整代码
时间: 2023-11-15 12:09:38 浏览: 95
以下是使用Android的MediaCodec录制系统音频的完整代码:
```java
public class AudioRecorder {
private static final String TAG = "AudioRecorder";
private static final String MIME_TYPE = "audio/mp4a-latm";
private static final int SAMPLE_RATE = 44100;
private static final int BIT_RATE = 64000;
private static final int CHANNEL_COUNT = 2;
private static final int TIMEOUT_US = 10000;
private MediaCodec mMediaCodec;
private AudioRecord mAudioRecord;
private boolean mIsRecording;
private ByteBuffer[] mInputBuffers;
private ByteBuffer[] mOutputBuffers;
public void startRecording(String filePath) throws IOException {
mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
MediaFormat format = MediaFormat.createAudioFormat(MIME_TYPE, SAMPLE_RATE, CHANNEL_COUNT);
format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mMediaCodec.start();
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
CHANNEL_COUNT == 1 ? AudioFormat.CHANNEL_IN_MONO : AudioFormat.CHANNEL_IN_STEREO,
AudioFormat.ENCODING_PCM_16BIT, AudioRecord.getMinBufferSize(SAMPLE_RATE,
CHANNEL_COUNT == 1 ? AudioFormat.CHANNEL_IN_MONO : AudioFormat.CHANNEL_IN_STEREO,
AudioFormat.ENCODING_PCM_16BIT) * 2);
mAudioRecord.startRecording();
mIsRecording = true;
new Thread(new Runnable() {
@Override
public void run() {
try {
writeDataToFile(filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void writeDataToFile(String filePath) throws IOException {
FileOutputStream fos = new FileOutputStream(filePath);
while (mIsRecording) {
int inputBufferIndex = mMediaCodec.dequeueInputBuffer(TIMEOUT_US);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = mInputBuffers[inputBufferIndex];
inputBuffer.clear();
int length = mAudioRecord.read(inputBuffer, inputBuffer.capacity());
if (length > 0) {
mMediaCodec.queueInputBuffer(inputBufferIndex, 0, length, System.nanoTime() / 1000, 0);
}
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = mOutputBuffers[outputBufferIndex];
outputBuffer.position(bufferInfo.offset);
outputBuffer.limit(bufferInfo.offset + bufferInfo.size);
byte[] chunkAudio = new byte[bufferInfo.size];
outputBuffer.get(chunkAudio);
fos.write(chunkAudio);
mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US);
}
}
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
mAudioRecord.stop();
mAudioRecord.release();
mMediaCodec.stop();
mMediaCodec.release();
}
}
```
在上述代码中,我们使用了Android的`MediaCodec`和`AudioRecord` API来进行音频录制。在`startRecording()`方法中,我们首先创建了一个`MediaCodec`对象,用于进行编码操作。然后,我们创建了一个`AudioRecord`对象,并按照指定的参数进行了初始化。最后,我们启动了一个新线程,将音频数据写入到指定的文件中。
在`writeDataToFile()`方法中,我们首先从`AudioRecord`对象读取音频数据并将其填充到`MediaCodec`的输入缓冲区中。接下来,我们从`MediaCodec`的输出缓冲区中读取编码后的音频数据,并将其写入到指定的文件中。循环进行上述操作直到停止录制。
需要注意的是,这段代码只是一个简单的示例,还需要根据具体的应用场景进行适当的调整。例如,可以添加错误处理和异常情况的处理逻辑。
阅读全文