新版本浏览器播放rtmp流媒体替代方案

2,169 阅读4分钟

新版本浏览器播放rtmp流媒体替代方案

RTMP(Real Time Messaging Protocol)实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输 开发的开放协议

背景:目前监控直播大多采用的是rtmp协议的流媒体推流,要想正常播放需要依赖flash插件。但是随着新版本浏览器(谷歌浏览器高于88版本)禁用flash插件,rtmp就不能再新版本浏览器中播放了。

解决方案

  1. 更换流媒体服务器播放协议,如:HTTP-FLV、HLS等协议
    Web 浏览器:HTTP-FLV、HLS,移动浏览器HLS、FLV(需要考虑兼容性),移动Native or 小程序RTMP、HTTP-FLV、HLS。
  2. 安装支持flash插件的低版本浏览器(谷歌低于88版本)
    简单直接粗暴,但是低版本的浏览器安装包找起来比较麻烦。
  3. nginx-http-flv-module
    nginx-http-flv-module是在nginx-rtmp-module基础上开发的一个直播模块。它是Nginx的一个优秀的第三方模块,可以用来直播,支持RTMP,HLS和DASH方式直播,还支持调用第三方软件进行转码,录制视频等功能,由于依托Nginx,性能也比较高。但是美中不足的地方也不少,例如首屏时间长,不支持HTTP-FLV方式直播,不支持虚拟主机(vhost)功能,省略listen配置无法接受连接,有很多很明显的bug等问题。
  4. webrtc
    使用python-opencv-ffmpeg进行收流,再推给SRS流服务器,最后浏览器H5使用JSwebrtc播放webrtc流。

本文将介绍nginx-http-flv-module解决方案。

项目实战

一、环境搭建

  1. 安装nginx
wget http://nginx.org/download/nginx-1.20.0.tar.gz

确保nginx版本要大于等1.9.11,创建nginx目录,并解压到对应目录下

mkdir /usr/local/nginx
tar -zxvf nginx-1.20.0.tar.gz -C /usr/local/nginx
  1. 下载nginx-http-flv-module,并解压到nginx目录下
wget https://github.com/winshining/nginx-http-flv-module/archive/master.zip
mv nginx-http-flv-master.zip /usr/local/nginx
cd /usr/local/nginx
unzip nginx-http-flv-master.zip

如果没有unzip命令,可以安装一下zip在进行解压

yum install -y unzip zip
  1. 安装编译模块
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel

二、编译nginx

将nginx-http-flv-module模块编译进 nginx,执行以下命令,等待nginx编译完成

cd /usr/local/nginx/nginx-1.22.0
./configure --add-module=/usr/local/nginx/nginx-http-flv-module
make 
make build

三、修改nginx.conf

cd /usr/local/nginx/conf
vi nginx.conf

配置转发规则

http {
    ...
    server {
        listen       8080;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        # 前端请求路径,匹配到/live会进行直播拉流
        location /live {
            flv_live on;
            chunked_transfer_encoding on;

            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Credentials' 'true';
        }
    }

} 
rtmp {
    server {
        listen 1935; 
        notify_method get;
        # 应用名称
        application live {
            live on;
            pull rtmp://ns8.indexforce.com/home/mystream; # 拉流的地址
            # 如果服务器有安装ffmpeg 可以做在线转码
            #exec ffmpeg -r 24 -i rtmp://ns8.indexforce.com/home/mystream -preset:v ultrafast -tune zerolatency -c:v libx264 -profile:v baseline -level 3.0 -an -s 1280x720 -f flv rtmp://127.0.0.1/720p/$name;
        }
    }
} 

启动nginx

cd /usr/local/nginx/sbin
./nginx 

查看是否启动成功

./nginx -v 

查看服务能否正常访问

curl localhost:8080

访问流媒体通用路径

http://example.com[:port]/dir?[port=xxx&]app=appname&stream=streamname

参数 dir 用于匹配 http 配置块中的 location 块。

HTTP 默认端口为 80, 如果使用了其他端口,必须指定 :port。

RTMP 默认端口为 1935,如果使用了其他端口,必须指定 port=xxx。

参数 app 的值(appname)用来匹配 application 块,但是如果请求的 app 出现在多个 server 块中,并且这些 server 块有相同的地址和端口配置,那么还需要用匹配主机名的 server_name 配置项来区分请求的是哪个 application 块,否则,将匹配第一个 application 块。

参数 stream 的值(streamname)用来匹配发布的流的名称。

假设在 http 配置块中的 listen 配置项是:

http {
    ...
    server {
        listen 8080; #不是默认的 80 端口
        ...

        location /live {
            flv_live on;
        }
    }
}

在 rtmp 配置块中的 listen 配置项是:

rtmp {
    ...
    server {
        listen 1935;
        ...

        application myapp {
            live on;
        }
    }
}

并且发布的流的名称是 mystream,那么基于 HTTP 的播放 url 是:

http://example.com:8080/live?port=1985&app=myapp&stream=mystream

更多详情见(github.com/winshining/…)

四、前端视频播放

前端使用flv.js来播放视频。

cd /usr/local/nginx/html
vi index.html

使用以下代码内容替换原来目录下的index.html内容

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script src="flv.min.js"></script>
    <video id="videoElement" autoplay muted></video>
    <script>
        if (flvjs.isSupported()) {
            var videoElement = document.getElementById('videoElement');
            var flvPlayer = flvjs.createPlayer({
                type: 'flv',
                isLive:true,
                // 写入本机ip,app对应application 名称,stream
                url: 'http://ip:8080/live?port=1935&app=live&stream=stream'
            });
            flvPlayer.attachMediaElement(videoElement);
            flvPlayer.load();
            flvPlayer.play();
        }
    </script>
</body>
</html>

再将flv.min.js 上传到/usr/local/nginx/html目录下

打开浏览器使用http://服务器ip:8080 访问前端页面,页面视频成功播放

最终效果如图

五、参考资料