洞察 video 超能力系列——玩转 flv

从2016年10月(Chrome 54)开始,Chrome不再内置flash,而是改为用户第一次访问flash资源时提示安装。从Chrome62开始,不再提供“click to play的选项”,改为点击视频box后,左上方弹出

这意味着,flash作为过时的标准将被新技术所取代。

前言
从我们可以在网站上播放视频开始,到h5播放器们如火如荼地发展之前,使用flash一直都是web播放视频的不二之选。甚至于说得更加广泛一些,在html5成为主流之前,网站的多媒体能力,包括动画、游戏和视频一直都是adobe生态在掌控。那么随着html5标准的推出,这一切都成为了过去式。

flv与播方案
flv的全程是 Flash Video,顾名思义,就是专门给flash播放器提供的播放格式,这种格式具有结构简单、清晰的优点,最早出现是为了解决flash导出的swf文件体积过大,不适合在web中播放的问题。随着flash的逐渐淘汰,新的video标签自然是不支持flv格式的,人们开始把web视频的重点放在mp4或者hls上,但是随着直播这种视频形式的火热兴起,flv迎来了新一轮的生机。

我们来横向对比一下可用的直播方案:

flv播放实现·跳转·清晰度切换
可以看到,flv由于其编码格式的特点,只需要一个MetaData 以及音视频Track各自的Header就可以在任意的时间点播放,极大地符合实时直播的需求,在GOP足够小的情况下甚至可以达到0延迟,可以说在现有的技术方案里,http-flv是最理想的一个,正是因此,flv依然是web播放器不可或缺的一个格式支持。

首先我们通过一张图了解一下前端播放flv的过程

从上图可以看到,flv播放的过程其实是从flvt中提取元信息、音视频header以及数据,然后转码成fmp4盒子结构的过程,再通过MSE交给video的过程。因为flv的结构本身就是流式的,也就是说,它的数据被拆分到了很多个小的tag中,所以我们可以很方便地做数据的封装,也就是说将一段flv tag数据封装成一个独立的moof_mdat盒子对,然后就可以直接交给MSE处理,非常的方便。这里我们讨论flv是如何处理加载、跳转播放、重放及清晰度切换问题的

数据加载数据加载直播和点播两种模式,首先来聊一下点播:针对点播的数据获取,我们采用Range这个参数作为分段加载的控制参数

如上图,Range这个参数向服务器描述了希望加载**一个flv文件的 100000 到 3987705 个字节 **这段数据,相应的,服务器也需要能够根据Range参数正确返回这段数据。这里展示一个极简的服务端代码:

从上述代码可以看到,服务端是先是解析range,根据range切出文件分段,然后返回一个readableStream交给前端。

再看一下直播:直播跟点播是非常不一样的数据流动结构,我们看一下简单的直播流程

可以看到,直播的流程是一个 推流->服务端格式编码-> 终端播放 的一个流程。那么这里就带来了一个问题,我们不可以像点播时那样去加载数据了。因为服务端实际上保存的是一个文件流,不断有数据推到服务端,播放器也不存在缓存一段数据这样的情况,而是不断向服务器请求,只要有新的流到达服务端,播放器就要拿到这一段进行解码播放,达到推流和拉流同步进行的一个直播效果。为了实现这种效果,在播放器内,我们使用 fetch+ streamReader,简单的实现如下:

从上述代码我们可以看到,我们通过一个reader递归地从流里面读取数据,再将数据交给解码器进行处理。关于直播的数据加载还有更加先进的websocket方式,这里不再深入探讨,有兴趣的同学可以自行查阅相关资料。

播放时跳转播放时点击进度条跳转(下称seek)是一个非常高频的操作,尤其是在长视频中。用户遇到不想看的部分,或者想重看的片段,都会点击进度条触发seek。举个例子,一段视频,可能用户实际观看的部分只占不到50%, 如果我们将整段视频加载,那剩下加载的50%就浪费掉了。所以我们要做的事情就是精确地加载用户希望播放的部分,节约流量。解决方法如下:

  1. 获取用户将要跳转到的时间点,下称seekTime根据seekTime计算出离该时间点最近的一帧的位置,称为 startPos

  2. 以预加载时间为30s 为例, 计算出seekTime + 30s 这个时间点最近的帧位置 称为 endPos

  3. 我们以 Range: startPos-endPos 为请求参数,向服务端请求这一段数据

  4. 解码播放

这里说起来简单,但是涉及到了一个跟flv格式紧密相关的问题,那就是flv的onMetaData信息里是否具有keyframes这个属性。我们上述所提到的,基于时间点计算某一帧位置的算法,是完全依赖keyframes这个属性的,它记录了flv中所有关键帧的时间点和文件偏移量,keyframes大概长这个样子:

times中每一个时间点都对应着同位置的fileposition的偏移量,正是基于这一点,我们可以计算需要加载的数据Range。值得注意的一点是,并不是所有flv文件都携带了keyframes头,flv文件缺失部分onMetaData属性是很常见的事情。缺失了keyframes信息,我们就没办法做跳转了,因此我们需要借助额外的工具帮我们补全flv的onMetaData。这里推荐使用yamdi,一个轻量级的工具,有兴趣的同学可以看一下它的使用。

清晰度切换 清晰度切换是一个非常重要的功能,为什么重要呢,因为用户会根据网速的快慢,去选择更清晰或者更流畅的视频。假设没有这个选项,用户看视频卡顿了没法切换清晰度,就只能愤愤地关掉窗口了。那么多个清晰度的视频源我们如何做到无缝的切换呢?我们分情况来讨论一下:

点播中的清晰度切换方案 点播的切换清晰度是比较容易实现的,流程如下

如图,简而言之,就是尝试加载视频B,通过从视频B的onMetaData中提取关键帧信息,推算出当前应该加载哪一个关键帧,然后加载这个位置之后的数据,直到数据加载到之后,将视频B的数据交给MSE,同时,清除掉之前视频A在buffer中的缓存。

直播中的清晰度切换方案 直播清晰度切换目前还没有发现无缝的方案,因此建议在切换时,直接重建解码器以及MSE,关于这方面的问题我们还在探究。更多内容请关注我们的开源播放器——http://h5player.bytedance.com/
并且欢迎来我们github提issue: https://github.com/bytedance/xgplayer


你还可能感兴趣的文章
洞察 video 超能力系列——玩转 mp4
MediaSession在57中的开场白
如何精确统计页面停留时长

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