在浏览器中实现RTMP推流

什么是RTMP

  • 引用自Adobe官方说明

    RTMP(Real-Time Messaging Protocol) 是为了能在基于Adobe Flash平台的技术间实现音频、视频及数据的高性能传输而设计的,包括Adobe Flash Player和Adobe AIR。现在,RTMP已经可以被作为一项开放的标准,用于那些支持视频、音频及其他数据传输的产品或技术,只要传输的数据格式能与Adobe Flash Player适配(如swf、flv、f4v等)。

关于RTMP推流

“视频直播”是近两年互联网产业里很火的一个版块,大大小小的视频网站、APP层出不穷,而RTMP是目前市面上实现视频直播所采用的最主流的数据传输方式。常规的方式是,视频主播通过OBS等推流软件将摄像头捕捉的视频通过RTMP协议传输到指定的服务器地址,服务器将接收到的视频流以m3u8格式保存下来,客户端再通过拉取RTMP数据流的方式获取到视频数据并播放。

以上所描述大概就是一个基本的视频直播模型。那么,如果想要直接在浏览器中向RTMP服务器推流又该如何实现呢?这也并非难事,目前市面上大部分浏览器都可以很好的支持Flash,别忘了,RTMP技术正是为了Flash而生的!只需要几行简单的ActionScript代码,我们就能轻松搞定。

ActionScript & Flex

Flex是Adobe官方提供的一款ActionScript开发框架,Flex提供了丰富的API,并能将ActionScript编译成可被Flash Player执行的swf文件。在开始工作之前,我们需要在开发环境中下载并安装Flex SDK

通过ActionScript我们可以实现通过摄像头和麦克风捕捉画面和声音并将媒体数据通过网络流推送至RTMP服务器的工作:

  cam = Camera.getCamera();
  ns = new NetStream(nc);
  ns.attachCamera(cam);
  ns.publish(name, "live");

更多细节可以参考这个简单的例子

借助Flex SDK中的 mxmlc, ActionScript最终会被编译成swf文件并嵌入我们的网页中,我们只要通过javascript调用swf文件暴露出的接口,就能实现对推流过程的操作。

这里,提供一个现成的 Web端实现RTMP推流的Javascript库(可以通过bower或npm获得),该库遵循AMD规范,开发者可以通过Requirejs之类的AMD加载器引入自己的项目中。其原理正是上面所提到的,通过调用swf暴露出的接口,来实现对RTMP数据流的控制。这个库提供了一些基础的API,比如设置视频采集的帧率、摄像头品质、麦克风品质等,如果没有特殊的需求,只需要引入项目中编译好的swf文件及 rtmp-streamer.min.js,通过javascript提供的API就能实现基本的推流功能了。如果需要更多复杂的特性,也可以通过修改ActionScript的代码来实现,Flex提供了丰富的接口帮助你实现对摄像头及数据流的操作。更详细使用说明,请参见项目文档

这里提供一个简单的例子: 在html文件中, 需要引入 RtmpStreamer.swf 文件:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh_cn" lang="zh_cn">  
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312"/>
    <title>rtmp streamer example</title>
    <script data-main="main" src="require.js"></script>
</head>  
<body style="text-align: center;">

rtmp address:  
<input id="url" type="text" style="width: 400px;" value="rtmp://localhost:1935/live" title="url">  
<input id="stream-name" type="text" style="width: 150px;" value="myStream" title="stream-name">

<h2>Streamer</h2>  
<object>  
    <embed id="rtmp-streamer" src="../RtmpStreamer.swf" bgcolor="#999999" quality="high"
           width="320" height="240" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"></embed>
</object>  
<br>  
<button id="publish"> push</button>  
<button id="streamer-disconnect"> disconnect</button>

<hr>

<h2>Player</h2>  
<object>  
    <embed id="rtmp-player" src="../RtmpStreamer.swf" bgcolor="#999999" quality="high"
           width="320" height="240" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"></embed>
</object>  
<br>  
<button id="play"> play</button>  
<button id="player-disconnect"> disconnect</button>

</body>

<script lang="javascript">

</script>

</html>  

在js文件里, 我用 RequireJs 将rtmp-streamer包加载进来:

require.config({  
    paths: {
        "rtmp-streamer": "../rtmp-streamer.min"
    }
});

require(["rtmp-streamer"], function (RtmpStreamer) {

    var getUrl = function () {
        return document.getElementById('url').value;
    };

    var getName = function () {
        return document.getElementById('stream-name').value;
    };

    var streamer = new RtmpStreamer(document.getElementById('rtmp-streamer'));
    var player = new RtmpStreamer(document.getElementById('rtmp-player'));

    document.getElementById("play").addEventListener("click", function () {
        player.play(getUrl(), getName());
    });

    document.getElementById("publish").addEventListener("click", function () {
        streamer.publish(getUrl(), getName());
    });

    document.getElementById("streamer-disconnect").addEventListener("click", function () {
        streamer.disconnect();
    });

    document.getElementById("player-disconnect").addEventListener("click", function () {
        player.disconnect();
    });

});

运行效果如下:

RTMP服务器

RTMP作为一种比较成熟的技术,市面上的服务端项目不论是开源的还是商业软件都有不少的选择,这里推荐一个叫Wowza的RTMP服务器,如果作为个人学习使用,下载一个免费试用版来玩一玩还是挺不错的。

采用直播云服务

直播业务对服务器的负载和网络延迟都有较高的要求, 如果不是很大规模的项目, 一般直接采用靠谱的直播云服务的比较划算, 这里我们以七牛云为例:

设置参数的方式和用OBS等工具推流时的方式类似, 地址为直播云的空间名, 数据流名称为直播流的名称加鉴权参数:

在七牛的直播云管理后台中预览推流视频:

Show Comments