3

Android系统中音视频播放技术探究

 1 year ago
source link: https://www.51cto.com/article/711948.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Android系统中音视频播放技术探究-51CTO.COM

Android系统中音视频播放技术探究
作者:移动Labs 2022-06-20 05:59:35
随着5G技术的发展和普及,视频场景越来越多。同时随着元宇宙概念的火热,VR、AR被推向风口浪尖,而VR、AR都与音视频密切相关,目前市面上的VR一体机基本是安卓系统。笔者相信会有更多的音视频应用场景出现,音视频技术也必将为人类的数字生活增添更多色彩。​

作者 | 户锐,单位:中国移动智慧家庭运营中心

​Labs 导读

随着智能手机和5G技术的普及,视频播放需求迅速增加,碎片时间刷小视频,熬夜追电视剧都是视频播放,毫不夸张地说,视频播放时刻伴随着你和我。我们经常听别人说MP4、MKV、H264、H265、AAC、1080p、60fps等一些专业术语,他们的含义是什么呢?视频播放的流程是怎么样的呢?当今占市场份额最大的Android平台播放器框架是如何设计的呢?本文就带你一起捋一捋这些知识要点。

Part 01 常见的专业术语

我们通常说的MP4、MKV、WMV是一种视频文件格式,在行业中我们将其称为容器,音视频文件的数据存放在容器中,每种容器都有固定的格式。其中MP4是最常见的国际通用格式,在常见的播放软件中都可以使用和播放,被广泛使用,在安卓手机上用相机录制的视频一般都是MP4格式。MKV最大的特点就是能容纳多种不同类型编码的视频、音频及字幕流,俗称万能媒体容器。WMV是微软推出的一种流媒体格式,它是在ASF格式升级延伸来的。在同等视频质量下,WMV格式的体积非常小,因此很适合在网上播放和传输,通过工具或者命令将WMV文件转成相同分辨率的MP4文件后,文件的大小会变大。下图可以粗略的表示文件格式和数据的关系。

图片

视频的原始数据是YUV格式,音频的原始数据是PCM格式,这两种格式的数据会占用大量的存储空间。为了解压音视频数据占用的存储空间,需要将音视频数据进行压缩,这就是行业中说的编码,在播放音视频文件的时候需要将压缩的音视频文件进行解压缩,这就是解码。编码和解码都是按照一定规范进行的,不同的规范有不同的名字,比如H264、H265、AAC。换言之H264、H265、AAC就是编解码格式。其中H265和H264都是视频编解码格式,且都是基于宏块进行编码,其中H264最大支持16*16的宏块,而H265最大支持64*64的宏块,因此H265在细节表达上会比H264更清楚,在像素一致的情况下,H265的压缩比会比H264更高。由于H265具有更高的压缩比,所以H265占据的存储空间更少,从而达到了节约带宽的目的和播放流畅的效果,这也是目前热播高清电视剧采用H265编码的原因。

我们经常听到的画面比例是指视频画面宽和高的比例。生活中常见的比例有16:9和4:3。我们还常常听到标清、高清、超高清等术语,这对应的专业术语是分辨率,720p以下为标清,720p、1080p为高清,4k、8k称为超高清。720p、1080p究竟是什么意思呢?说到这里,我们要先讲一下视频分辨率的概念,分辨率指视频宽高的像素数值,单位为Px。通常视频分辨率的数值宽高比要等于画面比例,不然视频文件就会产生黑边。标准1080p的分辨率为1920×1080其含义是宽度上有1920个像素,高度上有1080个像素,分辨率越高视频就越清晰。而30fps、60fps是指帧率,视频是由一张一张的图片组成的,视频播放就是将一张一张的图片(一张图片也可以简单理解为一帧)按照固定的速率展示给观众,比如一秒钟显示30帧(30fps),或者一秒钟显示60帧(fps),让观众感觉动作是连续的。因此帧率就是为每秒显示帧数,帧率越高视频就越流畅,目前主流的视频帧率是60帧。

