您当前的位置:首页 > 电脑百科 > 网络技术 > 网络知识

珍稀干货!阿里 Web 音视频开发趟坑指南

时间:2020-02-05 11:03:25  来源:  作者:

作者 | 阿里文娱前端技术专家 归影

责编 | 夕颜

出品 | CSDN(ID:CSDNnews)

这不是一篇基于MSE开发Web播放器的入门文章,而是围绕Web播放器开发遇到的常见问题与解决方案,毕竟入门文章常有而趟坑干货不常有。如果您有Web播放开发经验和音视频技术基础,读起来会更有共鸣。

Web播放器开发基础知识

先介绍Web播放器开发的一些基础知识。有人要问了,Web播放器开发难道不是一个video标签就够了么?非也!

1、浏览器Video支持的格式非常有限

在W3C的标准里面Video只支持MP4格式 准确的说是ISOBMFF(Fragment MP4)。当然chrome支持WEBM,safari支持HLS(MPEG-TS)这都是自家的私有实现,做不得数。

2、浏览器Video无法逐个加载视频切片

现在主流的流媒体点播/直播技术,都会把视频切片。而video标签src只能挂载整个MP4资源。没法逐个的加载视频分段。

所以我们的主角出场—— MediaSource Extenstion,简称MSE,是一套能不断的把音视频二进制数据塞给video标签播放的API。

图1:MSE简明结构

MSE内部可以创建一系列的sourcebuffer,一般是一个音频buffer,一个视频buffer。把MSE做成blob url之后绑定给video的src。然后就可以通过AppendBuffer往video里追加音视频数据了。有了MSE,播放器器的整体结构是什么样的呢,见下图。

图2:Web播放器简明结构

首先在浏览器层面,主要使用video标签、MSE、XHR 和UI。那么播放器主要由Manager驱动加载视频的playlist(比如HLS里的m3u8,dash里的MPD,FLV虽然不是playlist概念,但是是原理上差别不大,都是为了拿到视频的一个个的片段的地址),并通过数据服务加载这一个个的分片。然后通过transmuxer也就是所谓的转封装器,把分片的封装格式比如TS拆开(demux) 把连原始的音视频数据解出来,再重新打包成fmp4(remux),最后通过MSE API喂给video标签里,让video去播放。

因此播放器所做的事情最主要有两点:

1) 转封装。即将video不支持的封装格式转码成video所支持的封装格式;

2) 如何驱动整个播放进行。即决定何时下载下一个分片,何时需要解码插入到video的buffer里。

时间戳对齐

转封装除了的封装格式的解复用(demux)和再复用(remux)之外最重要的环节就是分片的时间戳对齐策略,以及音视频同步。

图3(传说中的“开局一张图 原理全靠猜”)

简单讲一下上图:红色代表音频的时间轴。蓝色/青色是视频的时间轴。PTS(Presentation Time Stamp) 指的是这一帧需要渲染的时间。DTS(Decoding Time Stamp) 指的是这一帧需要解码的时间。

1、首片首帧的对齐策略

正常来说音频PTS和DTS是一样的,而视频如果有B帧的话DTS往往要比PTS早一些(因为要预留一定的时间解码)。因此视频的首帧会有一个洞(gap/shift随便你怎么叫),如果不经处理插到video里,那么video里的buffer也会呈现出一小段的洞,一般是0.08s(比如10s的分片 插进去可能出现0.08~10.08的情况)。现在主流的做法是削掉这个洞。就是把DTS跟PTS强行拉平,一般来说chrome 不会出现太大的问题。但是safari不行,如果不预留一定的DTS/PTS偏移,safari前两帧的播放会明显卡顿。

2、后续对齐策略后续分片的对齐,会通过DTS/PTS两个尾部指针来做。如果发现后续分片时间轴有间隔就往前推从而填上间隔。如果发现重叠,就把重叠帧后移。这样虽然会导致后续分片的前几帧重叠。但在播放的过程中几乎没有影响。

音视频同步

首先,什么情况下会导致音画不同步?

1、视频源流压根没对齐。没救了,看下一点。

2、还是因为有洞。很多时候视频切出来的每个分片之间都不一定是严丝合缝的,分片间的音视频时间戳可能有洞。而且对于TS由于音频每一帧的duration(≈23ms) 跟视频每一帧的duration(40ms@25fps) 无法吻合(整除) 所以加剧了这种参差不齐的情况。那么,重点来了!chrome有个特殊的机制, 如果发现音频之间有洞之后,为了保证音频的平顺,会自动把后续音频往前推抹平这个洞。如果每个分片都有洞,悲剧了,这种往前推的操作就会积累越来越多导致音视频不同步。

小tips:

打开chrome的媒体调试页面 chrome://media-internals 可以看到媒体播放相关的所有debug信息和error信息非常有用。其中就会有一条关于音频处理的提示:

