返回

Android音频开发:入门指南

Android

Android 音频开发指南:录制、播放、编码和解码

一、音频录制

Android 为音频录制提供了 AudioRecord 类,它可让您指定音频源、采样率、声道数和编码格式。该类使用缓冲区存储音频数据,并在录制过程中通过回调函数将数据发送给应用层。

代码示例:

AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
        44100,
        AudioFormat.CHANNEL_IN_MONO,
        AudioFormat.ENCODING_PCM_16BIT,
        bufferSize);

recorder.startRecording();

while (recording) {
    int bytesRead = recorder.read(buffer, 0, bufferSize);
    // 将 buffer 中的数据发送给应用层
}

recorder.stop();

二、音频播放

要播放音频,Android 提供了 AudioTrack 类,它支持指定音频源、采样率、声道数和编码格式。该类从缓冲区中读取音频数据,并通过扬声器或耳机将其播放。

代码示例:

AudioTrack player = new AudioTrack(AudioManager.STREAM_MUSIC,
        44100,
        AudioFormat.CHANNEL_OUT_MONO,
        AudioFormat.ENCODING_PCM_16BIT,
        bufferSize,
        AudioTrack.MODE_STREAM);

player.play();

while (playing) {
    int bytesRead = audioInputStream.read(buffer, 0, bufferSize);
    if (bytesRead == -1) {
        break;
    }
    player.write(buffer, 0, bytesRead);
}

player.stop();

三、音频编码

音频编码涉及将音频数据从一种格式转换为另一种格式。Android 使用 MediaCodec 类支持编码。您可以指定编码器类型、采样率、声道数和比特率。MediaCodec 会从输入缓冲区读取音频数据,将其编码为指定的格式,并将其存储在输出缓冲区中。

代码示例:

MediaCodec encoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);

MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AAC);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);

encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

encoder.start();

while (encoding) {
    int inputBufferIndex = encoder.dequeueInputBuffer(timeoutUs);
    if (inputBufferIndex >= 0) {
        ByteBuffer inputBuffer = encoder.getInputBuffer(inputBufferIndex);
        inputBuffer.put(buffer);
        encoder.queueInputBuffer(inputBufferIndex, 0, buffer.length, 0, 0);
    }

    int outputBufferIndex = encoder.dequeueOutputBuffer(info, timeoutUs);
    if (outputBufferIndex >= 0) {
        ByteBuffer outputBuffer = encoder.getOutputBuffer(outputBufferIndex);
        outputBuffer.position(info.offset);
        outputBuffer.limit(info.offset + info.size);
        // 将 outputBuffer 中的数据发送给应用层
        encoder.releaseOutputBuffer(outputBufferIndex, false);
    }
}

encoder.stop();

四、音频解码

类似地,音频解码使用 MediaCodec 类将音频数据从一种格式转换为另一种格式。您需要指定解码器类型、采样率、声道数和比特率。MediaCodec 会从输入缓冲区读取音频数据,将其解码为指定的格式,并将其存储在输出缓冲区中。

代码示例:

MediaCodec decoder = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);

MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AAC);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);

decoder.configure(format, null, null, 0);

decoder.start();

while (decoding) {
    int inputBufferIndex = decoder.dequeueInputBuffer(timeoutUs);
    if (inputBufferIndex >= 0) {
        ByteBuffer inputBuffer = decoder.getInputBuffer(inputBufferIndex);
        inputBuffer.put(buffer);
        decoder.queueInputBuffer(inputBufferIndex, 0, buffer.length, 0, 0);
    }

    int outputBufferIndex = decoder.dequeueOutputBuffer(info, timeoutUs);
    if (outputBufferIndex >= 0) {
        ByteBuffer outputBuffer = decoder.getOutputBuffer(outputBufferIndex);
        outputBuffer.position(info.offset);
        outputBuffer.limit(info.offset + info.size);
        // 将 outputBuffer 中的数据发送给应用层
        decoder.releaseOutputBuffer(outputBufferIndex, false);
    }
}

decoder.stop();

五、示例

以下示例展示了如何使用 Android 音频开发 API 录制和播放音频:

public class AudioRecorderActivity extends Activity {

    private AudioRecord recorder;
    private AudioTrack player;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_audio_recorder);

        recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                44100,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                bufferSize);

        player = new AudioTrack(AudioManager.STREAM_MUSIC,
                44100,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                bufferSize,
                AudioTrack.MODE_STREAM);
    }

    @Override
    protected void onStart() {
        super.onStart();

        recorder.startRecording();
        player.play();
    }

    @Override
    protected void onStop() {
        super.onStop();

        recorder.stop();
        player.stop();
    }
}

常见问题解答

1. 如何选择合适的音频源?

正确的音频源取决于您的具体要求。例如,MediaRecorder.AudioSource.MIC 用于麦克风输入,而 MediaRecorder.AudioSource.CAMCORDER 用于摄像机输入。

2. 如何处理录音中的噪音?

可以使用各种技术来减少噪音,例如降噪算法和过滤器。

3. 如何提升音频质量?

通过调整采样率、声道数和比特率等参数,可以提升音频质量。

4. 如何实现音频流式传输?

您可以使用 MediaPlayer 类实现音频流式传输,该类支持从远程服务器或本地文件播放音频。

5. 如何将音频数据保存到文件中?

可以使用 AudioFileWrite 类将音频数据保存到文件中。