本文采用nginx+rtmp方式搭建流媒體服務(wù)器,使用obs推流,rtmp+flv拉流的方式實(shí)現(xiàn)
服務(wù)端配置
nginx+nginx-http-flv-module介紹
nginx-http-flv-module介紹
nginx-http-flv-module是在nginx-rtmp-module基礎(chǔ)上開發(fā)的一個(gè)直播模塊。
感謝Arut創(chuàng)造了nginx-rtmp-module,它是Nginx的一個(gè)優(yōu)秀的第三方模塊,可以用來直播,支持RTMP,HLS和DASH方式直播,還支持調(diào)用第三方軟件進(jìn)行轉(zhuǎn)碼,錄制視頻等功能,由于依托Nginx,性能也比較高。但是美中不足的地方也不少,例如首屏?xí)r間長(zhǎng),不支持HTTP-FLV方式直播,不支持虛擬主機(jī)(vhost)功能,省略listen配置無法接受連接,有很多很明顯的bug等問題。
nginx-http-flv-module解決了上述的問題。
為什么選擇Nginx作為支持HTTP-FLV方式直播的服務(wù)器呢?
因?yàn)镹ginx的Web服務(wù)器功能對(duì)HTTP協(xié)議的支持非常完善,Nginx的性能優(yōu)秀,經(jīng)過了很多場(chǎng)景的檢驗(yàn)。另外,Nginx本身對(duì)第三方軟件的依賴較少,非常易于部署。這些都使得它成為HTTP-FLV方式直播服務(wù)器不可多得的選擇。
nginx-http-flv-module功能
- 兼容nginx-rtmp-module所有功能,基于nginx-rtmp-module的流媒體服務(wù)器。
- 支持HTTP-FLV方式的直播
- 支持GOP緩存,以減少首屏?xí)r間
- 支持虛擬主機(jī)功能
- 可以省略listen配置項(xiàng)而不影響基本功能
- 修復(fù)nginx-rtmp-module已知的bug
nginx-http-flv-module 安裝配置
- 下載nginx包
下載地址:https://nginx.org/download/nginx-1.14.2.tar.gz - 下載nginx-http-flv-module 模塊包
下載地址:https://github.com/winshining/nginx-http-flv-module
與nginx-rtmp-module功能對(duì)比
- nginx-http-flv-module的其他功能與nginx-rtmp-module的對(duì)比:
| 功能 | nginx-http-flv-module | nginx-rtmp-module | 備注 |
|---|---|---|---|
| HTTP-FLV (播放) | √ | x | 支持HTTPS-FLV和chunked回復(fù) |
| GOP緩存 | √ | x | |
| 虛擬主機(jī) | √ | x | |
省略listen配置 |
√ | 見備注 | 配置中必須有一個(gè)listen
|
| 純音頻支持 | √ | 見備注 |
wait_video或wait_key開啟后無法工作 |
| 定時(shí)打印訪問記錄 | √ | x | |
| JSON風(fēng)格的stat | √ | x |
- NGINX的版本應(yīng)該大于1.2.6,與其他版本的兼容性未知。
- Linux(推薦)/FreeBSD/MacOS/Windows(受限)
- 支持的播放器 VLC (RTMP & HTTP-FLV)/OBS (RTMP & HTTP-FLV)/JW Player (RTMP)/flv.js (HTTP-FLV).
- flv.js只能運(yùn)行在支持Media Source Extensions的瀏覽器上
nginx+nginx-http-flv-module安裝
安裝依賴項(xiàng)
yum -y install unzip
yum -y install gcc-c++
yum -y install pcre pcre-devel
yum -y install zlib zlib-devel
yum -y install openssl openssl-devel
將nginx-http-flv-module.zip 解壓到/usr/local/nginx下面
unzip nginx-http-flv-module-1.2.6.zip //解壓文件
//解壓文件復(fù)制到/usr/local/nginx 目錄下
cp /opt/toos/nginx-http-flv-module-1.2.6.zip /usr/local/nginx/nginx-http-flv-module
將nginx-http-flv-module模板添加到nginx中,生成make文件 并安裝nginx
/opt/tools
tar -zxvf nginx-1.18.1.tar.gz
cd nginx-1.18.1
./configure --prefix=/usr/local/nginx --add-module=/usr/local/nginx/nginx-http-flv-module
make && make install
修改配置文件
cd /usr/local/nginx/conf
vim nginx.conf
-------------------------------------------------------------------------------
worker_processes 10;
error_log logs/error.log error;
#如果此模塊被編譯為動(dòng)態(tài)模塊并且要使用與RTMP相關(guān)的功
#能時(shí),必須指定下面的配置項(xiàng)并且它必須位于events配置
#項(xiàng)之前,否則NGINX啟動(dòng)時(shí)不會(huì)加載此模塊或者加載失敗
#load_module modules/ngx_http_flv_live_module.so;
events {
worker_connections 10240; #Nginx處理的最大連接數(shù)
}
#因?yàn)镹ginx可能開啟多個(gè)子進(jìn)程,這個(gè)選項(xiàng)表示推流時(shí),媒體流會(huì)發(fā)布到多個(gè)子進(jìn)程
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
#多個(gè)子進(jìn)程情況下,推流時(shí),最開始只有一個(gè)子進(jìn)程在競(jìng)爭(zhēng)中接收到數(shù)據(jù),然后它再relay給其他子進(jìn)程,他們之間通過unix domain socket傳輸數(shù)據(jù),這個(gè)選項(xiàng)表示unix domain socket的路徑
rtmp_socket_dir /tmp;
rtmp{
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;
drop_idle_publisher 15s;
log_interval 5s; #log模塊在access.log中記錄日志的間隔時(shí)間,對(duì)調(diào)試非常有用
log_size 1m; #log模塊用來記錄日志的緩沖區(qū)大小
server{
listen 1935;
# server_name www.test.*; #用于虛擬主機(jī)名后綴通配
application live{
live on;
record off;
gop_cache on; #打開GOP緩存,減少首屏等待時(shí)間
#notify_method get;
#publish_notify on;
#on_publish http://192.168.0.103:8087/autho/rtmp; #這里進(jìn)行權(quán)限控制
#on_publish_done http://127.0.0.1:8087/autho/rtmpOver;#直播結(jié)束回調(diào)
#pull rtmp://live.hkstv.hk.lxdns.com/live/hks; #如果懶得推流,那可以用這個(gè),香港衛(wèi)視的直播推流
}
application hls{
live on;
hls on;
hls_path /home/soap/rtmp/hls;#視頻流存放地址
hls_fragment 5s;
hls_playlist_length 15s;
hls_continuous on; #連續(xù)模式。
hls_cleanup on; #對(duì)多余的切片進(jìn)行刪除。
hls_nested on; #嵌套模式。
}
application dash{
live on;
dash on;
dash_path /usr/local/nginx/html/dash;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
add_header Access-Control-Allow-Origin $http_origin always; # '*'
add_header Access-Control-Allow-Credentials true always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
server {
listen 8002;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location /live {
flv_live on; #打開HTTP播放FLV直播流功能
chunked_transfer_encoding on; #支持'Transfer-Encoding: chunked'方式回復(fù)
}
location /hls{
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /usr/local/nginx/html/hls;
add_header 'Cache-Control' 'no-cache';
}
location /dash {
root /usr/local/nginx/html/dash;
add_header 'Cache-Control' 'no-cache';
}
location /stat {
#configuration of push & pull status
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/local/nginx/nginx-http-flv-module;
}
location /control {
rtmp_control all; #configuration of control module of rtmp
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
說明:如果采用動(dòng)態(tài)編譯nginx-http-flv-module模塊的方式,需要將load_module “modules/ngx_http_flv_live_module.so”;前面的#去掉
rtmp測(cè)試地址: rtmp://192.168.102.222:1935/live/串流密鑰
http-flv測(cè)試地址: http://192.168.102.222/live?port=1935&app=live&stream=串流密鑰
視頻推流
OBS推流
Open Broadcaster Software(OBS)是一個(gè)免費(fèi)的開源的視頻錄制和視頻實(shí)時(shí)流軟件。
下載
obs官網(wǎng)
-
安裝后如下:
image.png -
配置好場(chǎng)景來源才能顯示在窗口中
image.png
點(diǎn)擊新建后可以選擇推流的源,可以選擇攝像頭或者顯示器或者某個(gè)窗口
點(diǎn)擊右下角的設(shè)置可以設(shè)置推流的流媒體地址
- 配置推流地址
image.png
如上配置地址為:rtmp://192.168.102.222:1953/live,還有一個(gè)串流密鑰為xxxx,可以隨便寫。
點(diǎn)確定后,再點(diǎn)開始推流即可。 -
添加推流token
image.png
ffmpeg推流
- ffmpeg是個(gè)開源且強(qiáng)大的工具,可在官網(wǎng)直接下載。http://ffmpeg.org/download.html
- 再將ffmpeg的bin目錄導(dǎo)入環(huán)境變量Path。
- 最后,cmd推流命令,詳情請(qǐng)參考這篇資料http://m.itdecent.cn/p/c141fc7881e7
- 舉例,我用??禂z像頭的命令:
ffmpeg -rtsp_transport tcp -i "rtsp://admin:123456@192.168.10.128.19:554/h264/ch1/sub/av_stream" -vcodec copy -acodec aac -f flv "rtmp://192.168.55.65:1935/myapp/video19"
-g 25:每隔25幀,插入一個(gè)關(guān)鍵幀,可提高緩沖速度。而且延遲不會(huì)明顯增加。
為了實(shí)現(xiàn)首屏秒開使用-g設(shè)置gop大小,同時(shí)使用-b降低網(wǎng)絡(luò)負(fù)載,保證流暢度。
#linux
ffmpeg -r 30 -i /dev/video0 -vcodec h264 -max_delay 100 -f flv -g 5 -b 700000 rtmp://219.216.87.170/live/test1
#window
ffmpeg -r 30 -f vfwcap -i 0 -vcodec h264 -max_delay 100 -f flv -g 5 -b 700000 rtmp://219.216.87.170/live/test1
- url根據(jù)nginx配置文件的不同,而改變。
rtmp://example.com[:port]/appname/streamname
- 注意這里用flv.js音頻配置必須是 aac 否者就會(huì)報(bào)錯(cuò)(除非你不加入音頻)
-vcodec copy -acodec aac -f flv
注意:rtsp協(xié)議默認(rèn)使用udp容易丟數(shù)據(jù)包,所以rtsp強(qiáng)制使用tcp方式可以一定程度避免丟包。
本地視頻推流
把視頻推流至rtmp://127.0.0.1:1935/live/123(127.0.0.1:1935為rtmp服務(wù)器地址、live為nginx配置節(jié)點(diǎn)、123當(dāng)做密鑰)
ffmpeg.exe -re -i demo.wmv -f flv rtmp://127.0.0.1:1935/live/123
ffmpeg -re -i test.h264 -vcodec copy -acodec copy -f flv -y rtmp://ip:port/live/test
循環(huán)多次讀取文件, -1為無限循環(huán)
ffmpeg -re -stream_loop -1 -i 0-0.mp4 -vcodec copy -acodec copy -f flv -y "rtmp://192.168.102.222:1935/live/room"
-re表示重新調(diào)整時(shí)間戳,這樣就能夠?qū)⒏鞣N文件、RTSP源、RTMP源的不均勻時(shí)間戳全部進(jìn)行ffmpeg的重新調(diào)整,再進(jìn)行rtmp推流,保證直播的平滑和hls切片的均勻。
-flvflags no_duration_filesize 這個(gè)參數(shù)是關(guān)鍵,這個(gè)參數(shù)告訴ffmpeg不要拋出duration_filesize警告
相關(guān)參數(shù):
-re 代表按照幀率發(fā)送,否則ffmpeg會(huì)一股腦地按最高的效率發(fā)送數(shù)據(jù)
-stream_loop -1循環(huán)次數(shù),-1表示自動(dòng)循環(huán)
-i "發(fā)送文件路徑"指定要發(fā)送的源文件
-vcodec copy 表示視頻解碼使用原有格式,如果報(bào)錯(cuò)可以修改類型,如使用-vcodec h264,B站要求不超過1500
-acodec aac 表示視頻解碼使用AAC格式,如果報(bào)錯(cuò)可以修改類型,如使用-vcodec copy,未設(shè)定時(shí)則使用與輸入流相同的編解碼器
-b:v 1500k 指定視頻碼率為1500k,默認(rèn)為200Kbit/s
-b:a 320k 指定音頻碼率為320k
-r 60 指定幀率為60幀/s,如果不寫這個(gè)參數(shù)默認(rèn)為25
-f flv 設(shè)定輸出格式為flv
-headers "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"
攝像頭推流
攝像頭名稱為USB2.0 PC CAMERA,而且推流服務(wù)器ip為127.0.0.1:1935,關(guān)鍵字為live
ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
麥克風(fēng)推流
ffmpeg -f dshow -i audio="麥克風(fēng) (2- USB2.0 MIC)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
和前面差不多,聲音被推流出去了,通過vlc拉流可以聽到錄制的聲音,但很明顯不會(huì)有畫面
攝像頭&麥克風(fēng)推流
這次要實(shí)現(xiàn)同時(shí)推流攝像頭畫面與聲音,此時(shí)我們的語句應(yīng)該如下
ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -f dshow -i audio="麥克風(fēng) (2- USB2.0 MIC)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
或者
ffmpeg -f dshow -i video="USB2.0 PC CAMERA":audio="麥克風(fēng) (2- USB2.0 MIC)" -vcodec libx264 -r 25 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
畫面與聲音源源不斷的被推流到服務(wù)器,接下來我們就應(yīng)該正式的開發(fā)拉流了。
拉流
VLC
-
安裝后啟動(dòng)的樣子
image.png -
點(diǎn)擊媒體后可以選擇打開網(wǎng)絡(luò)串流
image.png -
選擇網(wǎng)絡(luò)在URL里面輸入流媒體服務(wù)器的IP和串流密鑰
image.png
點(diǎn)擊播放按鈕此時(shí)就成功了
ckplayer播放器拉流
下載
https://www.ckplayer.com/down/
下載完成后直接打開sample\rtmp.html,并把拉流地址修改為上面的地址,如下:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="video" style="width: 600px; height: 400px;"></div>
<script type="text/javascript" src="../ckplayer/ckplayer.js"></script>
<script type="text/javascript">
var videoObject = {
container: '#video', //容器的ID或className
variable: 'player',//播放函數(shù)名稱
autoplay:false,
live:true,
video: 'rtmp://192.168.102.222:1935/live/room' //room是串流密鑰
};
var player = new ckplayer(videoObject);
</script>
</body>
</html>
刷新頁面出現(xiàn)如下頁面

注意:此方式只能適用于IE(not edge.)
HTTP-FLV
HTTP-FLV,即將音視頻數(shù)據(jù)封裝成 FLV,然后通過 HTTP 協(xié)議傳輸給客戶端。
樣例如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>播放頁面</title>
</head>
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.5.0/flv.min.js"></script>
<video style="height: 400px;width: 600px;" id="videoElement" muted autoplay controls></video>
<script>
var flvPlayer = null;
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
flvPlayer = flvjs.createPlayer({
type: 'flv',
// 8080 對(duì)應(yīng)Nginx監(jiān)聽的端口
// rtmpLive 對(duì)應(yīng)Nginx的路徑
url: 'http://192.168.102.222/live?port=1935&app=live&stream=room'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
}
</script>
</body>
</html>
注意:參數(shù)port對(duì)應(yīng)端,app對(duì)應(yīng)application, stream對(duì)應(yīng)串流密鑰
與vue整合
引入flv.js
import flvjs from 'flv.js/dist/flv.min.js'
html
<video class="video" #videoElement id="videoElementflv" controls muted>
播放失敗
</video>
具體js代碼如下:
/**
* @description flv視頻播放
*/
flvVideoPlayer() {
if (this.httpSrc && flvjs.isSupported()) {
if (this.flvPlayer) {// 每次播放前先卸載之前組件
this.flvPlayer.pause()
this.flvPlayer.unload()
this.flvPlayer.detachMediaElement()
this.flvPlayer.destroy()
this.flvPlayer = null
}
let videoElement = this.video.nativeElement
this.flvPlayer = flvjs.createPlayer({
type: 'flv',
enableWorker: true, //瀏覽器端開啟flv.js的worker,多進(jìn)程運(yùn)行flv.js
isLive: true, //直播模式
hasAudio: true, //開啟音頻
hasVideo: true,
stashInitialSize: 128,
enableStashBuffer: false, //播放flv時(shí),設(shè)置是否啟用播放緩存,只在直播起作用。
url: this.httpSrc,
})
this.flvPlayer.attachMediaElement(videoElement)
this.flvPlayer.load()
this.flvPlayer.play()
this.flvPlayer.on('error', (err) => {
console.log('err-------------------', err)
})
}
}
最后
如果您已經(jīng)看到這里了,希望您還是點(diǎn)個(gè)贊再走吧~
您的點(diǎn)贊是對(duì)作者的最大鼓勵(lì),也可以讓更多人看到本篇文章!






