返回

MediaMuxer: 封装编码音视频到 MP4 容器的利器

Android

导言

在我们的 Camera 开发系列中,我们已经成功地获取了 H.264 格式的视频裸流和 PCM 格式的音频数据。而 MediaMuxer 的出现,则为我们提供了将处理过的音视频数据封装到 MP4 容器中的有力工具。

MediaMuxer 简介

MediaMuxer 是 Android 平台上一个强大的 API,它允许开发者将各种媒体数据流(如音频、视频和字幕)组合成一个统一的媒体文件。MP4 容器是一种广泛使用的多媒体文件格式,因为它具有高度的兼容性和可扩展性。

MediaMuxer 的工作原理非常简单:它创建一个 MP4 容器,然后将音视频数据流写入该容器中。容器包含有关每个数据流的信息,如编解码器、比特率和分辨率。当写入完成时,MediaMuxer 会关闭容器并将其作为 MP4 文件保存。

使用 MediaMuxer 封装

使用 MediaMuxer 封装音视频数据涉及以下步骤:

  1. 创建 MediaMuxer 实例

    MediaMuxer mediaMuxer = new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
    
  2. 添加音视频轨道

    int videoTrackIndex = mediaMuxer.addTrack(videoFormat);
    int audioTrackIndex = mediaMuxer.addTrack(audioFormat);
    
  3. 开始写入数据

    mediaMuxer.start();
    
  4. 写入音视频数据

    mediaMuxer.writeSampleData(videoTrackIndex, videoBuffer, videoBufferInfo);
    mediaMuxer.writeSampleData(audioTrackIndex, audioBuffer, audioBufferInfo);
    
  5. 释放 MediaMuxer

    mediaMuxer.stop();
    mediaMuxer.release();
    

示例代码

以下是一个使用 MediaMuxer 封装 H.264 视频和 PCM 音频的示例代码:

private void muxVideoAudio(String videoPath, String audioPath, String outputPath) {
    MediaMuxer mediaMuxer = new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

    MediaFormat videoFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720);
    videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
    videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
    videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
    int videoTrackIndex = mediaMuxer.addTrack(videoFormat);

    MediaFormat audioFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 44100, 2);
    audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
    int audioTrackIndex = mediaMuxer.addTrack(audioFormat);

    mediaMuxer.start();

    // Read and write video data
    FileInputStream videoInputStream = new FileInputStream(videoPath);
    MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo();
    byte[] videoBuffer = new byte[1024 * 1024];
    while (videoInputStream.read(videoBuffer) != -1) {
        videoBufferInfo.size = videoBuffer.length;
        videoBufferInfo.presentationTimeUs = presentationTimeUs;
        mediaMuxer.writeSampleData(videoTrackIndex, videoBuffer, videoBufferInfo);
        presentationTimeUs += 1000000 / 30;
    }
    videoInputStream.close();

    // Read and write audio data
    FileInputStream audioInputStream = new FileInputStream(audioPath);
    MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo();
    byte[] audioBuffer = new byte[1024 * 1024];
    while (audioInputStream.read(audioBuffer) != -1) {
        audioBufferInfo.size = audioBuffer.length;
        audioBufferInfo.presentationTimeUs = presentationTimeUs;
        mediaMuxer.writeSampleData(audioTrackIndex, audioBuffer, audioBufferInfo);
        presentationTimeUs += 1000000 / 44100 * 2;
    }
    audioInputStream.close();

    mediaMuxer.stop();
    mediaMuxer.release();
}

结论

MediaMuxer 是封装音视频数据到 MP4 容器的强大工具。通过理解其工作原理和使用指南,开发者可以轻松地将编码后的媒体数据集成到统一的文件中。本文提供了全面的介绍和示例代码,使开发者能够自信地利用 MediaMuxer 增强其媒体处理应用程序。