视音频技术分享

视音频分享的由来

少儿趣配音bugtags数据展示

可以使用的播放器

PLPlayerKit 

 地址:https://github.com/pili-engineering/PLPlayerKit

优点:简单方便,功能强大

可以播放短视频,长视频,直播,支持边下边播,支持各种视频格式,对错误的处理比较详细。SDK 为七牛自主研发的播放器内核,拥有更加优异的性能,二次开发方便。

用法:

拉取代码

git clone https://github.com/pili-engineering/PLPlayerKit

更新pod文件

pod install

简单的两步,基本不会有报错,就直接可以使用demo了。

IJKPlayer  

地址:https://github.com/bilibili/ijkplayer

优点:可以看到FFmpeg解码源码,是一个基于 ffmpeg 的轻量级 Android/iOS 视频播放器,比较成熟,接入方便,B站,美拍和斗鱼都使用IJKPlayer,经历市场试验,IJKPlayer较为稳定的一款播放器。

缺点:根据之前使用来看,遇到的问题会比较多。对于问题优化请参考:https://blog.csdn.net/shareus/article/details/78585260

用法:

git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios

cd ijkplayer-ios

git checkout -B latest k0.8.8

./init-ios.sh

cd ios

编译ffmpeg

./compile-ffmpeg.sh clean

./compile-ffmpeg.sh all

可以参考:https://www.jianshu.com/p/65fb80dff4d6

JPVideoPlayer

优点:基于 AVPlayer实现边下边播,全部都是按照AVPlayer的处理来处理的,不会出现标示符重复问题。

用法和源码解析:https://juejin.im/post/5ad3657351882555712ccf00

AVPlayer和FFmpeg的区别 

AVPlayer特点

AVPlayer存在于AVFoundation中,它更加接近于底层,所以灵活性也更强,AVPlayer本身并不能显示视频,如果AVPlayer要显示必须创建一个播放器层AVPlayerLayer用于展示,播放器层继承于CALayer,只要把AVPlayerLayer添加到控制器视图的layer中即可.

 AVPlayer解码方式 

AVPlayer+httpserver+HLS的组合方案的硬件解码方式,而HLS(HTTP Live Streaming) 是Apple在2009年发布的,可以通过普通的web服务器进行分发的新型流媒体协议,HLS 使用的 HTTP 协议传输数据,视频有延迟,不适合做视频通讯,做直播使用avplayer起播可能会比较慢。

优点:HLS 协议本身实现了码率自适应,不同带宽的设备可以自动切换到最适合自己码率的视频播放,CPU消耗极低,解码效率极高。

AVPlayer支持的视频格式

AVPlayer支持的视频编码格式:H.264、HEVC(iPhone7及以后设备)、MPEG-4。 视频格式(封装格式):.mp4、.mov、.m4v、.3gp、.avi等。 如果想支持更多的视频格式,可以使用第三方的框架。

FFMPEG特点

高可移植性:可以在Linux, Mac OS X, Microsoft Windows, the BSDs, Solaris等等系统上编译。

高性能:专门针对X86,arm,MIPS,ppc等大多数主流的处理器提供了对应的汇编级别的优化实现

高度安全:FFMPEG官网上说,他们对代码审查总是考虑安全性,而且一旦发布的版本中有安全性的Bug都会尽快的修复并更新发布版本

高度易用性:FFMPEG的提供的API都有相关的注释,且官方也有对应的说明文档

支持的格式多样性:FFMPEG支持很多很多多媒体格式的解码,编码,复用,解复用等功能,不管是很老的格式,还是比较新的格式均有不错的支持

高度可扩展:FFMPEG是一个模块化的结构,不管是avformat,还是avcodec都有相应的类型结构体,完全可以实现自己比较特殊的编解码器或者解复用等功能并注册到FFMPEG当中去,而且延迟比较少。

那他们播放一个视频的过程是什么样的呢

音视频基础知识介绍

视频播放器原理

视音频技术主要包含以下几点:封装技术,视频压缩编码技术以及音频压缩编码技术。如果考虑到网络传输的话,还包括流媒体协议技术。

视频播放器播放一个互联网上的视频文件,需要经过以下几个步骤:解协议,解封装,解码视音频,视音频同步。如果播放本地文件则不需要解协议,为以下几个步骤:解封装,解码视音频,视音频同步。他们的过程如图所示。


