科普:直播知多少

1 前言

全民购物节双十一结束了,李佳琪薇娅直播间的交易金额高达70亿,大家有没有贡献自己的钱包?现在在直播中可以实现各种活动,比如说卖货、教育、竞赛、企业会议等。直播模式以高效率、高互动率,已经完爆其他模式。各大平台相继推出了自己的直播功能。今天就来给大家科普下直播相关的知识。

2 直播的基本概念

2.1 直播和点播

直播 直播视频源是实时的,一旦主播停播,直播地址就失去意义,而且由于是实时直播,所以播放器在播直播视频的时候是没有进度条的。

点播 点播视频源是某个服务器上的文件,只要文件没有被提供方删除,就可以随时播放, 而且由于整个视频都在服务器上,所以播放器在播点播视频的时候是有进度条的。

2.2 推流和拉流

直播是由三部分组成:推流端、拉流端和服务器。推流端就是我们所说的主播端,把自己拍摄的东西用手机或电脑传送出去。拉流端就是观众端,观看主播推送的内容。流(stream):数据在网络上按时间先后次序传输和播放的连续音/视频数据流。

推流 :指的是把采集阶段封包好的内容传输到服务器的过程。采集的工具主要有手机、PC、摄像头等。推流的方式有摄像头推流、录屏推流、摄像头推流+录屏推流。

直播卖货一般采用的是摄像头推流。电子竞赛一般采用的就是 摄像头推流+录屏推流。

拉流 :指服务器已有直播内容,用指定地址进行拉取的过程。根据协议类型(如RTMP、RTSP、HTTP等),与服务器建立连接并接收数据。

现在各大公司推流基本用的都是APP或者PC推流,因为APP客户端和PC能直接操作系统、可以直接向服务器推送数据。H5更多的是承接端外的一个场景,以拉流为主。当然H5也可以基于WebRTC实现推流,这个可以放到下次再讲。

2.3 视频编解码codec

视频实际上就是一帧一帧的图片,拼接起来进行播放;标准的图像格式使用 RGB 三字节描述像素颜色值,会占用较大的存储空间与带宽。视频编解码器会根据前后图像的变化做运动检测,通过各种压缩把变化的结果发送到对方。

实时视频编码器需要考虑两个因素:编码计算量和码率带宽,实时视频会运行在移动端上,需要保证实时性就需要编码足够快,码率尽量小。基于这个原因现阶段一般认为 H.264 是最佳的实时视频编码器,而且各个移动平台也支持它的硬编码技术。音频一般使用ACC(高级音频编码)格式。

3 常见的几种直播协议

上面提到的推流和拉流都是需要

3.1 Real Time Messaging Protocol(RTMP)

RTMP,即实时消息传送协议。是由Macromedia公司提出,后来被Adobe 公司收购,作为Flash 播放器和服务器之间音视频数据传输开发的私有协议。工作在 TCP 之上的明文协议,默认使用端口 1935。协议中的基本数据单元成为消息(Message),传输的过程中消息会被拆分为更小的消息块(Chunk)单元。最后将分割后的消息块通过 TCP 协议传输,接收端再反解接收的消息块恢复成流媒体数据。

直播流地址举例:某卫视,rtmp://live..lxdns.com/live/hks

优点:延迟低

缺点:Adobe私有协议,播放需要安装flash插件,可能会被防火墙阻拦(因为是基于TCP协议)

一般推流端使用比较多。

3.2 Real-Time Streaming Protocol (RTSP)

RTSP 是由Real Network和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议。RTSP对流媒体提供了诸如暂停,快进等控制,而它本身并不传输数据,RTSP的作用相当于流媒体服务器的远程控制。服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。而且允许同时多个串流需求控制(Multicast),除了可以降低服务器端的网络用量,还可以支持多方视频会议(Video onference)。

直播流地址举例:rtsp://**vod/mp4://BigBuckBunny_175k.mov

