文章目录
前言
在 Android 多媒体框架中,Media Extractor 扮演着十分重要的角色。本文作为自定义 Media Extractor 系列的第一篇文章,将对播放器的一些基本原理进行普及,然后简要介绍 Android 系统中 Media Extractor 的框架结构,以及 Extractor 组件加载流程。本文 基于 Android 11,主要目的为普及 Android Extractor 的基本框架以及工作原理,不对 Android 源代码展开过多的分析。
一、 播放器基本原理
该章节内容引自 雷霄骅-视音频编解码技术零基础学习方法,感谢雷神留下的宝贵财富,为无数从事音视频开发工作的同学拨开了迷雾。
播放器框架简介
播放器是一种典型的输入输出模型。输入媒体文件,输出音视频原始数据到设备(音响、电视、显示器…)。播放器播放一个视频,需要经过解协议,解封装,解码音视频,音视频同步四个基本步骤。过程如图所示:
在播放器中,通常将负责解析协议模块称为 source(媒体源)、解封装模块为demuxer、解码模块为decoder(分为 audio decoder 和 video decoder)、音视频同步模块为 avsync。
解协议
音视频在网络上传播,需要采用各种网络协议(HTTP,RTMP,HLS等等)。从网络下载的数据,除了包含本身的音视频数据,可能还会包含信令数据。解协议的过程就是从网络下载数据并去除掉信令数据,只保留音视频数据的过程。例如,采用RTMP协议传输的数据,经过解协议操作后,输出FLV格式的数据。播放已下载的本地视频时(如 MP4 文件),实质上没有解协议的过程,但可视为一种特殊的协议。
解封装
封装格式种类很多,例如 MP4,MKV,RMVB,TS,FLV,AVI 等等,它的作用就是将已经压缩编码的视频数据和音频数据按照一定的格式放到一起。解封装的目的就是将音视频数据从封装格式数据中分离出来。例如,FLV 格式的数据,经过解封装操作后,输出 H.264 编码的视频码流和 AAC 编码的音频码流。
常见封装格式:
解码
原始的音视频数据体积庞大,为了便于音视频的存储和传输,通常进行会压缩以降低音视频的数据量。音频的压缩编码标准包含 AAC,MP3,AC-3 等等,视频的压缩编码标准则包含 H.264,MPEG2,VC-1 等等。解码是整个播放器系统中最重要也是最复杂的环节,目的在于将压缩的音视频数据解压缩成为设备能够播放的数据。
音视频同步(音画同步)
由于播放音频和视频是不同的设备,如果送给音频设备和送给视频设备数据的时间戳不匹配,则会导致音视频不同步(音频快于视频或视频快于音频),因此在最终的音视频数据送给设备播放前,还需要对音视频数据进行同步。
播放器控制
常见的播放器控制逻辑:
- 准备(prepare),一般会进行 source、demuxer、decoder、avsync 等模块的初始化
- 播放(play),开始播放
- 暂停(pause),暂停播放,暂停播放不释放 prepare 时已初始化的资源
- 恢复(resume),暂停后恢复播放
- 停止(stop),stop通常会释放 prepare 时初始化的资源
- 定位(seek),从指定位置播放,常见的操作如拖动进度条
元数据(metadata)
用于描述媒体文件的数据被称为元数据,元数据包含了媒体文件的时长、大小、编码格式、封装格式等信息,如下图:
二、Media Extractor 框架简析
Media Extractor 直译为媒体提取器,顾名思义,其用途为提取媒体源中的音视频数据。在上一章节 播放器基本原理 中充当 demuxer 角色,完成解封装的任务:
在 Android Multimedia 框架中,Media Extractor 为媒体文件的扫描(MeidaProvider)以及播放(