Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

了解直播技术 #35

Open
dcharlie123 opened this issue Mar 25, 2020 · 0 comments
Open

了解直播技术 #35

dcharlie123 opened this issue Mar 25, 2020 · 0 comments
Labels

Comments

@dcharlie123
Copy link
Owner

dcharlie123 commented Mar 25, 2020

常见直播协议

RTMP

RTMP是Macromedia开发的一套视频直播协议,现在属于adobe ,这套方案需要搭建专门的 RTMP 流媒体服务如 Adobe Media Server,并且在浏览器中只能使用 FLASH 实现播放器。它的实时性非常好,延迟很小,但无法支持移动端 WEB 播放是它的硬伤。html5中根据网上资料可用video.js实现播放(//TODO)

HLS

HTTP Live Streaming(简称 HLS)是一个基于 HTTP 的视频流协议。这是 Apple 提出的直播流协议。目前,IOS 和 高版本 Android 都支持 HLS。那什么是 HLS 呢?HLS 主要的两块内容是 .m3u8 文件和 .ts 播放文件。
HLS 协议基于 HTTP,而一个提供 HLS 的服务器需要做两件事:
编码:以 H.263 格式对图像进行编码,以 MP3 或者 HE-AAC 对声音进行编码,最终打包到 MPEG-2 TS(Transport Stream)容器之中;
分割:把编码好的 TS 文件等长切分成后缀为 ts 的小文件,并生成一个 .m3u8 的纯文本索引文件;
浏览器使用的是 m3u8 文件。m3u8 跟音频列表格式 m3u 很像,可以简单的认为 m3u8 就是包含多个 ts 文件的播放列表。播放器按顺序逐个播放,全部放完再请求一下 m3u8 文件,获得包含最新 ts 文件的播放列表继续播,周而复始。整个直播过程就是依靠一个不断更新的 m3u8 和一堆小的 ts 文件组成,m3u8 必须动态更新,ts 可以走 CDN。

http-flv

基于http流式IO传输flv。HTTP-FLV 协议由 Adobe 公司主推,格式极其简单,只是在大块的视频帧和音视频头部加入一些标记头信息,由于这种极致的简洁,在延迟表现和大规模并发方面都很成熟。唯一的不足就是在手机浏览器上的支持非常有限,但是用作手机端 APP 直播协议却异常合适。

avatar

question

  • flv.js无法在ios及低版浏览器使用的原因:使用了 Media Source Extensions API,由于依赖Media Source Extensions,目前所有iOS和Android4.4.4以下里的浏览器都不支持,也就是说目前对于移动端flv.js基本是不能用的。caniuse
  • HLS延迟高的原因:

我们知道 hls 协议是将直播流分成一段一段的小段视频去下载播放的,所以假设列表里面的包含 5 个 ts 文件,每个 TS 文件包含 5 秒的视频内容,那么整体的延迟就是 25 秒。因为当你看到这些视频时,主播已经将视频录制好上传上去了,所以时这样产生的延迟。当然可以缩短列表的长度和单个 ts 文件的大小来降低延迟,极致来说可以缩减列表长度为 1,并且 ts 的时长为 1s,但是这样会造成请求次数增加,增大服务器压力,当网速慢时回造成更多的缓冲,所以苹果官方推荐的 ts 时长时 10s,所以这样就会大改有 30s 的延迟。参考资料:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaG

采集

  • 音频采集(音频的采集过程主要通过设备将环境中的模拟信号采集成 PCM 编码的原始数据,然后编码压缩成 MP3 等格式的数据分发出去。)
  • 图像采集(图像的采集过程主要由摄像头等设备拍摄成 YUV 编码的原始数据,然后经过编码压缩成 H.264 等格式的数据分发出去。)

处理

  • 美颜
  • 鉴黄

编码

编码的意义

视频编码是本系列一个重要的部分,如果把整个流媒体比喻成一个物流系统,那么编解码就是其中配货和装货的过程,这个过程非常重要,它的速度和压缩比对物流系统的意义非常大,影响物流系统的整体速度和成本。同样,对流媒体传输来说,编码也非常重要,它的编码性能、编码速度和编码压缩比会直接影响整个流媒体传输的用户体验和传输成本。而经过 H.264 编码压缩之后,视频大小只有 708 k 、10 Mbps 的带宽仅仅需要 500 ms ,可以满足实时传输的需求,所以从视频采集传感器采集来的原始视频势必要经过视频编码。

编码器

  • H.264
  • HEVC/H.265
  • VP8
  • VP9
  • FFmpeg

封装

封装可以理解为采用哪种货车去运输,也就是媒体的容器。
目前,我们在流媒体传输,尤其是直播中主要采用的就是 FLV 和 MPEG2-TS 格式,分别用于 RTMP/HTTP-FLV 和 HLS 协议。

推流和传输

传输协议

  • RTMP

RTMP 是 Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于 TCP,是一个协议族,包括 RTMP 基本协议及 RTMPT/RTMPS/RTMPE 等多种变种。RTMP 是一种设计用来进行实时数据通信的网络协议,主要用来在 Flash/AIR 平台和支持 RTMP 协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括 Adobe Media Server/Ultrant Media Server/red5 等。目前推流协议大部分采用的rtmp协议。在浏览器端基于flv格式(FLV是Flash Video的简写,是一种文件体积小,适合在网络上传输的封包方式。),在浏览器端播放依赖于FLASH。
优点:CDN 支持良好,主流的 CDN 厂商都支持;协议简单,在各平台上实现容易。
缺点:基于 TCP ,传输成本高,在弱网环境丢包率高的情况下问题显著;不支持浏览器推送;Adobe 私有协议,Adobe 已经不再更新。

  • WebRTC
  • 基于 UDP 的私有协议
  • HLS

HLS 全称是 HTTP Live Streaming。这是 Apple 提出的直播流协议。,iOS和 Android 都天然支持这种协议,配置简单,直接使用video标签即可。
简单讲就是把整个流分成一个个小的,基于 HTTP 的文件来下载,每次只下载一些,前面提到了用于 H5 播放直播视频时引入的一个 .m3u8 的文件,这个文件就是基于 HLS 协议,存放视频流元数据的文件。每一个 .m3u8 文件,分别对应若干个 ts 文件,这些 ts 文件才是真正存放视频的数据,m3u8 文件只是存放了一些 ts 文件的配置信息和相关路径,当视频播放时,.m3u8 是动态改变的,video 标签会解析这个文件,并找到对应的 ts 文件来播放,所以一般为了加快速度,.m3u8 放在 Web 服务器上,ts 文件放在 CDN 上。
.m3u8 文件,其实就是以 UTF-8 编码的 m3u 文件,这个文件本身不能播放,只是存放了播放信息的文本文件。

  • HTTP-FLV

HTTP-FLV 和 RTMP 类似,都是针对于 FLV 视频格式做的直播分发流。但,两者有着很大的区别。

  • 直接发起长连接,下载对应的 FLV 文件
  • 头部信息简单

现在市面上,比较常用的就是 HTTP-FLV 进行播放。但,由于手机端上不支持,所以,H5 的 HTTP-FLV 也是一个痛点。

解码和渲染*

具体:现代播放器原理

上面封装提到了‘视频文件格式实际上我们常常称作为容器格式’,传到用户端如何将该盒子解开?就需要找到对应的解码器进行解码

前端直播相关

各浏览器支持的视频格式

各浏览器支持的视频格式

  • flv格式依赖于flash,但是由于浏览器已不内置flash

由于各大浏览器的对 FLV 的围追堵截,导致 FLV 在浏览器的生存状况堪忧,但是,FLV 凭借其格式简单,处理效率高的特点,使各大视频后台的开发者都舍不得启用,如果一旦更改的话,就需要对现有视频进行转码,比如变为 MP4,这样不仅在播放,而且在流处理来说都有点重的让人无法接受。而 MSE 的出现,彻底解决了这个尴尬点,能够让前端能够自定义来实现一个 Web 播放器,确实完美。(不过,苹果老大爷觉得没这必要,所以,在 IOS 上无法实现。)——《不再碎片化学习,快速掌握 H5 直播技术》
MSE 全称就是 Media Source Extensions。它是一套处理视频流技术的简称,里面包括了一系列 API:Media Source,Source Buffer 等。在没有 MSE 出现之前,前端对 video 的操作,仅仅局限在对视频文件的操作,而并不能对视频流做任何相关的操作。现在 MSE 提供了一系列的接口,使开发者可以直接提供 media stream。
b站开源的flv.js就是基于MSE,解析flv数据,通过MSE封装成fMP4喂给video标签

怎么选:

我们知道 hls 协议是将直播流分成一段一段的小段视频去下载播放的,所以假设列表里面的包含 5 个 ts 文件,每个 TS 文件包含 5 秒的视频内容,那么整体的延迟就是 25 秒。因为当你看到这些视频时,主播已经将视频录制好上传上去了,所以时这样产生的延迟。当然可以缩短列表的长度和单个 ts 文件的大小来降低延迟,极致来说可以缩减列表长度为 1,并且 ts 的时长为 1s,但是这样会造成请求次数增加,增大服务器压力,当网速慢时回造成更多的缓冲,所以苹果官方推荐的 ts 时长时 10s,所以这样就会大改有 30s 的延迟。参考资料:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaG——《h5视频直播扫盲》

根据观察,目前各大直播平台,移动端网页直播用的基本是hls的m3u8格式,例如b站,YouTube,虎牙,斗鱼等,不强调互动性,对流畅度比较高,一般选用HLS,延时在10秒以上。
需要较低延迟(3-5秒),可以选用rtmp和http-flv,但是需要考虑兼容性,依赖flash或MSE意味着放弃部分端;如果需要实时通讯IM,直播答题这些对延迟要求更高的,可能可以考虑webRTC,因为无论是HLS还是RTMP、http-flv都基于TCP。
下一代低延时直播CDN:HLS、RTMP 与UDP +WebRTC
进击的WebRTC:我们为什么需要它?
WebRTC 中文教程
在web移动端hls协议直播是目前兼容性较好的因为其输出的m3u8格式在移动端都能播放(无需插件),如果我们想要移动端和pc端都能播放直播有以下两种解决方法:

  1. 移动端采用hls输出m3u8,pc端使用http-flv用b站的flv.js库播放(mse在pc端浏览器兼容性还行,基本可以播放,可以看https://caniuse.com/#search=Media%20Source%20Extensions浏览器兼容)。
  2. 全部使用hls输出m3u8,然后由于PC端播放不了m3u8格式,需要使用hls.js或者video.js解析,下面以video.js为例(央视1直播源:http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8):
    video.js
<!DOCTYPE html>
<html lang="en">


<head>
    <title>Video.js | HTML5 Video Player</title>
    <script src="https://cdn.bootcss.com/video.js/7.7.6/video.min.js"></script>
    <link href="https://cdn.bootcss.com/video.js/7.7.5/alt/video-js-cdn.min.css" rel="stylesheet">
</head>

<body>
    <video id="my-player" class="video-js">
    </video>
</body>
<script>
    const videojs = window.videojs || _videojs
    var player = videojs('my-player', {
        width: '360px',
        autoplay: true,
        controls: true,
        // preload: 'auto',
        // fluid: false,
        // muted: false,
        controlBar: {
            remainingTimeDisplay: false,
            playToggle: {},
            progressControl: {},
            fullscreenToggle: {},
            volumeMenuButton: {
                inline: false,
                vertical: true
            }
        },
        sources: [{
            type: "application/x-mpegURL",
            src: "http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8" //你的m3u8地址(必填)
        }],
        poster: "https://surmon-china.github.io/vue-quill-editor/static/images/surmon-3.jpg",
        techOrder: ['html5'],
        plugins: {}
    }, function () {
        console.log(111)
    })
</script>

</html>

由于水平有限各个协议没有深入学习,只是根据网络上的网站、文档浅显的了解,可能存在错误,欢迎指正。

参考文章

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant