方案简述

之前搭建过使用RTMP协议推流 前端基于Flash的直播流服务 奈何历史潮流不可挡 马上就到2020年底Adobe都要彻底停止支持 想起某位总加速师还在拼命加速倒车... 2018new_kuxiao_thumb.png

flv.js

flv.js是来自Bilibli的开源项目。它解析FLV文件喂给原生HTML5 Video标签播放音视频数据,使浏览器在不借助Flash的情况下播放FLV成为可能。( 顺带着膜谦谦大神 批判狗日的逼站 如何看待哔哩哔哩的 flv.js 作者月薪不到 5000 元?)

flv.js只做了一件事,在获取到FLV格式的音视频数据后通过原生的JS去解码FLV数据,再通过Media Source Extensions API 喂给原生HTML5 Video标签。(HTML5 原生仅支持播放 mp4/webm 格式,不支持 FLV)

flv.js 为什么要绕一圈,从服务器获取FLV再解码转换后再喂给Video标签呢?原因如下:

  1. 兼容目前的直播方案:目前大多数直播方案的音视频服务都是采用FLV容器格式传输音视频数据。
  2. FLV容器格式相比于MP4格式更加简单,解析起来更快更方便。

livego

Simple and efficient live broadcast server:

  • Very simple to install and use;
  • Pure Golang, high performance, and cross-platform;
  • Supports commonly used transmission protocols, file formats, and encoding formats;

Supported transport protocols
RTMP、AMF、HLS、HTTP-FLV
Supported container formats
FLV、TS
Supported encoding formats
H264、AAC、MP3

大致方向就是OBS使用RTMP协议推流给livego服务器 livego从RTMP中拿出FLV格式音视频数据 flv.js通过HTTP向livego拉取FLV数据解码并喂给浏览器Video标签实现播放

  • OBS Studio ---> livego ---> flv.js

  • RTMP: 底层基于TCP,在浏览器端依赖Flash。

  • HTTP-FLV: 基于HTTP流式IO传输FLV,依赖浏览器支持播放FLV。

livego部署

在这里通过容器部署 开放RTMP 1935端口、HTTP-FLV 7001端口、HTTP-API 8090端口 HLS端口暂时用不到

docker run -d -p 1935:1935 -p 7001:7001 -p 8090:8090 --name mylivego gwuhaolin/livego

容器运行起来后 通过HTTP-API获取获取频道密钥用于推流 (不得不说livego还挺适合二次开发的 f48.png )

GET http://服务器地址:8090/control/get?room=频道或房间名


OBS推流

推RTMP:rtmp://服务器地址:1935/live

livego-OBS


flv.js前端

拉FLV:http://服务器地址:7001/live/频道或房间名.flv

<!DOCTYPE html>
<html>
<head>
    <title>flv.js_demo</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.5.0/flv.min.js"></script>
</head>
<body>
    <video id="videoElement" autoplay muted></video>
    <script>
        if (flvjs.isSupported()) {
            var videoElement = document.getElementById('videoElement');
            var flvPlayer = flvjs.createPlayer({
                type: 'flv',
                isLive: true,
                enableWorker: true,
                enableStashBuffer: false,
                stashInitialSize: 128,   // 减少首桢显示等待时长
                url: 'http://192.168.1.9:7001/live/test.flv'
            });
            flvPlayer.attachMediaElement(videoElement);
            flvPlayer.load();
            flvPlayer.play();
        }
    </script>
</body>
</html>
  1. 这里flv.js引用自前端开源项目免费CDN服务BootCDN

  2. muted是用来设置视频静音 不然Chrome浏览器可以会出现这个错误 (原因未知 很迷 2018new_wenhao_thumb.png ) :
    Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first. https://goo.gl/xX8pDD

  3. 下面这三个参数为优化选项 参考https://github.com/gwuhaolin/blog/issues/3