RTSP一般用来做视频点播、视频监控等(单向)。当然,根据它的实现原理,它也可以实现双向视频通话

3.3 Dynamic Adaptive Streaming over HTTP (MPEG-DASH)

MPEG-DASH 是最新的协议之一。虽然还没被广泛支持,但是我觉得未来应该会成为主流。

首先,MPEG-DASH 支持码率自适应。这意味着将始终为观众提供他们当前互联网连接速度可以支持的最佳视频质量。网络速度波动时 DASH 可以保持不间断播放。

其次,MPEG-DASH 几乎支持所有编解码器,还支持加密媒体扩展(Encrpted Media Extensions,简写EME)和媒体扩展源(Media Source Extension,简写MSE),这些扩展用于浏览器的数字版权管理标准API。

优点:支持所有编解码器,跨平台支持

缺点:还未得到广泛支持

3.4 HTTP-FLV

FLV (Flash Video) 是 Adobe 公司推出的另一种视频格式,是一种在网络上传输的流媒体数据存储容器格式。其格式相对简单轻量,不需要很大的媒体头部信息。整个 FLV 由 The FLV Header, The FLV Body 以及其它 Tag 组成。因此加载速度极快。采用 FLV 格式封装的文件后缀为 .flv。HTTP-FLV,即将音视频数据封装成 FLV,然后通过 HTTP 协议传输给客户端。

相比 RTMP 的优点:

  • 可以在一定程度上避免防火墙的干扰 (例如, 有的机房只允许 80 端口通过);
  • 可以很好的兼容 HTTP 302 跳转,做到灵活调度;
  • 可以使用 HTTPS 做加密通道;
  • 很好的支持移动端(Android,IOS)。

3.5 HTTP Live Streaming (HLS)

HLS, 是2009年,由Apple公司定义的基于HTTP的流媒体实时传输协议。愿意是删除掉Flash插件,现在各大浏览器它的原理是将整个流分为多个小的文件来下载,每次只下载若干个。服务器端会将最新的直播数据生成新的小文件,客户端只要不停的按顺序播放从服务器获取到的文件,就实现了直播。基本上,HLS是以点播的技术实现了直播的体验。因为每个小文件的时长很短,客户端可以很快地切换码率,以适应不同带宽条件下的播放。

地址举例:http://ivi.*.cn/hls/cctv1hd.m3u8(某卫视)

分段推送的技术特点,决定了HLS的延迟一般会高于普通的流媒体直播协议,只适合直播播放,不适合互动直播。

HLS传输内容包括两部分:一是M3U8描述文件,二是TS媒体文件。TS媒体文件中的视频必须是H264编码,音频必须是AAC或MP3编码。下面是一个M3U8文件里的内容。

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:NO
#EXT-X-MEDIA-SEQUENCE:1606135349
#EXT-X-TARGETDURATION:6
#EXTINF:5.869,
19842_1330843442602852012-1606135349.ts
#EXTINF:3.93,
19842_1330843442602852012-1606135350.ts
  • EXTM3U 表明该文件是一个 m3u8 文件。每个M3U8文件必须将该标签放置在第一行。
  • EXT-X-VERSION 的协议版本号,该标签与流媒体的兼容性相关。该标签为全局作用域,使能整个 m3u8 文件;每个 m3u8 文件内最多只能出现一个该标签定义。如果 m3u8 文件不包含该标签,则默认为协议的第一个版本。
  • EXT-X-MEDIA-SEQUENCE 每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号+1。
  • EXT-X-TARGETDURATION 指定最大的媒体段时间长(秒)。所以#EXTINF中指定的时间长度必须小于或是等于这个最大值
  • EXTINF 指定每个媒体段(ts)的持续时间,这个仅对其后面的URI有效,每两个媒体段URI间被这个tag分隔开。在这个文件里包含了两段ts文件

