什么是流媒體服務(wù)器
流媒體服務(wù)器(Streaming Media Server)是一種用于存儲和傳輸音頻、視頻、直播等媒體內(nèi)容的服務(wù)器軟件。它通過網(wǎng)絡(luò)將媒體文件實(shí)時(shí)傳輸給用戶,而不需要用戶先下載完整文件。流媒體服務(wù)器支持按需播放、實(shí)時(shí)廣播等功能,常見的使用場景包括在線視頻、音頻點(diǎn)播、直播視頻等。
視頻流媒體數(shù)據(jù)傳輸往往對流媒體服務(wù)器編解碼能力和協(xié)議轉(zhuǎn)換有要求,因?yàn)椴煌木幋a格式和不同的協(xié)議適用的場景不同。例如,RTMP協(xié)議延遲低,但是web瀏覽器不支持,需要將其轉(zhuǎn)為HLS或者是FLV才能進(jìn)行播放。
Nginx如何實(shí)現(xiàn)流媒體服務(wù)器
Nginx作為web服務(wù)器的一種,本身關(guān)注點(diǎn)在靜態(tài)資源代理、正反向代理方面,實(shí)現(xiàn)作為流媒體服務(wù)器使用是依賴“插件”來擴(kuò)展。例如:nginx-rtmp-module插件和nginx-http-flv-module插件。
為Nginx安裝nginx-http-flv-module
概述
nginx中的模塊雖然就是類似插件的概念,但是它無法像VsCode那樣輕松的安裝擴(kuò)展。針對像 nginx-http-flv-module 這樣的 nginx 模塊,僅能通過重新編譯 nginx 源碼的方式完成“插件的安裝”。
nginx-http-flv-module 基于 nginx-rtmp-module 二次開發(fā),擁有 nginx-rtmp-module 全部的功能,同時(shí)具備HTTP-FLV播放,這個(gè)功能就很Nice,有了這個(gè)就可以實(shí)現(xiàn)在瀏覽器中觀看直播,針對推送端無需額外的配置,一個(gè)直播流推送到流媒體服務(wù)器,直接可以輸出多種流,包括:rtmp、hls、flv,rtmp用于在桌面應(yīng)用程序中播放,hls和flv用于在瀏覽器中播放,當(dāng)然hls也可以在桌面應(yīng)用程序中播放,在瀏覽器播放方式中flv的畫面延遲明顯由于hls。
需要注意的是 nginx-http-flv-module 要求nginx的版本大于等于1.2.6。由于nginx-http-flv-module包含了 nginx-rtmp-module 模塊,所以不可將 nginx-http-flv-module 和 nginx-rtmp-module 同時(shí)編譯,當(dāng)我們編譯完 nginx-http-flv-module 之后,其實(shí)就已經(jīng)擁有了 nginx-rtmp-module 的完整功能。
流程
- 查看當(dāng)前nginx 的版本(假設(shè)安裝位置為:/usr/local/nginx)
- 下載當(dāng)前版本nginx的源代碼
- 下載 nginx-http-flv-module 模塊源代碼
- 重新編譯nginx并追加nginx-http-flv-module
- 將新編譯好的 nginx 可執(zhí)行文件拷貝到當(dāng)前nginx安裝目錄(/usr/local/nginx/sbin)
操作步驟
使用如下命令查看當(dāng)前已經(jīng)安裝的nginx的版本
[root@bogon sbin]# ./nginx -V nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-pcre --with-http_ssl_module --with-http_gzip_static_module
下載 nginx 源碼和 nginx-http-flv-module 的源碼,示例代碼如下:
wget http://nginx.org/download/nginx-1.18.0.tar.gz tar -zxvf nginx-1.18.0.tar.gz git clone https://github.com/winshining/nginx-http-flv-module.git
進(jìn)入nginx源碼目錄,使用如下命令重新編譯nginx:
./configure --prefix=/usr/local/nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-pcre --with-http_ssl_module --with-http_gzip_static_module --add-module=/home/cml/nginx-http-flv-module make
- 使用configure 配置編譯環(huán)境
- 將上面 保存的“arguments 后面的內(nèi)容”作為configure 的第一個(gè)參數(shù)
- 第二個(gè)參數(shù)為 --add-module=/home/cml/nginx-http-flv-module ,即添加一個(gè)模塊,模塊源代碼位置是 /home/cml/nginx-http-flv-module
- 使用make命令執(zhí)行編譯編譯
編譯成功后,在 objs中會有一個(gè) 名為nginx的可執(zhí)行文件,這個(gè)就是編譯好的nginx了, 里面包含已經(jīng)安裝的功能和新增加的nginx-rtmp-module,將這個(gè)可執(zhí)行文件拷貝到當(dāng)前安裝目錄(/usr/local/nginx/sbin)中就可以了。
注意拷貝之前需要停止nginx,否則會報(bào)當(dāng)前文件繁忙,無法覆蓋的錯(cuò)誤。
通過如下命令驗(yàn)證安裝是否正常:
nginx -V
若打印的信息中包含nginx-http-flv-module,說明安裝好了。
配置流媒體服務(wù)器
當(dāng)安裝好了 nginx-http-flv-module 之后,就可以創(chuàng)建流媒體應(yīng)用了。所謂的創(chuàng)建流媒體應(yīng)用其實(shí)就是編寫 nginx 的配置文件,如果需要創(chuàng)建一個(gè)名為 live 的流媒體應(yīng)用,那么可以在 nginx.conf 中做如下配置
#以下內(nèi)容放可在 nginx.conf 的最后,rtmp 配置塊為頂級配置塊
rtmp_auto_push on ;
rtmp {
server {
listen 1935; #監(jiān)聽的端口
notify_method get;
chunk_size 4000;
application live { #rtmp推流請求路徑
live on;
# 添加 hls 支持
hls on;
hls_path /usr/local/nginx/html/hls;
hls_fragment 3;
hls_playlist_length 60;
# 允許從任何源push 流
allow publish all ;
# 允許從任何地方來播放流
allow play all;
# 20s內(nèi)沒有push,就斷開連接
drop_idle_publisher 20s ;
}
}
}
- listen 1935:指定流媒體服務(wù)器的運(yùn)行端口
- live :為流媒體應(yīng)用的應(yīng)用的名稱,也即流媒體應(yīng)用的唯一標(biāo)識
- live on : 添加直播的支持
- hls_path:指定生成的m3u8文件的位置
之后就是創(chuàng)建http-flv端點(diǎn)和hls端點(diǎn)了,目的是讓直播流可以在http協(xié)議上面?zhèn)鬏斨辈ギ嬅妗?br>若不創(chuàng)建,將僅可以使用rtmp協(xié)議拉流,即rtmp://ip:1935/live/stream_no;若創(chuàng)建了就可以使用hls或者flvjs來拉流播放了。
創(chuàng)建http-flv端點(diǎn)和hls端點(diǎn)同樣是編輯nginx.conf來實(shí)現(xiàn),如下示例配置:
server {
listen 82;
server_name rtmpserver;
# 創(chuàng)建hls端點(diǎn)
location /hls {
add_header 'Access-Control-Allow-Origin' '*' ;
add_header 'Access-Control-Allow-Credentials' 'true' ;
types {
application/vnd.apple.mpegurl m3u8 ;
video/mp2t ts;
}
alias /usr/local/nginx/html/hls;
expires -1 ;
add_header 'Cache-Control' 'no-cache';
}
# 創(chuàng)建 flv 端點(diǎn)
location /flv {
flv_live on ;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
- listen 82 :指定 hls端點(diǎn)和flv端點(diǎn)的監(jiān)聽端口,此端口可以自定義,針對hls端點(diǎn)和flv端點(diǎn)可以分開設(shè)置不同的監(jiān)聽端口
- hls端點(diǎn)的標(biāo)識為 hls,此標(biāo)識可以自定義,拉流的時(shí)候會用到
- alias:指定m3u8文件的訪問路徑,需要和 "創(chuàng)建流媒體應(yīng)用"中的hls_path配置保持一致
- flv端點(diǎn)的標(biāo)識為flv,此標(biāo)識可以自定義,拉流的時(shí)候會用到
使用OBS推流
OBS 是非常成熟的軟件了,安裝參考官網(wǎng):https://obsproject.com/
假設(shè)約定的推拉流地址為 rtmp://192.168.1.115:1935/live/room-1
設(shè)置直播流來源為 視頻采集設(shè)備 和 瀏覽器,其中視頻采集設(shè)備就是筆記本的攝像頭,瀏覽器為OBS內(nèi)置瀏覽器并打開 https://time.is/zh/ 這個(gè)網(wǎng)址。最終的直播畫面就是兩個(gè)采集終端的畫面疊加在一起,底部是一個(gè)網(wǎng)址,網(wǎng)頁中有一個(gè)時(shí)鐘,頂部是攝像頭。
設(shè)置直播服務(wù)器和推流碼:
- 服務(wù)器:即流媒體應(yīng)用的地址,即 rtmp://192.168.1.115:1935/live
- 推流碼:即當(dāng)前推流唯一標(biāo)識,可以隨意指定,保證推拉流地址一致即可,示例為: room-1
點(diǎn)擊開始直播,OBS就開始向流媒體服務(wù)器推流了。
此時(shí)就可以使用拉流客戶端拉取直播畫面了,同時(shí)hls_path 下將生成m3u8文件,文件名稱為 room-1.m3u8。
使用VLC拉RTMP
VLC是非常成熟的軟件了,安裝參考官網(wǎng)。
VLC拉流使用rtmp進(jìn)行,拉流地址為:
rtmp://192.168.1.115:1935/live/room-1
使用flv.js拉流
基于flv.js編寫一個(gè)視頻播放器,新建一個(gè)html文件,示例代碼如下:
flvjs_player.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FLV.js Example</title>
<script src="https://cdn.jsdelivr.net/npm/flv.js@1.5.0/dist/flv.min.js"></script>
</head>
<body>
<h1>FLV.js Player</h1>
<video id="videoElement" width="640" height="360" controls></video>
<button id="playButton">Click to Play Video</button>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://192.168.1.115:82/flv?port=1935&app=live&stream=room-1'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
document.getElementById('playButton').addEventListener('click', function() {
flvPlayer.play().catch(function(error) {
console.error('Error playing video:', error);
});
});
} else {
console.error('FLV.js is not supported in this browser.');
}
</script>
</body>
</html>
使用jls.js拉m3u8
基于hls.js編寫一個(gè)視頻播放器,新建一個(gè)html文件,示例代碼如下:
m3u8_play.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HLS.js Example</title>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<h1>HLS.js Player</h1>
<video id="videoElement" width="640" height="360" controls></video>
<script>
var video = document.getElementById('videoElement');
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource('http://192.168.1.115:82/hls/room-1.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
video.play();
});
hls.on(Hls.Events.ERROR, function(event, data) {
if (data.fatal) {
switch (data.fatal) {
case Hls.ErrorTypes.NETWORK_ERROR:
console.error("網(wǎng)絡(luò)錯(cuò)誤");
break;
case Hls.ErrorTypes.MEDIA_ERROR:
console.error("媒體錯(cuò)誤");
break;
case Hls.ErrorTypes.OTHER_ERROR:
console.error("其他錯(cuò)誤");
break;
default:
console.error("無法播放視頻");
break;
}
}
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'http://192.168.1.92:82/hls/room-1.m3u8';
video.play();
} else {
console.error('HLS.js 不支持此瀏覽器');
}
</script>
</body>
</html>
總結(jié)
本文介紹了流媒體服務(wù)器的特性及各種流媒體傳輸協(xié)議的適用場景,并詳細(xì)闡述了使用 nginx-http-flv-module 擴(kuò)展Nginx作為流媒體服務(wù)器的詳細(xì)步驟,并提供了在VLC,flv.js,hls.js下的流媒體拉流播放示例。
轉(zhuǎn)自https://www.cnblogs.com/Naylor/p/18583472
該文章在 2024/12/4 9:27:52 編輯過