CodeMaker

world change code

RTSP转HLS集成Web系统直播实现

继上一篇海康DS-2CD3325-I配Face++人脸识别预研,现有监控系统接入人脸识别能力后,实时监控、抓拍、跟踪和录播功能与Web应用系统的集成一体化也是非常应用化的功能。
从随处可在网上找到的方案中看到,只要将现有摄像头的RTSP转HLS就可以实现Web页面的直播,之前折腾WebRTC的时候了解过现行的一些流媒体服务推拉流实现,这里选用Nginx+RTMP插件简单验证(成熟的落地全家桶以后详述),流程配置大致如下:

Centos安装Ningx,RTMP

Nginx不是大井的主向,所以我是全新编译安装:

1
2
3
4
5
6
7
wget http://nginx.org/download/nginx-1.8.1.tar.gz
git clone https://github.com/arut/nginx-rtmp-module.git
tar -zxvf nginx-1.8.1.tar.gz
cd nginx-1.8.1
./configure --add-module=../nginx-rtmp-module
make
sudo make install

Nginx配置

nginx配置文件在/usr/local/nginx/conf,如果找不到用whereis nginx.conf看看,你可以直接vi /usr/local/nginx/conf
去编辑,但Windows系推荐用Xftp更方便直观,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
user  root;
worker_processes 1;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application vod {
play /etc/opt/video/vod;
}
application live {
live on;
hls on; #这个参数把直播服务器改造成实时回放服务器。
wait_key on; #对视频切片进行保护,这样就不会产生马赛克了。
hls_path /etc/opt/video/hls; #切片视频文件存放位置。
hls_fragment 1s; #每个视频切片的时长。
hls_playlist_length 3s; #总共可以回看的时间,这里设置的是1分钟。
# disable consuming the stream from nginx as rtmp
#deny play all;
hls_continuous on; #连续模式。
hls_cleanup on; #对多余的切片进行删除。
hls_nested on; #嵌套模式。
}
}
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /root/nginx-rtmp-module;
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /etc/opt/video/hls;
expires -1;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

注意顶部的use root提权,保存配置后,重启nginx:sudo ./sbin/nginx -s reload
划重点:
上面的配置网上抄作业的很多,工不工作就看有没有消化,这里主要干了几件事:

  • rtmp开了一个vod,在/etc/opt/video/vod下放了一个视频文件,方便用VLC检查拉流是否工作,如:rtmp://192.168.2.111/vod/test.mp4
  • rtmp开了一个live,用来接受推流,可以用OBS测试,注意:OBS推流配置中可变的房间号填在<串流密钥>处,字符不行就换数字,如rtmp://192.168.2.111/live + 串流密钥room,VLC拉流实际为:rtmp://192.168.2.111/live/room(而ffmpeg中可直接写)。live同时开启了hls直播,后面是直播相关配置。
  • http server部分,一个stat站点,用来可视化rtmp推拉流工作概况,注意stat站点读取stat.xsl,其中/root/nginx-rtmp-module路径因人而异
  • server里还有一个hls站点,其中/etc/opt/video/hls是.ts切片和m3u8路径,如:http://192.168.2.111/hls/room/index.m3u8可以直接用VLC打开播放。

OBS推流VLC拉流测试

有了流媒体服务器,你就可以像对接直播平台一样,OBS推入,VLC拉取直观的看到效果。不考虑网络差异理论上RTMP延迟在5s左右。

HTML直播

这种HLS的原理类似把流截成了.ts片的存放,切片的大小和个数与网络延迟之间的关系要根据实际测试结果调整把握,量少可能会导致web端去拉的时候已经删除,太小虽然延迟低但是增加了HTTP Request数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
<head>
<title>demo</title>
<meta charset="utf-8">
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
<script src="https://unpkg.com/video.js/dist/video.js"></script>
<script src="https://unpkg.com/videojs-contrib-hls/dist/videojs-contrib-hls.js"></script>
</head>
<body>
<video id="myvideo" class="video-js vjs-default-skin" controls preload="none" width="640" height="264" data-setup="{}">
<source src="http://192.168.2.111/hls/room/index.m3u8" type='application/x-mpegURL'>
</video>
<script type="text/javascript">
var myPlayer = videojs('myvideo');
videojs("myvideo").ready(function () {
var myPlayer = this;
myPlayer.play();
});
</script>
</body>
</html>

总结

这种常见的RTSP转推RTMP/HLS方式综合来说可用性稳定性都还行,但是切片式web直播特点还是延迟下不来,好处是有个缓存效果,实际经过切片调整,延迟也维持在8-10s,而VLC直接播放RTMP流延迟也在4-6s的样子,不管是HLS还是RTMP在对实效性要求比较高的Web监控系统里都比较难以接受,总不能事故发生了,Web端5-10s才反应出来,人都跑了。后面项目最终落地了再写一篇。