简介

视频直播服务目前支持三种直播协议,分别是RTMP、HLS、FLV 以下内容来自阿里云帮助中心

  • RTMP 实时消息传输协议,由Adobe公司研发,但当前还没有收入国际标准(wikipedia)。协议比较全能,既可以用来推送又可以用来直播,其核心理念是将大块的视频帧和音频帧“剁碎”,然后以小数据包的形式在互联网上进行传输,且支持加密,因此隐私性相对比较理想,但拆包组包的过程比较复杂,所以在海量并发时容易出现一些不可预期的稳定性问题。

  • HLS 协议:基于HTTP协议的流直播(wikipedia)。苹果推出的解决方案,将视频分成 5-10 秒的视频小分片,然后用 m3u8 索引表进行管理。由于客户端下载到的视频都是 5-10 秒的完整数据,故视频的流畅性很好,但也同样引入了很大的延迟(HLS 的一般延迟在 10-30s 左右)。相比于 FLV, HLS 在iPhone 和大部分 Android 手机浏览器上的支持非常给力,所以常用于 QQ 和微信朋友圈的 URL 分享。

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

下面看一下三种技术的对比:
live-tech-table.png

在 Vue 中应用

我们做的直播项目用 Vue 编写,后台主要输出 RTMP 和 HLS 的直播流

播放器使用的是 vue-video-player,其实就是 video.js 集成到 vue 中

注意点

下面说说用这个插件来直播的一些坑和注意点吧:

首先,常用的 demo 在 vue-video-player 中官方已经给出了,按要求来就可以,其中

  1. 如果需要播放 HLS 流,需要安装 videojs-contrib-hls 插件,非原生支持的浏览器,直播服务端需要开启 CORS(后面会讲到)
  2. 如果需要播放 RTMP 流,需要安装 videojs-flash 插件
  3. 如果两个流都需要播放,flash 插件需要安装到 hls 插件之前

兼容性

下面说下这两个直播流的兼容性问题

  1. RTMP: 上面说了 RTMP 是 Adobe 公司研发的协议,目前主要的直播服务都主推 RTMP 流,它延时小,但是需要 flash 插件的支持,也需要的上面提到的安装 videojs-flash 的插件。但是在 MAC 下对 flash 插件支持不友好,而且 MAC 下的 flash 插件 firefox 浏览器和 chrome 还是两个插件。。这就很尴尬。

  2. HLS: 这个协议兼容性较好,但是最大的缺点是延迟较高,大概 20s 左右,所以只能当做备选方案。

说 HLS 兼容性较好,主要是指可以通过 JS 让用户免配置(不必安装flash),可以在 caniuse 看下 HLS 的支持程度:http://caniuse.com/#search=HLS

只有 EdgeSafari 提供原生支持,其他浏览器都需要 JS 插件支持。那是不是只要引了 videojs-contrib-hls 就 ok 了呢?❌,这里面还有个坑。这个坑在该插件的官方文档有说明:

Unlike a native HLS implementation, the HLS tech has to comply with the browser's security policies. That means that all the files that make up the stream must be served from the same domain as the page hosting the video player or from a server that has appropriate CORS headers configured. Easy instructions are available for popular webservers and most CDNs should have no trouble turning CORS on for your account.

简单的意思就是:除了原生支持 HLS 的浏览器,其他浏览器要想播 HLS,需要直播流服务端开启 CORS。

最后我们使用的方案是。优先使用 RTMP 流,如果不支持,就切换到 HLS 流。好在这个切换过程 video.js 会自动替我们做。下面贴一下相关配置代码。

配置代码

Vue 实例中的播放器 options,更多代码见 https://github.com/savokiss/vue-videojs-demo

      playerOptions: {
        autoplay: false, // 自动播放
        controls: true, // 是否显示控制栏
        techOrder: ['flash', 'html5'], // 兼容顺序
        sourceOrder: true, // 
        flash: { hls: { withCredentials: false } },
        html5: { hls: { withCredentials: false } },
        sources: [{ // 流配置,数组形式,会根据兼容顺序自动切换
          type: 'rtmp/mp4',
          src: 'rtmp://184.72.239.149/vod/&mp4:BigBuckBunny_115k.mov'
        }, {
          withCredentials: false,
          type: 'application/x-mpegURL',
          src: 'http://playertest.longtailvideo.com/adaptive/bipbop/gear4/prog_index.m3u8'
        }],
        poster: "/static/img/no_data.png", // 播放器默认图片
        // controlBar: { // 配置控制栏
        //   timeDivider: false, // 时间分割线
        //   durationDisplay: false, // 总时间
        //   progressControl: true, // 进度条
        //   customControlSpacer: true, // 未知
        //   fullscreenToggle: true // 全屏
        // },
      },

最后

以上是最近研究直播项目的一些小的总结吧,直播中其他的技术暂时还没有涉及到,以后涉及到也会总结出来,如果有问题可以拍砖交流~
最后欢迎给我的 demo 项目 star 啊啊啊啊~

参考文档