新版本浏览器播放rtmp流媒体替代方案
RTMP(Real Time Messaging Protocol)实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输 开发的开放协议
背景:目前监控直播大多采用的是rtmp协议的流媒体推流,要想正常播放需要依赖flash插件。但是随着新版本浏览器(谷歌浏览器高于88版本)禁用flash插件,rtmp就不能再新版本浏览器中播放了。
解决方案
- 更换流媒体服务器播放协议,如:HTTP-FLV、HLS等协议
Web 浏览器:HTTP-FLV、HLS,移动浏览器HLS、FLV(需要考虑兼容性),移动Native or 小程序RTMP、HTTP-FLV、HLS。 - 安装支持flash插件的低版本浏览器(谷歌低于88版本)
简单直接粗暴,但是低版本的浏览器安装包找起来比较麻烦。 - nginx-http-flv-module
nginx-http-flv-module是在nginx-rtmp-module基础上开发的一个直播模块。它是Nginx的一个优秀的第三方模块,可以用来直播,支持RTMP,HLS和DASH方式直播,还支持调用第三方软件进行转码,录制视频等功能,由于依托Nginx,性能也比较高。但是美中不足的地方也不少,例如首屏时间长,不支持HTTP-FLV方式直播,不支持虚拟主机(vhost)功能,省略listen配置无法接受连接,有很多很明显的bug等问题。 - webrtc
使用python-opencv-ffmpeg进行收流,再推给SRS流服务器,最后浏览器H5使用JSwebrtc播放webrtc流。
本文将介绍nginx-http-flv-module解决方案。
项目实战
一、环境搭建
- 安装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
- 下载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
- 安装编译模块
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 访问前端页面,页面视频成功播放