目前主流的安卓系统都支持H264、H265硬件编码和解码,可以很好满足用户的需求。而且在安卓系统上为开发人员预留了方便简单的接口来实现编码和解码,比如用MediaRecorder实现录像(编码场景),用MediaPlayer实现播放(解码场景),MediaRecorder和MediaPlayer接口非常简单,上手容易,而且屏蔽了编解码底层逻辑,对开发人员非常友好。接下来我们简单介绍一下视频播放的流程。

Part 02 视频播放流程

一个播放器播放视频的主要流程如下:

1.读取视频文件解析文件格式,即获取容器格式,在安卓平台Media框架的DataSource有一个sniff函数,此函数会调用各个Extractor的sniff函数,每个Extractor的sniff函数会返回一个分数,DataSource最终会选择分数最大的Extractor;

2.利用对应的容器格式解析器(在Android平台的名字是Extractor)对视频文件进行解析,获取元数据、音轨、视频轨索引以及音视频编码器格式,如果是MP4文件,在安卓平台就会使用Mp4Extractor对文件进行解析;

3.调用对应的解码器对音频和视频数据进行解码,在安卓平台就是通过MediaCodec调用OMX或者C2解码器插件进行解码,并将解码后的数据通过MediaCodec返回;

4.对解码后的数据进行音视频同步,必要时做丢帧处理,在做音视频同步的时候一般都是视频同步音频,而且在安卓平台也是这么做的,具体做法是将解码后视频的时间戳和音频时间戳进行比较,如果视频时间戳和音频时间戳差值大于某个设定的值比如200ms,那么就丢弃当前视频帧;

5.对音视频进行渲染,在安卓平台上解码器解码后的音频数据会交给SurfaceFlinger渲染,解码后的音频数据会通过AudioTrack处理最终输出到扬声器。

图片

现在我们大概了解了一个视频播放的主要流程,但是作为一名勤劳的搬砖人,总是想自己编写一个视频播放器,体验一下自己的成果,下面就简单介绍一下在Android平台上如何编写一个简单的视频播放器。

Part 03  Android上实现一个最简单的播放器

其实在Android想要编写一个视频播放器,是非常简单的。利用Android提供的一个MediaPlayer Java类,可以很容易实现一个播放器。

Sample Code:
String url = https://www.xxx.com/video/test.mp4
MediaPlayer player = new MediaPlayer();
player.setDataSource(url);
player.prepare();
player.setDisplay(surfaceView.getHolder());
player.start();

你没有看错,就是这么简单。

作为一名爱钻研技术的伙伴,你肯定很好奇,Android MediaPlayer内部是如何实现的呢?

Part 04  Android MeiaPlayer播放器架构

在Android平台上Java层的MediaPlayer只是提供对外暴露的接口,其实真正的逻辑实现都在Native的MediaSever中。MediaPlayer的setDataSource会触发Native IPC请求服务端创建一个player实例,而prepare会触发服务端寻找一个合适的容器解析器(MediaExtractor),并解析得到需要的解码器信息,因此prepare比较耗时start会触发服务端创建对应的解码器,并开始解码,然后音视频同步,最后显示。

图片

MediaCodec可以认为是一个解码器组件与OMX或者C2解码器plugin交互。

图片

在onInputBufferAvailable回调中给解码器喂数据,通过queueInputBuffer向解码器提供数据。

在onOutputBufferAvailable回调中处理解码后的数据,通过releaseOutputBuffer规划output buffer给解码器。

在Android平台上,除了MediaPlayer外还有很多开源的播放器框架可以供我们使用,下面我们用一个表格简单介绍一下。

Part 05 常见开源播放器

图片
图片
图片

Part 06 安卓音视频的未来

音视频技术在数字化时代永远不会过时,而且需求会越来越旺盛。我们工作中参加视频会议,生活中刷小视频,拿着手机追剧,微信视频通话,进出大楼的人脸识别等,都与音视频技术密切相关。随着5G技术的发展和普及,视频场景越来越多。同时随着元宇宙概念的火热,VR、AR被推向风口浪尖,而VR、AR都与音视频密切相关,目前市面上的VR一体机基本是安卓系统。笔者相信会有更多的音视频应用场景出现,音视频技术也必将为人类的数字生活增添更多色彩。​


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK