【Android】音视频开发基础入门

发布于:2023-01-04 ⋅ 阅读:(788) ⋅ 点赞:(0)

音视频基本概念

帧率

即单位时间内帧的数量,单位是fps。一帧表示一张图像,一个视频由许许多多的帧组成。

24/25fps:一秒24/25帧,一般的电影帧率

30/60fps:一秒30/60帧,游戏的帧率,30帧可以接受,60帧会感觉更加流程逼真

85fps以上人眼基本无法察觉出来了,所以更高的帧率在视频里没有太大的意义

分辨率

影响图像大小,与图像大小成正比:分辨率越高,包含像素越多,图像越大;分辨率越低,图像越小。

常见的分辨率有720P(1280 × 720)、1080P(1920 ×1080)、4K(3840 × 2160)

视频码率

指视频文件在单位时间内传输的数据位数,单位是kb/s或者Mb/s。

一般来说视频的码率越大,压缩比就越小,画面质量越高,越接近原始文件,要求播放器的解码能力也越高。

分辨率一定的情况下,码率越高,视频就越清晰度。

色彩空间

RGB:通过RGB(红绿蓝)三种基础色,可以混合出所有的颜色,等量的三原色相加会变成白色。一张图片每个像素点展示的颜色都可以用一个RGB值表示,所以我们就可以用RGB数据来记录一张图像数据。

YUV:YUV主要用于彩色视频信号的传输。 与RGB相比,YUV只需要占用极少的带宽。

YUV细分的话有Y’UV,YUV,YCbCr,YPbPr等类型,其中YCbCr主要用于数字信号,我们一般所讲的YUV大多指的是YCbCr。

YUV有很多编码格式,其中YUV420就是一种。I420又是YUV420编码格式的一种,且是所有的厂商都是适配的,也是目前主流视频编码标准中要求输入的YUV格式。NV21也是YUV420编码格式的一种。对于Android来说,摄像头采集到的数据永远都是NV21格式的数据。

Y 亮度,就是灰度值(明亮度),除了表示亮度信号外,还含有较多的绿色通道量。

U 蓝色通道与亮度的差值

V 红色通道与亮度的差值

人眼对亮度敏感,对色度不敏感,因此减少部分UV的数据量,人眼却无法感知出来,这样可以通过压缩UV的分辨率,在不影响观感的前提下,减小视频的体积。

采样率

要把音频模拟信号转化为数字信号,就要采样。一秒采样的次数就叫采样率。

封装格式

视频文件有多种封装格式,比如常见的avi、wmv、mp4等。封装格式是指音视频保存的一种格式。

硬解码和软解码

硬解码是将解码工作的一部分交由GPU来做,这样可以大大的降低对CPU的负载,CPU的占用率较低了之后就可以同时运行一些其他的程序了。

软解码具有更好的适应性,有CPU就可以使用,但是占用了更多的CPU那就意味着很耗费性能,很耗电,在设备电量充足的情况下,或者设备硬件解码支持不足的情况下使用软件解码更加好。

IPB帧

在这里插入图片描述

I帧(关键帧):解码时只需要本帧数据就可以单独解码出一个完整的图像。

P帧(前向预测帧):表示的是这一帧跟之前的一个关键帧或P帧的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。

B帧(双向预测帧):记录了本帧与前后帧的差别,解码时需要参考前面一个I帧或P帧,同时也需要后面的P帧才能解码一张完整的图像

GOP(Group of Pictures)是一组连续的画面,由一张I帧和数张B/P帧组成,是视频图像编码器和解码器存取的基本单位。

常用视频渲染控件

解码器解码出来的数据,需要展示出来,就要用到渲染视图了

SurfaceView

基于View类,因此它本质上是一个View。它与普通View不在同一个视图层级。SurfaceView有一个置于应用程序窗口之后的独立窗口。SurfaceView刷新时不需要重绘应用程序的窗口。内部使用双缓冲机制,在新的线程中更新画面,所以刷新画面速度比普通view快。

android普通窗口的视图绘制机制是一层一层的,任何一个子元素或局部的刷新都会导致整个视图结构全部重绘一次,效率较低。而SurfaceView不属于这个窗口,它会在WMS中创建一个独立的窗口

因为SurfaceView不在应用程序窗口上,所以不能使用变换(平移、缩放、旋转等)动画。SurfaceView适合用于视频的展示,也适合2D游戏的开发,是view的子类

TextureView

Andriod4.0之后的api才能使用,和SurfaceView不同,它不会在WMS中单独创建窗口,而是作为应用程序窗口中的一个普通View,能被缩放、平移,也能加上动画。TextureView只能在开启了硬件加速的Window中使用,消费的内存要比SurfaceView多,并伴随着1-3帧的延迟。

SurfaceView TextrueView
内存消耗
绘制 及时 1-3帧延迟
耗电
动画和截图 不支持 支持

点播和直播

视频点播

即根据用户的需要播放相应的视频节目,不需要购买录像带或者VCD盘就能收看自己想看的视频。视频点播的实现过程:当用户发出点播请求时,流媒体服务系统会根据点播信息,将存放在片源库中的节目信息检索出来,以视频和音频流文件,通过传输网络传送到用户终端

在这里插入图片描述

直播的流程

