基于ffmpeg的播放器sdk

基于ffmpeg的播放器sdk

简介

网上开源的音视频sdk很多,如比较出名的有vlc、ijkplayer、exoplayer、gstreamer等等,当然各大公司他们也会有自己的专属播放器sdk,可能基于ffmpeg,也可能完全自己实现。
因此,基于个人兴趣我写了一个简单的播放器sdk,名为PPlayer
github地址:https://github.com/KaiLuQiu/PPlayer

ffmpeg的简单介绍

ffmpeg是一个全球领先的多媒体框架,跨平台,提供视频的解码、编码、转码、demuxer、muxer、流媒体、过滤等支持。因此,ffmpeg中其实包好着好几库,如:
1.libavcode(它是音视频的编解码库)
2.libavformat(它实现了多种流媒体协议,各种容器的解封装,I/O访问等)、libavutil(它相当于是一个使用的工具程序库)
3.libavfilter(它是一个通用的音视频后处理库)
4.libavdevice
5.libswresample
6.libswscale

PPlayer的简单介绍

首先它是基于ffmpeg开发的,参考ffplay的一套跨平台播放器sdk。以下是其目录结构:


WechatIMG72.jpeg
WechatIMG73.jpeg
WechatIMG76.jpeg
WechatIMG77.jpeg

播放器内部源码简单分析

首先是demuxer线程,demuxer线程是对应各种不同媒体容器的解封装过程。如常见的媒体容器有mp4、mkv、flv、avi、ts等码流。不同容器的解封装过程当然不同。首先不同容器的解封装可以看不同的容器的spec里面对媒体文件格式的解析很详细。同时具体的解封装源码可以看ffmpeg libavformat库中对应的源码。

大致流程如下:读取一定的视频文件做probe过程,主要是通过probe对一个未知的视频源进行分析。首先可以通过文件的后缀名初步判断其文件容器格式,但这仅仅只是得到一定score值。如果这个文件可以支持read_probe,那么就会遍历所有容器的probe函数,比如,mp4可能就会去probe码流中是否存在ftyp这样字段信息。因此遍历所有容器的probe,并取最高分来确定当前播放的容器的格式。

当我们获取到媒体容器格式之后,我们就可以映射到相应容器的解封装源码。比如我的媒体容器格式是flv,那么av_read_fream最终就会映射到对应flv.c文件的read函数。seek函数也一样,同样也是映射到具体容器的seek过程(题外话:像有的容器,其内部带有index索引,则很方便seek。如果不带index索引的话,如ts码流就不带这种索引,那就可以通过类2分法方式进行seek操作。同时seek有by time or by byte等等,这一块就不展开讨论了)。在扯一个题外话(就是有些奇怪的码流,一开audio的数据就和video的数据离得很远远,那这种格式的码流的话,如果正常的一包一包的parse就会导致parse出来的某一种包过多,其实遇到这种case还是有方式可以对demuxer进行优化的)总之这一块的坑还是蛮多的,但是强大的ffmpeg都为我们封装好了。

解封装完毕后,接下来我们就会得到视频音频字幕两路不同的数据包了,我这边的做法就是参考ffplay 将数据送入到对应的ringbuffer中也就是一个packetQueue中。应该来说正常的播放器器audioringbuffer和videoringbuffer中其能够容纳的大小是需要一个限制的,主要根据当前视频的格式来进行区分,如4k那么其容纳限制应该高点,我这边只是简单的设置 #define MAX_SIZE (15 * 512 *1024) 15M的大小。我这边的ringbuffer开始播放和seek之后都应该插入一个flush包,这个包得作用也很简单,相当的一个分割线的作用。

接下来解码,解码主要调用ffmpeg对应的接口,将对应的pkt包丢下去通过软解的方式进行解码,解码后输出一个frame格式的数据。当我们获得对应的frame的时候,我们可对其pts做一个转换,也就是通过time_base将pts转换成秒,方便后面avsync 同步计算,其实也可以不转。最后将解码的数据送入到对应FrameQueue循环队列中(注意:这边Queue大小设置为3帧左右,目的是不让frameQueue中存放太多的frame,原因我会选择在videothread 和 videoOut线程中进行丢帧,如果FrameQueue存放太多帧的话,就会导致两边最新一笔的数据的pts相差太多。那么就会影响到avsync的丢帧地方)

音视频输出,视频输出采用的是GLView进行输出,audio 采用SDL库通过callback进行输出。

音视频同步,PPlayer目前只是简单的使用video同步audio的方式进行的。原因很简单,使用audio同步video,丢失数据的话,影响会比video丢数据更加明显,且更影响播放效果。同步方面参考ffplay,对应的流都有一套pts,根据pts的计算是否需要丢帧,根据系统时间判断是否要delay线程等。(此处在有遇到几个坑,一个是audioClock更新的时候一定要记住SDL采用的是双buffer的设计,一定要将那帧的audio frame pts减去两个buffer中缓存的数据以及减去当前这笔剩余的数据(因为每一次SDL库callback并不是读满一整samples的),这样子才是真正播放的pts,具体你可以看下源码,注释还是写的蛮清楚的)。其次在callback时一定要设置SDL_memset(stream, 0, len);,否则会出现声音异常。 SDL_SetMainReady();还有这个否者SDL_OpenAudio的时候就会失败。

总结

本人毕业两年多了还是第一次写简书惭愧惭愧,写的不好的地方还望指出。目的也是对以前所学的内容做一个复习与总结。之后将会持续更新自己所学的一些知识!
PPlayer是我空余时间基于兴趣写的一个简单的播放器SDK(内部某些实现参考ffplay),里面肯定有很多地方写的不是很好,如果遇大佬还望给予更多的意见。


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

推荐阅读更多精彩内容