因为有需要所以简单研究下监控视频直播流,需要把监控的(Onvif)协议通过硬盘录像机(RTSP)转成视频播放(RTMP)通过flv.js进行web直播,所以先从简单入手,走了不少坑,在此记录一下
建议有问题的话多看官方文档,文档地址在下面
先简单介绍下各种流媒体协议
RTMP(Real Time Messaging Protocol)是基于TCP的,由Adobe公司为Flash播放器和服务器之间音频、视频传输开发的开放协议。
HLS(HTTP Live Streaming)是基于HTTP的,是Apple公司开放的音视频传输协议。
HTTP FLV则是将RTMP封装在HTTP协议之上的,可以更好的穿透防火墙等。
Http_flv 对比 RTMP
这两个协议实际上传输数据是一样的,数据都是flv文件的tag。http_flv是一个无限大的http流的文件,相比rtmp就只能直播,而rtmp还可以推流和更多的操作。但是http有个好处,就是是以80http通信的,穿透性强,而且rtmp是非开放协议。
这两个协议是如今直播平台主选的直播方式,主要原因就是延时极低
关于Flv.js
flv.js是B站开源的一款HTML5 Flash Video(FLV)播放器
官方文档:https://github.com/Bilibili/flv.js
一、环境准备
1.1 环境描述:
服务器系统CentOS7.4(os:这两天的Centos新闻挺多啊,希望RockyLinux早点出来)
服务器:Nginx和nginx-http-flv-module模块作为推流服务端(之前是用的旧的nginx-rtmp-module,坑,nginx-http-flv-module具有nginx-rtmp-module所有功能)
nginx-http-flv-module和nginx-rtmp-module的对比
推流端工具:FFmpeg
拉流端:h5+ng、VLC测试
视频转码:x264
重点文档,有问题可以查询这里,非常详细
nginx-http-flv-module的官方地址:https://github.com/winshining/nginx-http-flv-module/blob/master/README.CN.md
1.2 所需工具提前准备,如果后续步骤下载失败可手动下载
-
1 . Nginx编译包:https://nginx.org/download/nginx-1.19.5.tar.gz
-
2 . Nginx所需模块nginx-http-flv-module:https://github.com/winshining/nginx-http-flv-module/archive/master.zip
-
4 . x264: https://code.videolan.org/videolan/x264/-/archive/master/x264-master.zip
-
5 . nasm: https://www.nasm.us/pub/nasm/releasebuilds/2.14/nasm-2.14.tar.gz
如果以上仍下载失败,可以到百度网盘进行下载,如果需要新版本下载可留言
链接:https://pan.baidu.com/s/1S8lMmX2pi8GDM8pd-ehm8w
提取码:7cq6
1.3 所需依赖项,需提前装好
# yum install unzip -y
# yum install gcc-c++ -y
# yum install pcre pcre-devel -y
# yum install zlib zlib-devel -y
# yum install openssl openssl-devel -y
# yum install yasm -y
1.4 海康等摄像头RSTP协议获取
这里是我用到的
rtsp://admin:123456@192.168.1.114:554/Streaming/Channels/101?transportmode=unicast
各种品牌的协议地址:https://blog.csdn.net/qq_38880380/article/details/80652697
二、环境安装
安装默认目录:/usr/local
2.1安装nginx和nginx-http-flv-module模块
这里使用源码编译的方式安装nginx
# cd /usr/local/
# wget http://nginx.org/download/nginx-1.19.5.tar.gz //下载nginx
# tar -zxvf nginx-1.19.5.tar.gz //解压ng
# cd nginx-1.19.5
# wget https://github.com/winshining/nginx-http-flv-module/archive/master.zip
# unzip nginx-http-flv-module-master.zip
# ./configure --prefix=/usr/local/nginx --add-module=./nginx-http-flv-module-master --with-http_ssl_module //编译安装nginx,并指定上面下载的模块路径
2.2修改Nginx配置文件
# cd /usr/local/nginx/conf
# vim nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 9938;
server_name localhost;
location /live {
flv_live on;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
include /usr/local/nginx/conf/vhost/*.conf;
}
rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;
drop_idle_publisher 15s;
log_interval 5s;
log_size 1m;
server {
listen 9909; #监听的端口号
#server_name 127.0.0.1;
application live { #自定义的名字
live on;
}
application hls {
live on;
hls on;
hls_path /tmp/hls;
hls_fragment 1s;
hls_playlist_length 3s;
}
}
}
wq进行保存
检查nginx配置文件,有问题及时修改
# cd /usr/local/nginx/sbin
# ./nginx -t //检查nginx
# ./nginx //启动nginx
# ./nginx -s reload //重载nginx配置使其配置生效
2.3 安装FFmpeg
先安装nasm
# cd /usr/local
# wget https://www.nasm.us/pub/nasm/releasebuilds/2.14/nasm-2.14.tar.gz
# tar -zxvf nasm-2.14.tar.gz
# cd nasm-2.14
# ./configure
# make && make install
再安装x264(视频流转码,必用,不然会推流失败)
# cd /usr/local
# wget https://code.videolan.org/videolan/x264/-/archive/master/x264-master.zip
# unzip x264-master.zip
# cd x264-master
# ./configure --enable-static --enable-shared
# make && make install
安装FFmpeg,时间长耐心等待
# cd /usr/local
# wget http://www.ffmpeg.org/releases/ffmpeg-4.3.tar.gz
# tar ffmpeg-4.3.tar.gz
# tar -zxvf nasm-2.14.tar.gz
# cd ffmpeg-4.3
# ./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-libx264
# make && make install
# cp /usr/local/ffmpeg/bin/* /usr/bin/
# ffmpeg -version
三、进行推流
ffmpeg -re -rtsp_transport tcp -i "rtsp://admin:123456@192.168.1.114:554/Streaming/Channels/101?transportmode=unicast" -f flv -vcodec libx264 -vprofile baseline -acodec aac -strict experimental -ar 44100 -ac 2 -b:a 96k -r 25 -b:v 500k -s 640*480 -f flv -q 10 rtmp://192.168.1.187:9909/live/101
FFmpeg命令大全:https://www.cnblogs.com/AllenChou/p/7048528.html
推流过程可能会遇到ffmpeg: error while loading shared libraries: libx264.so.157: cannot open shared object file: No such file or directory 错误
解决办法:
vim /etc/ld.so.conf
添加:
include /usr/local/lib/
/usr/local/lib/
保存后进行重载
ldconfig
拉流测试
四、web直播拉流
这里有两种web直播方式,RTMP直播和flv.js流直播
4.1video直播流Demo,需要服务器支持,iis,nginx等,或者使用webstorm进行调试,界面如下(假装好使)
<html>
<head>
<title>Live</title>
<meta charset="utf-8">
<link href="http://vjs.zencdn.net/5.5.3/video-js.css" rel="stylesheet">
<!-- If you'd like to support IE8 -->
<script src="http://vjs.zencdn.net/ie8/1.1.1/videojs-ie8.min.js"></script>
<script src="http://vjs.zencdn.net/5.5.3/video.js"></script>
</head>
<body>
<video id="my-video" class="video-js" controls preload="auto" width="640" height="300"
poster="http://img1.178.com/news/201705/289777912560/289777981574.jpg" data-setup="{}">
<source src="rtmp://192.168.1.187:9909/live/101" type="flv">
</p>
</video>
</body>
</html>
4.2FLV直播流Demo,flv.js文件在上面的百度云里
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>flv.js demo</title>
<style>
.mainContainer {
display: block;
1024px;
margin-left: auto;
margin-right: auto;
}
.urlInput {
display: block;
100%;
margin-left: auto;
margin-right: auto;
margin-top: 8px;
margin-bottom: 8px;
}
.centeredVideo {
display: block;
100%;
height: 576px;
margin-left: auto;
margin-right: auto;
margin-bottom: auto;
}
.controls {
display: block;
100%;
text-align: center;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
<p class="mainContainer">
<video name="videoElement" id="videoElement" class="centeredVideo" controls muted autoplay width="1024" height="576">
Your browser is too old which doesn't support HTML5 video.
</video>
</p>
<script src="./flv.js"></script>
<script>
function start() {
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://192.168.1.187:9938/live?port=9909&app=live&stream=101'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
}
document.addEventListener('DOMContentLoaded', function () {
start();
});
</script>
</body>
</html>
4.3 VLC拉流
关于VLC拉流详见:https://blog.csdn.net/macmacip/article/details/90301414,这里不过多介绍了
五、错误汇总
DemuxException: type = CodecUnsupported, info = Flv: Unsupported audio codec idx: 7
flv.min.js:1 Uncaught (in promise) Error: Uncaught, unspecified “error” event. (MediaError)
flv无法播放,这里需要在FFmpeg里添加x264转码流即可
还有个问题是FFmpeg无法推监控的rtmp视频流到腾讯云,flv文件的话就可以,但是用OBS可以正常推,不知道什么问题,如果有知道的麻烦告知一下