因為有需要所以簡單研究下監控視頻直播流,需要把監控的(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;
width: 1024px;
margin-left: auto;
margin-right: auto;
}
.urlInput {
display: block;
width: 100%;
margin-left: auto;
margin-right: auto;
margin-top: 8px;
margin-bottom: 8px;
}
.centeredVideo {
display: block;
width: 100%;
height: 576px;
margin-left: auto;
margin-right: auto;
margin-bottom: auto;
}
.controls {
display: block;
width: 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可以正常推,不知道什么問題,如果有知道的麻煩告知一下