视频监控RTSP转HLS解决方案
介绍
视频监控RTSP转RTMP转HLS解决方案
由于公司业务,需要实现基于WEB访问监控摄像头实时流的预览,经过各种百度,补充了不少相关知识,了解到了很多大神的实现方法,也因为很多过时的帖子,而踩了不少的坑。
尝试过nginx ffmpeg的方案,虽然可行,但是实现单摄像头还行,想不明白如何实现多摄像头预览,尝试过写脚本,同时处理多个摄像头,但结果是服务器卡死。
后来尝试通过代码,动态根据当前要访问的设备,来调用ffmpeg命令处理该设备,最终因效果不好,而且各种无法控制而告终。
最终无意间浏览到一大神写的使用javacv实现通过调用ffmpeg库的实现方法,于是就尝试用此方法推流给nginx,由nginx负责将流切片保存,并配置nginx自动删除旧的切片,以节省硬盘空间。
运行流程
使用说明
- 参考根目录下的nginx.conf来配置自己的web代理nginx
- 解压nginx-rtmp-server.zip,这是作为rtmp流服务器用的nginx版本,可自行修改conf/nginx.conf配置
- 导入monitor-rtsp-hls至eclipse,右键Main.java运行即可,生产环境可打成jar包来运行也可导出为war包部署tomcat运行
说明:
本服务负责将各个监控设备的实时视频rtsp协议流,转换为rtmp协议流,推送给nginx的rtmp服务, 然后由nginx的rtmp模块将流切片,转换为m3u8 ts格式片断,然后由nginx对外提供web访问m3u8和ts片段的服务,供页面呈现
运行流程
1.用户访问nginx路由:http://127.0.0.1:8888/hls/{{设备编码}}/index.m3u8 2.nginx匹配到该路由,将请求转发至本服务,nginx路由规则:
代码语言:javascript复制location ~ /hls/([0-9] )/index.m3u8 {
proxy_pass http://127.0.0.1:8083/$1;
}
3.本服务的ProcessController的index接收到请求,从getPara(0)获取到设备编码,然后根据设备编码从配置文件中找到设备的rtsp协议地址,基于javacv将数据流推送给nginx的rtmp模块。
我做的是使用Redis存储设备编码,通过Lua脚本从Redis中获取设备号
rtmp地址如:
代码语言:javascript复制rtmp://127.0.0.1:1935/hls/#(code)
推流线程中设置了转换持续最大时间,因为页面播放器会不断的请求m3u8文件,也就是会不断的请求本服务的转换请求,如果在有效时间内请求,只是重新激活线程,重新开始计时,如果有效期到了,则线程会自动结束,防止无用的浪费CPU资源。 4.nginx的rtmp模块接收推送流,进行切片生成ts片段,并生成m3u8格式媒体列表
代码语言:javascript复制rtmp{
server{
listen 1935;
application hls{
live on;
hls on;
hls_path 'E:/Server/html/hls'; #hls存放路径
hls_fragment 5s;
hls_playlist_length 60s;
hls_continuous on; #连续模式
hls_cleanup on; #对多余的切片进行删除
hls_nested on; #嵌套模式
}
}
}
5.由nginx提供对外访问ts文件的服务
代码语言:javascript复制server{
listen 8888;
#匹配m3u8请求,转发给后端rtmp推流服务
location ~ /hls/([0-9] )/index.m3u8 {
proxy_pass http://127.0.0.1:8083/$1;
}
#ts片段文件匹配
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
add_header Cache-Control no-cache;
#后端配置支持HTTP1.1,必须配
proxy_http_version 1.1;
proxy_set_header Connection "";
alias 'E:/Server/html/hls'; #ts片段存放路径
autoindex on;
expires 24h;
}
#rtmp状态查看
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root 'E:/Server/nginx 1.7.12.1 Lizard with rtmp/nginx-rtmp-module/';
}
}