rtmp协议:基于TCP的应用层协议,规定了数据的格式和收发数据的规则。是adobe公司推出的协议

在这里插入图片描述

RTC协议:基于UPD的引用层协议。RTC讲究的是实时通信传输音视频的场景,实时性的需求是大于可靠性的需求的。

音视频编解码

**视频编码:**将视频像素数据(RGB,YUV等)压缩成为视频码流,从而降低视频的数据量。

H.264/AVC: 使得高清视频和互联网视频得以广泛推广,也是当前主流标准;

H.265/HEVC: 推动了 4K 超高清视频的普及;

H.266/VVC: 则对8K超高清、屏幕、高动态和360度全景视频等新的视频类型,以及自适应带宽和分辨率的流媒体和实时通信等应用有了更好的支持。

**音频编码:**将音频采样数据(PCM等)压缩成为音频码流,从而降低音频的数据量。

WAV:微软公司开发的一种声音文件格式,音质较高,可以认为是一种无损压缩的格式。

MP3:MP3是使用用户最多的有损压缩的数字音频格式。MP3音频编码具有较高的压缩率。相同长度的音乐文件,用MP3格式来储存,一般只有WAV文件的1/10,音质次于WAV格式的声音文件。

AAC:AAC是新一代的音频有损压缩编码技术。MP4视频中的音频数据,大多数时候都是采用AAC压缩格式。AAC可以在比MP3文件缩小30%体积的前提下提供更好的音质。AAC的音频编码能力和效率远超MP3编码。

视频缓存原理

边播边缓存

边播边缓存的意思就是在播放的过程中,会同时将视频流保存到本地,当文件缓存完毕了再次播放的话就不用再次请求网络,直接播放本地文件就行了。既节省了流量又提高了加载速度。

采用本地代理的方式,通过原始url给播放器返回一个本地代理url,代理url类似于127.0.0.1:1234/真实url,播放器播放视频的时候实际就是通过请求代理来获取数据,比如手机看视频,手机是服务器,播放器是客户端。

CDN缓存

CDN(Content Delivery NetWork),即内容分发网络,通过在网络各处放置节点服务器所构成,CDN是构建在现有网络基础上的职能虚拟网络,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度。CDN的关键技术有内容存储和分发技术。

版权相关

对于公司私有的视频内容资源,一般都需要做版权保护

1、防盗链(域名防盗链、有效期)—目前精品视频正在使用的方案

2、对视频进行加密—目前自研视频都有使用的方案

3、添加视频隐形水印

MediaCodec

MediaCodec是Android提供的用于对音视频进行编解码的类,它通过访问底层的codec来实现编解码的功能。是Android media基础框架的一部分。MediaCodec只提供编解码功能,其他的功能则需要其他组件。MediaCodec提供了硬件编解码功能,效率高,且cpu占用低。

编解码流程如下:

MediaCodec编解码流程

MediaCodec生命周期:

MediaCodec整体上分为三个大状态:stopped、executing、released

Stoped:包含了3个小状态:Error、Uninitialized、Configured。

首先,新建MediaCodec后,会进入Uninitialized状态;
其次,调用configure方法配置参数后,会进入Configured;

Executing:同样包含3个小状态:Flushed、Running、End of Stream

再次,调用start()方法后,MediaCodec进入Flushed状态;

接着,调用dequeuelnputBuffer方法后,进入Running状态;

最后,当解码/编码结束时,进入end of stream(EOF)状态;这时,一段视频流就处理完了

Released:最后,如果想结束整个数据处理过程,可以调用release方法,释放所有资源

MediaPlayer

生命周期:

FFmpeg

FFmpeg可以看作是媒体处理工具的集合,开源的媒体处理库,它包含了很多的媒体文件处理工具。例如媒体文件格式解析工具、编解码器(libavcodec)等,这些工具实际上就是一个个库,而ffmpeg的命令行程序实际上就是对这些库的包装。而且ffmpeg也支持一些外部的库,例如,x264、MediaCodec。FFmpeg还具有高度可移植性,可以在各种构建环境,机器架构和配置下跨平台编译。

一些ffmpeg命令:

查看视频基本信息:ffmpeg -i E:\videos\input.avi

裁剪一段音视频文件:ffmpeg -i E:\videos\input.avi -ss 00:01:23 -codec copy -t 10 E:\videos\output1.mp4

给视频加水印:ffmpeg -i E:\videos\output1.mp4 -i E:\videos\logo.png -filter_complex overlay=10:main_h-overlay_h-10 E:\videos\output2.mp4

倒放视频:ffmpeg -i E:\videos\output1.mp4 -vf reverse -af areverse -preset superfast E:\videos\output2.mp4

输出视频yuv原始数据:ffmpeg -i E:\videos\output1.mp4 E:\videos\src.yuv

对yuv数据进行H264编码:ffmpeg -f rawvideo -pix_fmt yuv420p -s 1920x1080 -r 30 -i E:\videos\src.yuv -c:v libx264 -f rawvideo E:\videos\src.h264

其他资料可参考:

https://developer.android.google.cn/reference/android/media/MediaPlayer

https://github.com/bilibili/ijkplayer

https://www.volcengine.com/activity/meetup/3/live

https://blog.csdn.net/leixiaohua1020?type=blog

http://ffmpeg.org/