当然这条显示的具体原因是自动切掉重叠overlap导致的。其实gap/overlap本质是一样的。怎么办?当然是播放器自己主动把洞填上。具体做法是插帧。目前主要是插静音帧,或者复制前一帧。静音帧会带来毛刺音,复制帧会导致拖音。我们目前的优化方案是判断附近的音频数据量,数据量大时说明此处声音丰富(其实不算靠谱,姑且这么处理,因为没有更好的判断方式),如果插静音帧会毛刺很明显,所以此时用复制帧,反之插静音帧。

那些年我们趟过的坑

1、 不同版本表现差异 容忍度不同

1) Chrome 35分水岭。chrome35之前要求关键帧之后的第一帧dts不允许跟关键帧dts相同,否则抛错。

2) 低延迟的模式。把转封装出来的FMP4中的视频轨duration(tkhd box) 设置成0xffffffff 时会让chrome认为这是直播流,会开启低延迟模式,所谓低延迟模式就是会极大的减少帧缓存,基本上视频帧立马解码立马播放减少每个分片的起播延迟。但是呢在CPU负载过高的情况下(解不过来)会造成视频频繁卡顿(网络无关的)。

2、 不同浏览器表现有差异

1) timeupdate事件。W3C的标准是不能超过250ms触发一次。windows下360等浏览器会达到500ms左右。

2) safari对每一帧duration平顺度更敏感。safari需要对每一视频帧的duration标准化处理,例如TS下要处理成3600。

3) 对洞的容忍度不同。chrome遇到buffer中有0.08的间隔以内会自动跳过去。像IE edge等浏览器不行会卡住,所以播放器一定要有跳洞逻辑。比如判断当前卡在洞的边界,要主动跳过去(seek)。

3、内存限制

通过MSE push给video的视频数据会在内部维护一个buffer,这个尺寸是有限制的。

1) chrome系列约100M

2) IE系列约30M

超过的话就会导致抛出 QuotaExceededError 。所以需要处理好buffer的尺寸以及及时清除不用的buffer。比如已经播放过的,正常浏览器会自己清除,但是不那么的及时。

优化

简单说一下卡顿相关的优化。

  • 多级Buffer控制
  • ABR 自适应码率算法
  • 基于WebRTC的P2P

1、多级buffer

为什么要有多级的buffer?因为video本身的解码buffer有大小限制,而且buffer过长会导致长时间解码,会导致CPU一直占用高。所以我们搞了两级buffer一级就是video的buffer另外一级是内存中的,只负责下载,二级很长。可以消除网络抖动带来的卡顿影响。

2、ABR自适应码率的算法

这个主要是来预测用户本身的带宽范围,然后选用不同码率的视频流来无缝切换播放。当然还有一些策略算法,比如根据用户现在buffer的水位,或者检测到用户频繁超时,来采用不同的策略。

3、基于WebRTC的P2P ‍‍

因为P2P是基于UDP的传输,可以突破一些带宽限制或网络拥塞而导致的卡顿问题。不过P2P不一定靠谱所以还是要辅以普通的HTTP传输相结合。我们一般是利用P2P加indexDB 来变相延长视频的缓冲区。因为P2P带宽成本便宜,我们利用P2P做了一个非常长又很便宜的buffer。这样的话网络再波动也不会导致卡顿了。