可以总结为:拉数据->解协议->解封装->音视频解码->音视频同步->播放。

解码的作用,就是将视频/音频压缩编码数据,解码成为非压缩的视频/音频原始数据。音频的压缩编码标准包含AAC,MP3,AC-3等等,视频的压缩编码标准则包含H.264,MPEG2,VC-1等等。解码是整个系统中最重要也是最复杂的一个环节。通过解码,压缩编码的视频数据输出成为非压缩的颜色数据,例如YUV420P,RGB等等;压缩编码的音频数据输出成为非压缩的音频抽样数据,例如PCM数据。

流媒体协议

流媒体协议是服务器与客户端之间通信遵循的规定。


封装格式

封装格式的主要作用是把视频码流和音频码流按照一定的格式存储在一个文件中。

除了AVI之外,其他封装格式都支持流媒体,即可以“边下边播”。

视频编码

视频编码的主要作用是将视频像素数据(RGB,YUV等)压缩成为视频码流,从而降低视频的数据量。

H.264又叫AVC,是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式,它集合了H.263和MPEG4的优点,拥有更高的数据压缩比。在同等的图像质量条件下,H.264的数据压缩比能比H.263高2倍,比MPEG-4高1.5倍。 也是目前苹果支持最好的编码格式。mp4格式是H.264编码指定使用的标准封装格式,3GP是MP4格式的一种简化版本,减少了储存空间和较低的频宽需求,让手机上有限的储存空间可以使用。

实际上这些封装格式对应的音频视频编码格式也不是固定的,就拿MP4来说,常见的MP4是由H.264+AAC封装,但是也由Xvid+AAC编码的可能。如果解码器不支持Xvid,则可能会出现无法播放,或者播放播放过程有声音无画面的情况。


FFMPEG视音频编解码

ffmpeg的官方网站是:http://ffmpeg.org/

FFmpeg的基本概念

容器(container):就是文件格式,在FFMPEG中,用来抽象文件格式的容器就是AVFormatContext; 

数据流(stream):数据流就是我们平时看到的多媒体数据流,它包含几种基本的数据流,包括:视频流、音频流、字幕流;数据流在FFMPEG中的抽象为AVStream。 

解复用器或者说分流器(demuxer):FFMPEG将要处理的多媒体文件看成多媒体数据流,先把多媒体数据流放入容器(AVFormatContext),然后将数据流送入解复用器(demuxer),demuxer在FFMPEG中的抽象为AVInputFormat,demuxer就是把交错的各种基本数据流识别然后分开处理,将分开的数据流分别送到视频、音频、字幕编解码器处理。

数据包(packet)当然分开的数据流在送往编解码器处理之前,要先放于缓存中,同时添加一些附属信息例如打上时间戳,以便后面处理,那么这个缓存空间就是数据包;由于数据流是在时间轴上交错放置,所以所有的视频、音频、字幕都被分割成一段一段的数据,这些一段段的数据从数据流中解析出来之后,就是存放在各自的packet,那么在这里要说明一下,单纯的视频数据包来说,一个视频数据包可以存放一个视频帧,对于单纯的音频帧来说,如果抽样率(sample-rate)是固定不变的,一个音频数据包可以存放几个音频帧,若是抽样率是可变的,则一个数据包就只能存放一个音频帧。

上面用到的PLPlayerKit、IJKPlayer都是通过FFMPEG解码。

FFMPEG的视音频编解码功能几乎囊括了现存所有的视音频编码标准,因此只要做视音频开发,几乎离不开它。

FFmpeg解码实例-simplest_ffmpeg_player

FFmpeg新版解码一个视频流程如下图所示:

解码Step1. 连接和打开视频流

连接和打开视频流必然是后续进行解码的关键,该步骤对应的API调用为:


官方文档建议加上avformat_network_init(),虽然这个不是必须的。这也就解释了网上很多资料关于如果要打开网络流的话,这个API是必须的的说法了。


avformat_open_input()打开并读取视频头信息,该函数较为复杂

参考链接:https://blog.csdn.net/leixiaohua1020/article/details/44064715

解码Step2. 定位视频流数据

