[Android] 移动端并行转码改造:音视频分离与视频分片

背景

基于响应时间和流量成本的考虑,移动端在完成视频内容生成后,一般会根据需要在本地进行一次转码再上传服务端。
常见处理是,对该文件进行硬件转码,完成后,将输出(单个)文件上传。这里的问题是,转码、上传以及后台转码都是串行的。

目前的框架

[Android] 移动端并行转码改造:音视频分离与视频分片_第1张图片

android 硬件转码

3个常见的API(demuxer, codec, muxer)

  • MediaExtractor
    MediaExtractor facilitates extraction of demuxed, typically encoded, media data from a data source.
  • MediaCodec
    MediaCodec class can be used to access low-level media codecs, i.e. encoder/decoder components. It is part of the
    Android low-level multimedia support infrastructure.
  • MediaMuxer
    MediaMuxer facilitates muxing elementary streams. Currently MediaMuxer supports MP4, Webm and 3GP file as the output. It
    also supports muxing B-frames in MP4 since Android Nougat.

[Android] 移动端并行转码改造:音视频分离与视频分片_第2张图片

并行转码系统改造

改造1:音视频分离

MediaMuxer与输出文件一一对应

  • 共用MediaExtractor(不变):
extractor.selectTrack(VIDEO_IDX);
extractor.selectTrack(AUDIO_IDX);
  • 改动1:分别创建video MediaMuxer和 audio MediaMuxer:
vMuxer.addTrack(vFormat);   ///< MediaFormat
aMuxer.addTrack(aFormat);
  • 改动2:取消muxer的buffer功能(QueuedMuxer)
    因为音视频分离,muxer过程独立进行,不再需要等到音视频第一帧凑齐再muxer,来一帧既可以mMuxer.writeSampleData()。

改造2:视频分片

  • 改动1:
    原来只生成一个文件,因此放在上层管理和销毁muxer比较合理。现在需要在transcode过程创建多个muxer,因此把muxer的生命周期交给transcode比较合理。

vMuxer.stop()完成mp4文件(视频分片)的生成且不能再restart,因此release老的muxer再创建下一个分片的muxer。

  • 改动2:分片结束

1)结束条件
MediaCodec每编码出一帧判断,是否达到分片结束条件。
利用

MediaCodec.BufferInfo 每帧编码的key frame标记: BUFFER_FLAG_KEY_FRAME

2) MediaMuxer使用MediaFormat初始化
视频里要分片,需要解决sps和pps初始化的问题。这两部分信息都保存在MediaFormat的csd-0csd-1字段,因此直接addTrack保存的format信息即可。

综上:

if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_KEY_FRAME) != 0)
{
    mMuxer.stop();
    reallocMuxer();                 ///< reallocMuxer
    mMuxer.addTrack(vFormat);       ///< MediaFormat
    mMuxer.start();
}   

新的框架

最终的框架如图:
[Android] 移动端并行转码改造:音视频分离与视频分片_第3张图片

你可能感兴趣的:(android,MediaMuxer,音视频分离,视频分片)