什么是流媒體服務器
流媒體服務器(Streaming Media Server)是一種用于存儲和傳輸音頻、視頻、直播等媒體內容的服務器軟件。它通過網絡將媒體文件實時傳輸給用戶,而不需要用戶先下載完整文件。流媒體服務器支持按需播放、實時廣播等功能,常見的使用場景包括在線視頻、音頻點播、直播視頻等。
視頻流媒體數據傳輸往往對流媒體服務器編解碼能力和協議轉換有要求,因為不同的編碼格式和不同的協議適用的場景不同。例如,RTMP協議延遲低,但是web瀏覽器不支持,需要將其轉為HLS或者是FLV才能進行播放。
Nginx如何實現流媒體服務器
Nginx作為web服務器的一種,本身關注點在靜態資源代理、正反向代理方面,實現作為流媒體服務器使用是依賴“插件”來擴展。例如:nginx-rtmp-module插件和nginx-http-flv-module插件。
為Nginx安裝nginx-http-flv-module
概述
nginx中的模塊雖然就是類似插件的概念,但是它無法像VsCode那樣輕松的安裝擴展。針對像 nginx-http-flv-module 這樣的 nginx 模塊,僅能通過重新編譯 nginx 源碼的方式完成“插件的安裝”。
nginx-http-flv-module 基于 nginx-rtmp-module 二次開發,擁有 nginx-rtmp-module 全部的功能,同時具備HTTP-FLV播放,這個功能就很Nice,有了這個就可以實現在瀏覽器中觀看直播,針對推送端無需額外的配置,一個直播流推送到流媒體服務器,直接可以輸出多種流,包括:rtmp、hls、flv,rtmp用于在桌面應用程序中播放,hls和flv用于在瀏覽器中播放,當然hls也可以在桌面應用程序中播放,在瀏覽器播放方式中flv的畫面延遲明顯由于hls。
需要注意的是 nginx-http-flv-module 要求nginx的版本大于等于1.2.6。由于nginx-http-flv-module包含了 nginx-rtmp-module 模塊,所以不可將 nginx-http-flv-module 和 nginx-rtmp-module 同時編譯,當我們編譯完 nginx-http-flv-module 之后,其實就已經擁有了 nginx-rtmp-module 的完整功能。
流程
- 查看當前nginx 的版本(假設安裝位置為:/usr/local/nginx)
- 下載當前版本nginx的源代碼
- 下載 nginx-http-flv-module 模塊源代碼
- 重新編譯nginx并追加nginx-http-flv-module
- 將新編譯好的 nginx 可執行文件拷貝到當前nginx安裝目錄(/usr/local/nginx/sbin)
操作步驟
使用如下命令查看當前已經安裝的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
進入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 配置編譯環境
- 將上面 保存的“arguments 后面的內容”作為configure 的第一個參數
- 第二個參數為 --add-module=/home/cml/nginx-http-flv-module ,即添加一個模塊,模塊源代碼位置是 /home/cml/nginx-http-flv-module
- 使用make命令執行編譯編譯
編譯成功后,在 objs中會有一個 名為nginx的可執行文件,這個就是編譯好的nginx了, 里面包含已經安裝的功能和新增加的nginx-rtmp-module,將這個可執行文件拷貝到當前安裝目錄(/usr/local/nginx/sbin)中就可以了。
注意拷貝之前需要停止nginx,否則會報當前文件繁忙,無法覆蓋的錯誤。
通過如下命令驗證安裝是否正常:
nginx -V
若打印的信息中包含nginx-http-flv-module,說明安裝好了。
配置流媒體服務器
當安裝好了 nginx-http-flv-module 之后,就可以創建流媒體應用了。所謂的創建流媒體應用其實就是編寫 nginx 的配置文件,如果需要創建一個名為 live 的流媒體應用,那么可以在 nginx.conf 中做如下配置
#以下內容放可在 nginx.conf 的最后,rtmp 配置塊為頂級配置塊
rtmp_auto_push on ;
rtmp {
server {
listen 1935; #監聽的端口
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內沒有push,就斷開連接
drop_idle_publisher 20s ;
}
}
}
- listen 1935:指定流媒體服務器的運行端口
- live :為流媒體應用的應用的名稱,也即流媒體應用的唯一標識
- live on : 添加直播的支持
- hls_path:指定生成的m3u8文件的位置
之后就是創建http-flv端點和hls端點了,目的是讓直播流可以在http協議上面傳輸直播畫面。
若不創建,將僅可以使用rtmp協議拉流,即rtmp://ip:1935/live/stream_no;若創建了就可以使用hls或者flvjs來拉流播放了。
創建http-flv端點和hls端點同樣是編輯nginx.conf來實現,如下示例配置:
server {
listen 82;
server_name rtmpserver;
# 創建hls端點
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';
}
# 創建 flv 端點
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端點和flv端點的監聽端口,此端口可以自定義,針對hls端點和flv端點可以分開設置不同的監聽端口
- hls端點的標識為 hls,此標識可以自定義,拉流的時候會用到
- alias:指定m3u8文件的訪問路徑,需要和 "創建流媒體應用"中的hls_path配置保持一致
- flv端點的標識為flv,此標識可以自定義,拉流的時候會用到
使用OBS推流
OBS 是非常成熟的軟件了,安裝參考官網:https://obsproject.com/
假設約定的推拉流地址為 rtmp://192.168.1.115:1935/live/room-1
設置直播流來源為 視頻采集設備 和 瀏覽器,其中視頻采集設備就是筆記本的攝像頭,瀏覽器為OBS內置瀏覽器并打開 https://time.is/zh/ 這個網址。最終的直播畫面就是兩個采集終端的畫面疊加在一起,底部是一個網址,網頁中有一個時鐘,頂部是攝像頭。
設置直播服務器和推流碼:
- 服務器:即流媒體應用的地址,即 rtmp://192.168.1.115:1935/live
- 推流碼:即當前推流唯一標識,可以隨意指定,保證推拉流地址一致即可,示例為: room-1
點擊開始直播,OBS就開始向流媒體服務器推流了。
此時就可以使用拉流客戶端拉取直播畫面了,同時hls_path 下將生成m3u8文件,文件名稱為 room-1.m3u8。
使用VLC拉RTMP
VLC是非常成熟的軟件了,安裝參考官網。
VLC拉流使用rtmp進行,拉流地址為:
rtmp://192.168.1.115:1935/live/room-1
使用flv.js拉流
基于flv.js編寫一個視頻播放器,新建一個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編寫一個視頻播放器,新建一個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("網絡錯誤");
break;
case Hls.ErrorTypes.MEDIA_ERROR:
console.error("媒體錯誤");
break;
case Hls.ErrorTypes.OTHER_ERROR:
console.error("其他錯誤");
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>
總結
本文介紹了流媒體服務器的特性及各種流媒體傳輸協議的適用場景,并詳細闡述了使用 nginx-http-flv-module 擴展Nginx作為流媒體服務器的詳細步驟,并提供了在VLC,flv.js,hls.js下的流媒體拉流播放示例。
轉自https://www.cnblogs.com/Naylor/p/18583472
該文章在 2024/12/4 9:27:52 編輯過