无论是离线的还是在线的视频文件,相对正确的称呼应该是“多媒体”文件。因为这些文件一般不止有一路视频流数据,可能同时包括多路音频数据、视频数据甚至字幕数据等。因此我们在做解码之前,需要首先找到我们需要的视频流数据。


avformat_find_stream_info()进一步解析该视频文件信息,主要是指AVFormatContext结构体的AVStream该函数内部已经做了一套完整的解码流程,获取了多媒体流的信息。一个视频文件中可能会同时包括视频文件和音频文件等多个媒体流,这也就解释了为什么后续还要遍历AVFormatContext的streams成员(类型是AVStream)做对应的解码。

以上,就完成了文件流的初步初始化工作。

解码Step3. 准备解码器codec

codec是FFMPEG的灵魂,顾名思义,解码必须由解码器完成。准备解码器的步骤包括:寻找合适的解码器 -> 拷贝解码器(optiona)-> 打开解码器。

寻找合适的解码器 


avcodec_find_decoder是从codec库内返回与id匹配到的解码器。另外还有一个与其对应的寻找解码器的API-AVCodec* avcodec_find_decoder_by_name(const char* name),这个函数是从codec库内返回名字为name的解码器。

拷贝解码器 -


avcodec_alloc_context3()创建AVCodecContext,而avcodec_parameters_to_context()才真正执行了内容拷贝。avcodec_parameters_to_context()是新的API,替换了旧版本的avcodec_copy_context()。

打开解码器

解码Step4. 解码

解码的核心是重复进行取包、拆包解帧的工作,这里说的包是FFMPEG非常重要的数据结构之一:AVPacket,帧是其中同样重要的数据结构:AVFrame

参考链接:https://blog.csdn.net/asd501823206/article/details/96189328

参考链接:https://blog.csdn.net/leixiaohua1020/article/details/38868499

IJKPlayer源码解析

解码过程

ijkmp_global_init 注册编码器

IJKPlayer播放器底层依赖于ffmpeg,基于ffplay进行改进。ffplay的核心代码被移植到ff_ffplay.c和ff_ffplay.h里面,媒体流打开时依然是从stream_open()函数开始,而在IJKPlayer里面,被封装到ffp_prepare_async()里面,所以还是从stream_open里面开始着手。stream_open里面开启是视频流读取线程

read_thread,在视频流读取线程里面,调用ffmpeg的api,打开网络流,读取音视频流,放进缓冲队列,进一步解码播放。

待补充

鸣谢

感谢勇哥这次的助推,本身是为了解决少趣的线上问题,分享各个播放器的用法和注意事项而已,勇哥让分享更深入一些,所以一周多研究了ffmpeg的一些基本知识,以后还会更深入的研究。

感谢雷霄骅无私的分享,很多知识都是来源于大神的分享和视频,留给了这么完整而且实用的教程。

分享

其实经过一番考察之后,发现AVPlayer做的好,也能实现基本的视频播放,实现无差错,只是没有太好的第三方使用,咱们之前使用的封装的解决问题反而更麻烦,在相对情况下,咱们使用七牛播放器或者ijk播放器,之前有了比较成功的例子,所以在使用问题上处理会更规范。

总结就是,最主要是处理逻辑上要严密。

分享之后最大的受益者是自己,有时准备分享有些痛苦,但是也是成长的标志。最好的收获是行动之后。

参考链接:https://blog.csdn.net/leixiaohua1020

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容

  • 教程一:视频截图(Tutorial 01: Making Screencaps) 首先我们需要了解视频文件的一些基...
    90后的思维阅读 4,632评论 0 3
  • //音频编码 JNIEXPORT void JNICALL Java_com_tz_dream_ffmpeg_an...
    Jackey_song阅读 1,466评论 0 1
  • ### YUV颜色空间 视频是由一帧一帧的数据连接而成,而一帧视频数据其实就是一张图片。 yuv是一种图片储存格式...
    天使君阅读 3,234评论 0 4
  • 原文地址:http://blog.csdn.net/yipie/article/details/7912291 摘...
    冬的天阅读 7,125评论 1 6
  • 当初选择去代理公司还不知道代理公司有什么区别,到了这个行业才知道有全国性与区域性之分。 如果当时我学会思维导图,有...
    娟娟12345阅读 934评论 0 0