Tags:Web   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
在互联网的江湖里头,每天都有新鲜事。我们昨天还在聊元宇宙,还没有了解元宇宙是个啥,今天又开始了web3.0,站在时代的浪潮之巅,哪怕我们只是一滴最普通的水,也会随着巨浪此起彼伏,直...【详细内容】
2021-12-24  Tags: Web  点击:(7)  评论:(0)  加入收藏
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Tags: Web  点击:(6)  评论:(0)  加入收藏
我们有时候在音频通话过程中,想要改成视频通话。如果挂断当前的通话再重新发起视频通话就会显得比较麻烦。 因此很多app提供了将音频通话升级成视频通话的功能,同时也有将视频...【详细内容】
2021-12-23  Tags: Web  点击:(5)  评论:(0)  加入收藏
你好,这里是科技前哨。 随着“元宇宙”概念的爆火,下一代互联网即将到来,也成了互联网前沿热议的话题,12月9日美国众议院的听证会上,共和党议员Patrick McHenry甚至宣称,要调整现...【详细内容】
2021-12-17  Tags: Web  点击:(14)  评论:(0)  加入收藏
一、SQL注入漏洞SQL 注入攻击( SQL Injection ),简称注入攻击、SQL注入,被广泛用于非法获取网站控制权,是发生在应用程序的数据库层上的安全漏洞。在设计程序,忽略了对输入字符串...【详细内容】
2021-12-10  Tags: Web  点击:(23)  评论:(0)  加入收藏
今天详解一个 Python 库 Streamlit,它可以为机器学习和数据分析构建 web app。它的优势是入门容易、纯 Python 编码、开发效率高、UI精美。 上图是用 Streamlit 构建自动驾驶...【详细内容】
2021-12-09  Tags: Web  点击:(24)  评论:(0)  加入收藏
对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右时间。。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,...【详细内容】
2021-12-08  Tags: Web  点击:(23)  评论:(0)  加入收藏
10月18号, W3C中网络平台孵化器小组(Web Platform Incubator Community Group)公布了HTML Sanitizer API的规范草案。这份草案用来解决浏览器如何解决XSS攻击问题。 网络安全中...【详细内容】
2021-12-07  Tags: Web  点击:(20)  评论:(0)  加入收藏
【网络通信 -- WebRTC】WebRTC 基础知识 -- ICE 交互总结【1】ICE 的一般概念简介ICE 角色offer (主动发起)的一方为 controlling 角色answer (被动接受)的一方为 controlle...【详细内容】
2021-11-30  Tags: Web  点击:(24)  评论:(0)  加入收藏
来源:AirPython作者:星安果 1. 前言大家好,我是安果!之前推荐过很多优秀的 Web 自动化工具,比如:Selenium、Helium、Cypress、Pyppeteer 等利用它们实现自动化的前提是必须安装依...【详细内容】
2021-11-30  Tags: Web  点击:(31)  评论:(0)  加入收藏
▌简易百科推荐
以京训钉开发平台接口文档为例,使用HttpClient类请求调用其接口,对数据进行增删改查等操作。 文档地址: https://www.yuque.com/bjjnts/jxd/bo1oszusing System;using System.C...【详细内容】
2021-12-28  Wednes    Tags:HttpClient   点击:(1)  评论:(0)  加入收藏
阿里云与爱快路由安装组网教程一、开通好阿里云轻量服务器之后在服务器运维-远程连接处进行远程 二、进入控制台后在root权限下根据需要安装的固件位数复制下面命令。32位:wg...【详细内容】
2021-12-28  ikuai    Tags:组网   点击:(1)  评论:(0)  加入收藏
HTTP 报文是在应用程序之间发送的数据块,这些数据块将通过以文本形式的元信息开头,用于 HTTP 协议交互。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应...【详细内容】
2021-12-27  程序员蛋蛋    Tags:HTTP 报文   点击:(5)  评论:(0)  加入收藏
一 网络概念:1.带宽: 标识网卡的最大传输速率,单位为 b/s,比如 1Gbps,10Gbps,相当于马路多宽2.吞吐量: 单位时间内传输数据量大小单位为 b/s 或 B/s ,吞吐量/带宽,就是网络的使用率...【详细内容】
2021-12-27  码农世界    Tags:网络   点击:(3)  评论:(0)  加入收藏
1.TCP/IP 网络模型有几层?分别有什么用? TCP/IP网络模型总共有五层 1.应用层:我们能接触到的就是应用层了,手机,电脑这些这些设备都属于应用层。 2.传输层:就是为应用层提供网络...【详细内容】
2021-12-22  憨猪哥08    Tags:TCP/IP   点击:(35)  评论:(0)  加入收藏
TCP握手的时候维护的队列 半连接队列(SYN队列) 全连接队列(accepted队列)半连接队列是什么?服务器收到客户端SYN数据包后,Linux内核会把该连接存储到半连接队列中,并响应SYN+ACK报...【详细内容】
2021-12-21  DifferentJava    Tags:TCP   点击:(10)  评论:(0)  加入收藏
你好,这里是科技前哨。 随着“元宇宙”概念的爆火,下一代互联网即将到来,也成了互联网前沿热议的话题,12月9日美国众议院的听证会上,共和党议员Patrick McHenry甚至宣称,要调整现...【详细内容】
2021-12-17  王煜全    Tags:Web3   点击:(14)  评论:(0)  加入收藏
一、demopublic static void main(String[] args) throws Exception { RetryPolicy retryPolicy = new ExponentialBackoffRetry( 1000, 3);...【详细内容】
2021-12-15  程序员阿龙    Tags:Curator   点击:(22)  评论:(0)  加入收藏
一、计算机网络概述 1.1 计算机网络的分类按照网络的作用范围:广域网(WAN)、城域网(MAN)、局域网(LAN);按照网络使用者:公用网络、专用网络。1.2 计算机网络的层次结构 TCP/IP四层模...【详细内容】
2021-12-14  一口Linux    Tags:网络知识   点击:(31)  评论:(0)  加入收藏
无论是在外面还是在家里,许多人都习惯了用手机连接 WiFi 进行上网。不知道大家有没有遇到过这样一种情况, 明明已经显示成功连接 WiFi,却仍然提示“网络不可用”或“不可上网”...【详细内容】
2021-12-14  UGREEN绿联    Tags:WiFi   点击:(25)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条