<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 音視頻學習 (十) 基于 Nginx 搭建(rtmp、http)直播服務器 ## 前言 最近這幾年做直播和短視頻領域是真的很火,而且直播的領域也很廣泛,可以預見,未來的音視頻技術將會作為一種基礎技術應用到更廣泛的場景中。它可以與 AR/VR 結合,讓你在遠端體驗虛擬與現實,如虛擬服裝體驗;也可以與人工智能結合用于提高服務質量,如用于教學上幫助老師提高教學質量;它還可以與物聯網結合,用在自動駕駛、家庭辦公等領域。那么這么火范圍這么廣的領域我們可不可以參與一下呢,肯定是可以的,下面我們借助[Nginx](http://nginx.org/en/download.html)和[nginx-http-flv-module](https://github.com/winshining/nginx-http-flv-module)搭建一個簡易的直播服務器,當然如果對并發要求不是太高的,這個完全可以滿足了。 由于筆者沒有后臺服務開發的經驗并且對一些服務環境配置也不太懂,所以也是參考了一些博客最后總結了一套安裝使用教程,下面附上詳細的步驟。 **注意:**以下文字中如有出現`http://ip:port`,請替換成您自己的 IP 或域名。 ## 直播協議介紹 國內常見公開的直播協議有幾個:RTMP、HLS、HDL(HTTP-FLV)、RTP,我們來逐一介紹。 ### RTMP 它是 Adobe 的專利協議,現在大部分國外的 CDN 已不支持。在國內流行度很高。原因有幾個方面: 1、開源軟件和開源庫的支持穩定完整。如斗魚主播常用的 OBS 軟件,開源的 librtmp 庫,服務端有 nginx-rtmp 插件。 2、播放端安裝率高。只要瀏覽器支持 FlashPlayer 就能非常簡易的播放 RTMP 的直播,協議詳解可以 Google 了解。相對其他協議而言,RTMP 協議初次建立連接的時候握手過程過于復雜(底層基于 TCP,這里說的是 RTMP 協議本身的交互),視不同的網絡狀況會帶來給首開帶來 100ms 以上的延遲。基于 RTMP 的直播一般內容延遲在2~5 秒。 ### HTTP-FLV 即使用 HTTP 協議流式的傳輸媒體內容。相對于 RTMP,HTTP 更簡單和廣為人知,而且不擔心被 Adobe 的專利綁架。內容延遲同樣可以做到 2~5 秒,打開速度更快,因為 HTTP 本身沒有復雜的狀態交互。所以從延遲角度來看,HTTP-FLV 要優于 RTMP。 ### HLS 即 Http Live Streaming ,是由蘋果提出基于 HTTP 的流媒體傳輸協議。HLS 有一個非常大的優點:**HTML5 可以直接打開播放;這個意味著可以把一個直播鏈接通過微信等轉發分享**,不需要安裝任何獨立的 APP,有瀏覽器即可,所以流行度很高。**社交直播 APP,HLS 可以說是剛需**,下來我們分析下其原理 。 基于 HLS 的直播流 URL 是一個 m3u8 的文件,里面包含了最近若干個小視頻 TS(一種視頻封裝格式,這里就不擴展介紹)文件。如`http://ip:port/live.m3u8`是一個直播留鏈接,其內容如下: ![](data:image/svg+xml;utf8,) 假設列表里面的包含 5 個 TS 文件,每個 TS 文件包含 5 秒的視頻內容,那么整體的延遲就是 25 秒。當然可以縮短列表的長度和單個 TS 文件的大小來降低延遲,極致來說可以縮減列表長度為 1,1 秒內容的 m3u8 文件,但是極易受網絡波動影響造成卡頓。通過公網的驗證,目前按同城網絡可以做到比較好的效果是 5~7 秒的延遲,也是綜合流暢度和內容延遲的結果。 ### RTP 即 Real-time Transport Protocol ,用于 Internet 上針對多媒體數據流的一種傳輸層協議。 實際應用場景下經常需要 RTCP(RTP Control Protocol)配合來使用,可以簡單理解為 RTCP 傳輸交互控制的信令,RTP 傳輸實際的媒體數據。 **RTP 在視頻監控、視頻會議、IP 電話上有廣泛的應用**,因為視頻會議、IP 電話的一個重要的使用體驗:內容實時性強。 對比與上述 3 種或實際是 2 種協議,RTP 和它們有一個重要的區別就是默認是使用 UDP 協議來傳輸數據,而 RTMP 和 HTTP 是基于 TCP 協議傳輸。為什么 UDP 能做到如此實時的效果呢?關于 TCP 和 UDP 差別的分析文章一搜一大把,這里不在贅述,簡單概括: **UDP:單個數據報,不用建立連接,簡單,不可靠,會丟包,會亂序;** **TCP:流式,需要建立連接,復雜,可靠 ,有序。** 實時音視頻流的場景不需要可靠保障,因此也不需要有重傳的機制,實時的看到圖像聲音,網絡抖動時丟了一些內容,畫面模糊和花屏,完全不重要。TCP 為了重傳會造成延遲與不同步,如某一截內容因為重傳,導致 1 秒以后才到,那么整個對話就延遲了 1 秒,隨著網絡抖動,延遲還會增加成 2 秒、3 秒,如果客戶端播放是不加以處理將嚴重影響直播的體驗。 總結一下:在直播協議的選擇中,如果選擇是 RTMP 或 HTTP-FLV 則意味著有 2~5 秒的內容延遲,但是就打開延遲開,HTTP-FLV 要優于 RTMP。HLS 則有 5~7 秒的內容延遲。選擇 RTP 進行直播則可以做到1秒內的直播延遲。但就目前所了解,各大 CDN 廠商沒有支持基于 RTP 直播的,所以目前國內主流還是 RTMP 或 HTTP-FLV 。 ## 流媒體服務器開源軟件 * [流媒體服務器](https://www.oschina.net/project/tag/111/streaming?lang=0&os=0&sort=view&p=1) ![](data:image/svg+xml;utf8,) ## 環境準備 本來我打算是在我的[個人博客](https://www.devyk.top/)服務器上搭建的,最終還是放棄了,因為之前的帶寬跟容量也不是很大,也正巧碰見了[騰訊云](https://cloud.tencent.com/act/season?fromSource=gwzcw.3381750.3381750.3381750&utm_medium=cpc&utm_id=gwzcw.3381750.3381750.3381750&gclid=Cj0KCQiA-bjyBRCcARIsAFboWg3FYHr_bD5iwOA1slhDSlU3C-2Rt-WLzFMPWEmbKKupuRKaAIWrdnAaAvhCEALw_wcB)這幾天在搞活動就又購買了一臺服務器,以后關于后臺服務的項目也基本上在這臺部署了。 以下是我搭建以及測試的環境 **搭建服務器環境** > 云服務器: 騰訊云 > > 系統: centos > > 直播服務器: nginx > > 拓展模塊:[nginx-http-flv-module](https://github.com/winshining/nginx-http-flv-module)(支持 rtmp、http-flv、http-hls 等) > > 如果 NGINX 要支持正則表達式,需要安裝[PCRE庫](http://www.pcre.org/)。 > > 如果 NGINX 要支持加密訪問,需要安裝[OpenSSL庫](https://www.openssl.org/)。 > > 如果 NGINX 要支持壓縮,需要安裝[zlib庫](http://www.zlib.net/)。 **測試環境:** > 電腦 : MAC > > 推流軟件:[obs-studio](https://github.com/obsproject/obs-studio) > > MAC 拉流軟件: VLC > > Android 拉流軟件: 前幾天寫的一個 Android 播放器[ykplayer](https://github.com/yangkun19921001/NDK_AV_SAMPLE/tree/master/myplayer)正好供于拉流測試 > > HTML5 FLV 播放器: bilibili 開源的[flv.js](https://github.com/bilibili/flv.js) 本來之前我是借助[nginx-rtmp-module](https://github.com/arut/nginx-rtmp-module)來搭建的直播服務器(已成功),奈何它好像不支持 Http-flv 協議,所以替換成了[nginx-http-flv-module](https://github.com/winshining/nginx-http-flv-module)模塊,它是基于[nginx-rtmp-module](https://github.com/arut/nginx-rtmp-module)模塊二次開發的,所以完美的繼承了 rtmp 模塊的所有功能。 ## 服務器搭建 ### 1\. download nginx ~~~ # 通過 wget 命令下載 wget http://nginx.org/download/nginx-1.17.8.tar.gz # 解壓 tar -zxvf nginx-1.17.8.tar.gz 復制代碼 ~~~ ### 2\. download nginx-http-flv-module **提醒:**關于它的詳細信息可以參考它的[介紹](https://github.com/winshining/nginx-http-flv-module/blob/master/README.CN.md) ~~~ # 通過 wget 命令下載 wget https://github.com/winshining/nginx-http-flv-module/archive/v1.2.7.tar.gz # 解壓 tar -zxvf v1.2.7.tar.gz # 重命名 mv v1.2.7 nginx-http-flv-module 復制代碼 ~~~ ### 3\. install nginx 需要的環境 如果在執行 configure 之后報**OpenSSL 、PCRE 、Zlib**error 那么就必須安裝它們 ~~~ #安裝 openssl yum install openssl #安裝 pcre yum install pcre-devel #安裝 zlib yum install zlib-devel 復制代碼 ~~~ 等它們安裝好了之后編譯 nginx ### 4\. build nginx 在當前解壓 nginx 目錄中創建編譯 nginx 和 http-flv 腳本 ![](data:image/svg+xml;utf8,) ~~~ #!/bin/sh # ../ 代表當前目錄的上一級 HTTP_FLV_MODULE_PATH=../nginx-http-flv-module-1.2.7 OpenSSL_PATH=../openssl-1.1.1d #--prefix=./bin 代表編譯完成之后輸出的路徑地址 #--add-module 將拓展模塊添加到當前一起編譯 ./configure --prefix=./bin \ --add-module=$HTTP_FLV_MODULE_PATH \ --with-openssl=$OpenSSL_PATH \ --with-debug # 通過 make install 構建 make make install 復制代碼 ~~~ 如果中途沒有報任何錯誤,并且輸出了我們指定的**bin**目錄,那么就代表成功了。如下圖所示: ![](data:image/svg+xml;utf8,) ### 5\. 配置 nginx.conf 在當前目錄下輸入`vim bin/conf/nginx.conf`進行配置 rtmp、http 直播協議,我直接貼上我的配置 ~~~ user root; worker_processes auto; #運行在Windows上時,設置為1,因為Windows不支持Unix domain socket #worker_processes auto; #1.3.8和1.2.5以及之后的版本 #worker_cpu_affinity 0001 0010 0100 1000; #只能用于FreeBSD和Linux worker_cpu_affinity auto; #1.9.10以及之后的版本 error_log logs/error.log error; #如果此模塊被編譯為動態模塊并且要使用與RTMP相關的功 #能時,必須指定下面的配置項并且它必須位于events配置 #項之前,否則NGINX啟動時不會加載此模塊或者加載失敗 #load_module modules/ngx_http_flv_live_module.so; events { worker_connections 4096; } http { include mime.types; default_type application/octet-stream; keepalive_timeout 65; server { listen 80;//自定義填寫 http 的端口 location / { root /root/nginx/nginx-http-flv-module-1.2.7/test/www; index index.html index.htm;//默認首頁 } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location /flvjsplay {//測試地址 root /root/nginx/flv.js-1.5.0; index index.html;//flv.js 測試播放首頁 } location /flv { flv_live on; #打開HTTP播放FLV直播流功能 chunked_transfer_encoding on; #支持'Transfer-Encoding: chunked'方式回復 #跨域 add_header 'Access-Control-Allow-Origin' '*'; #添加額外的HTTP頭 add_header 'Access-Control-Allow-Credentials' 'true'; #添加額外的HTTP頭 } location /hls { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root /root/nginx/nginx-http-flv-module-1.2.7; add_header 'Cache-Control' 'no-cache'; } location /dash { root /root/nginx/nginx-http-flv-module-1.2.7; add_header 'Cache-Control' 'no-cache'; } location /stat { #push和pull狀態的配置 rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root /root/nginx/nginx-http-flv-module-1.2.7; #指定stat.xsl的位置 } #如果需要JSON風格的stat, 不用指定stat.xsl #但是需要指定一個新的配置項rtmp_stat_format #location /stat { # rtmp_stat all; # rtmp_stat_format json; #} location /control { rtmp_control all; #rtmp控制模塊的配置 } } } rtmp_auto_push on; rtmp_auto_push_reconnect 1s; rtmp_socket_dir /root/nginx/nginx-http-flv-module-1.2.7; rtmp { out_queue 4096; out_cork 8; max_streams 128; timeout 30s; drop_idle_publisher 30s; log_interval 5s; #log模塊在access.log中記錄日志的間隔時間,對調試非常有用 log_size 1m; #log模塊用來記錄日志的緩沖區大小 server { listen 1935;//自定義 rtmp 端口 # server_name www.test.*; #用于虛擬主機名后綴通配 application devyk { live on; gop_cache on; #打開GOP緩存,減少首屏等待時間 } application hls { live on; hls on; hls_path /root/nginx/nginx-http-flv-module-1.2.7/hls; } application dash { live on; dash on; dash_path /root/nginx/nginx-http-flv-module-1.2.7/dash; } } #可以有多個 server 配置 } 復制代碼 ~~~ > [Nginx 配置文件詳解請看該篇文章](https://zhuanlan.zhihu.com/p/31202053) > > [nginx-rtmp-module配置指令詳解](https://yq.aliyun.com/articles/243454) 在根目錄輸入 bin/sbin/nginx -t , 如出現如下就說明配置成功。 ![](data:image/svg+xml;utf8,) ### 6\. 開啟 nginx 服務 ~~~ #開啟服務 bin/sbin/nginx #停止服務 bin/sbin/nginx -s stop #重啟服務 bin/sbin/nginx -s reload 復制代碼 ~~~ ### 7\. 網頁測試是否都顯示正常 1. 直接在網頁上輸入:`http://ip:port`,如果出現如下,證明首頁和基本配置沒有問題了 ![](data:image/svg+xml;utf8,) 2. 直接在網頁輸入:`http://ip:port/stat`如出現如下監控頁面,說明監控頁面一切正常。 ![](data:image/svg+xml;utf8,) 現在服務器搭建完成,下面可以進入測試環節了。 ## rtmp 推流 我們直接用開源[obs-studio](https://github.com/obsproject/obs-studio)軟件進行推流,聽說很多游戲主播也用該款推流軟件。 ![](data:image/svg+xml;utf8,) 推流源設置: ![](data:image/svg+xml;utf8,) 如上圖所示,證明已經推流成功了,下面我們就來測試拉流。 ## 拉流 ### flv 在 Html5 上播放 **注意:**其它播放也是如下格式,這里只是以 Html 舉例說明: 例子: 假設在`http`配置塊中的`listen`配置項是: ~~~ http { ... server { listen 8080; #不是默認的80端口 ... location /live { flv_live on; } } } 復制代碼 ~~~ 在`rtmp`配置塊中的`listen`配置項是: ~~~ rtmp { ... server { listen 1935; #也可以不是默認的1935端口 ... application myapp { live on; } } } 復制代碼 ~~~ 并且發布的流的名稱是`mystream`,那么基于 HTTP-FLV 的播放url是: ~~~ http://ip:8080/flv?port=1935&app=myapp&stream=mystream 復制代碼 ~~~ 播放器這里選擇 bilibili 開源的[flv.js](https://github.com/bilibili/flv.js), 既然我們已經有服務器了,那就直接把 flv.js 項目部署在服務器上吧 1. 安裝 npm ~~~ #安裝 npm yum install npm #檢查是否安裝成功,如有輸出證明安裝成功 npm --version 復制代碼 ~~~ 2. 直接下載 flv.js 到服務器上 ~~~ #通過 wget 下載 wget https://github.com/bilibili/flv.js/archive/v1.5.0.tar.gz #解壓 tar -zxvf v1.5.0.tar.gz 復制代碼 ~~~ 3. 安裝 進入 flv.js 根目錄直接輸入`npm install`命令,安裝完成之后會出現一個`node_modules`模塊 ![](data:image/svg+xml;utf8,) 4. 安裝生成工具 還是在當前根目錄下安裝,輸入如下命令: ~~~ npm install -g gulp 復制代碼 ~~~ 5. 包裝和最小化 js 放入 dist 文件夾中 ~~~ #輸入如下命令 gulp release 復制代碼 ~~~ 這一步執行完成之后會生成如下文件: ![](data:image/svg+xml;utf8,) 6. 修改 demo 提供的播放頁面 將 demo 中 2 個文件(.ccs,.js) copy 到 dist 文件下,并修改 html 中 flv.js 路徑,如下所示: ![](data:image/svg+xml;utf8,) 最后將 dist 文件夾重命名 flvjsplay 7. 部署 nginx.conf 配置網頁加載路徑: ~~~ location /flvjsplay {//測試地址 root /root/nginx/flv.js-1.5.0; index index.html;#flv.js 測試播放首頁 } 復制代碼 ~~~ 修改了配置文件需要在 nginx 根目錄輸入如下指令,對 nginx 服務器重啟: ~~~ #重新啟動 bin/sbin/nginx -s reload 復制代碼 ~~~ 8. chrome 加載播放 ![](data:image/svg+xml;utf8,) > 左邊是拉流,右邊是推流 可以看到首屏加載速度還是比較快延遲在 2-5s 之間,畫面延遲有點高跟我服務器和網絡有關。 ### VLC rtmp 拉流播放 VLC 點擊文件->打開網絡輸入 rtmp 拉流地址點擊播放 ~~~ //配置rtmp 拉流格式 //ip:host //rtmpPost:rtmp 服務的端口 //appname 配置在rtmp application 的名稱 //streamname:推流的時候填寫的密碼 rtmp://ip:rtmpPort/appname/streamname 復制代碼 ~~~ ![](data:image/svg+xml;utf8,) > 左邊是拉流,右邊是推流 ### http-hls 播放 **播放格式:** ~~~ http://ip:port/hls/streamname.m3u8 復制代碼 ~~~ 因為筆者不是做 H5 開發的,所以對瀏覽器播放 HLS 直播流兼容性不是太清楚,我就直接使用 video 標簽在我電腦上用 chrome 瀏覽器測試, 結果是播放不出來的,查了資料好像說是原生 video 標簽僅支持**MP4、WebM、Ogg**格式,那這怎么辦呢?其實可以直接使用開源項目來解決的,比如[video.js](https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fvideojs%2Fvideo.js)、[videojs-contrib-hls](https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fvideojs%2Fvideojs-contrib-hls)等,我這里直接使用的是[videojs-contrib-hls](https://link.jianshu.com/?t=https%3A%2F%2Fgithub.com%2Fvideojs%2Fvideojs-contrib-hls),目前測試在**Android 瀏覽器、PC 谷歌瀏覽器 、IOS 微信、IOS Safari 瀏覽器**均已成功,下面是 Html 代碼,如下所示: ~~~ <html> <head> <meta charset="utf-8" /> <title>Player</title> <link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet"> </head> <body> <video id="video" class="video-js vjs-default-skin" controls autoplay="autoplay" width="640" height="320" data-setup='{}'> //換成你自己的直播鏈接 <source src="http://ip:8082/hls/live1.m3u8" type="application/x-mpegURL" /> </video> <script src="https://unpkg.com/video.js/dist/video.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.12.1/videojs-contrib-hls.min.js"></script> </body> </html> 復制代碼 ~~~ **注意:在這兒使用的 js 等資源皆是在線的一些支持。若需要在項目中使用,最好下載到本地使用** 為了測試方便,我也直接把該 Html 代碼部署到了云服務器中,nginx.conf 配置如下: ~~~ location /hlsplay { root /root/nginx/nginx-http-flv-module-1.2.7/hls; index hlsplay.html; //指定首頁,也就是我們播放的頁面,hlsplay.html 就是上面代碼。 } 復制代碼 ~~~ 重啟 nginx 服務器之后,直接輸入`http://ip:port/hlsplay`就可以播放了,測試效果如下圖: ![](data:image/svg+xml;utf8,) ### VLC rtmp 、flv.js Http-Flv 、android rtmp 三端同時拉流測試 ![](https://user-gold-cdn.xitu.io/2020/2/21/17063b713f8bd12b?imageslim) ## 總結 到這里您已經成功搭建直播服務器了,雖然說該篇文章沒有敲任何的代碼,也許你會說沒有學到什么,但是搭建服務器和部署一套簡易直播環境這個過程也都是值得我們作為一個移動或者前端開發者學習的。 ## 參考 * [直播協議介紹](https://zhuanlan.zhihu.com/p/23377305) * [nginx + nginx-http-flv-module 搭建文檔](https://github.com/winshining/nginx-http-flv-module/blob/master/README.CN.md) ## 感謝 * Igor Sysoev,[NGINX](http://nginx.org/)的作者。 * Roman Arutyunyan,[nginx-rtmp-module](https://github.com/arut/nginx-rtmp-module)的作者。 * [winshining](https://github.com/winshining),[nginx-http-flv-module](https://github.com/winshining/nginx-http-flv-module)的作者。 * [obsproject](https://github.com/obsproject),[obs-studio](https://github.com/obsproject/obs-studio)(用于實時流式傳輸和屏幕錄制)。 * [bilibili](https://github.com/bilibili),HTML5[flv.js](https://github.com/Bilibili/flv.js/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看