HLS 理论上延时=1个切片的时长+ 0-1个td(td是EXT-X-TARGETDURATION,可简单理解为播放器取片的间隔时间) + 0-n个启动切片(苹果官方建议是请求到3个片之后才开始播放) + 播放器最开始请求的片的网络延时(网络连接耗时)。

也许你会想说通过缩减切片的时长,可以降低延时,但是切片越小,那请求的次数变多了,会造成服务端的压力,超时的情况下会出现丢包的可能,会造成卡顿的现象。苹果官方建议是切片的时长为10秒。我们公司设置的是4秒,整个延迟可能就在10秒左右。

缺点:延时高

优点:

  • 基于HTTP协议,不会被屏蔽
  • 兼容性好

4 H5拉流

作为前端工程师,我们更关心在浏览器里怎么无插件播放直播流,先从MSE开始。

4.1 MSE

随着HTML5的普及,我们已经可以在 Web 应用程序上无插件地播放视频和音频了。但是,由于架构过于简单,只能满足一次播放整个曲目的需要,无法实现拆分/合并数个缓冲文件。

<video src="demo.mp4"></video>

2016年11月17日, W3C正式推出媒体源扩展API(MSE,Media Source Extentions),实现无插件且基于 Web 的流媒体的功能。它定义了 MediaSource 对象,作为H5中HTMLMediaElement的媒体数据源。MediaSource 对象可以有一个或多个SourceBuffer对象。应用程序可以向 SourceBuffer 对象动态添加数据片段,并可以根据系统性能及其他因素自适应调整所添加媒体数据的数据质量。来自 SourceBuffer 对象的数据可以解码为音频、视频或文本数据,并由浏览器或播放器处理。

4.2 hls.js

hls.js是一个轻量级的JavaScript库,基于H5 <audio>、<video>和MSE 用来播放流媒体。我们H5直播播放器用的是腾讯封装的TcPlayer,它也是基于hls.js的封装。下面是一个hls.js的简单应用。

<video id="video"></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
var video = document.getElementById('video');
var videoSrc = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';
if (Hls.isSupported()) {
  var hls = new Hls();
  hls.loadSource(videoSrc);
  hls.attachMedia(video);
  hls.on(Hls.Events.MANIFEST_PARSED, function() {
    video.play();
  });
}
</script>

hls库的核心思想是事件触发,定义了一个EventEmitter监听hls的各种事件。这是一个基本的流程。hls会通过ajax请求M3U8文件,然后获取到切片列表,以及视频的编码格式、时长。然后按照顺序请求ts文件,解析ts文件区分出音频buffer、视频buffer,字幕buffer等,然后借用MSE合成可以播放的媒体资源文件。

4.3 flv.js

本来HTTP-FLV只支持客户端,H5需要安装插件才可以播放。但是Bilibili公司开源了一个Javascript 库——flv.js,使得浏览器可以不用安装插件就可以播放flv格式的视频。它的工作原理是将 FLV 文件流转码复用成 ISO BMFF(MP4 碎片)片段,然后通过 Media Source Extensions 将 MP4 片段喂进浏览器。

5 总结

因为我司购买的是腾讯云直播服务,所以播放方式都是采用腾讯封装好的SDK,大体上的协议分为:

  • 推流端:客户端采用RTMP协议推流;
  • 拉流端:客户端采用的是 HTTP-FLV 协议拉流,H5采用的是HLS协议。

比较特殊的一点,客户端直播底层播放是原生的功能,上层和用户互动的界面是半屏M页,比如说商品列表页。半屏M页是客户端实现的用半屏webview打开H5,来和直播间进行互动。这是考虑到IOS、安卓开发周期长,不能热更新。虽然牺牲了点体验优化,但是提高了开发效率、节约了人力成本。

写在最后的话,本文主要对直播的一些知识的概述,并没有深入探讨。如果大家有兴趣的话,下次可以深入科普原理。

发表评论

邮箱地址不会被公开。 必填项已用*标注

相关