直播技術學習筆記(直播協議+流媒體伺服器+音視訊處理+FFmpeg)
直播協議
RTMP(Real Time Messaging Protocol)
簡介
Time Messaging Protocol,實時訊息傳送協議
RTMP是Adobe公司為Flash播放器和伺服器之間音訊、視訊和資料傳輸開發的開放協議。
協議:長連線TCP
原理:每個時刻的資料,收到後立即轉發
延遲:1~3秒
優點
- 實時性高:一般能做到3秒內。
- 支援加密:rtmpe和rtmps為加密協議。
- 穩定性高:在PC平臺上flash播放的最穩定方式是rtmp,如果做CDN或者大中型叢集分發,選擇穩定性高的協議一定是必要的。
- 一般主流編碼器都支援該協議。
缺點
- 協議複雜:開發者寫起來累,效率也不行。
- Cache麻煩:流協議做快取不方便。
RTSP(Real Time Streaming Protocol)
簡介
實時流協議(Real Time Streaming Protocol,RTSP)是一種網路應用協議,專為娛樂和通訊系統的使用,以控制流媒體 伺服器。該協議用於建立和控制終端之間的媒體會話。媒體伺服器的客戶端釋出VCR命令,例如播放,錄製和暫停,以便於實時控制從伺服器到客戶端(視訊點播)或從客戶端到伺服器(語音錄音)的媒體流。
Time Streaming Protocol,實時流傳輸協議)
優點
● 延遲低,一般都能夠做到500ms。
● 頻寬好,時效率高。
● 倍速播放,主要是回放的時候提供的功能。
● 控制精準,任意選擇播放點。
缺點
● 服務端實現複雜。
● 代理伺服器弱:數量少,優化少。
● 無路由器防火牆穿透
● 管流分離:需要1-3個通道。
HLS(HTTP Live Streaming)
簡介
HTTP Live Streaming(縮寫是HLS)是一個由蘋果公司提出的基於HTTP的流媒體網路傳輸協議。是蘋果公司QuickTime X
協議:短連結HTTP
原理:集合一段時間資料,生成ts切片檔案,更新m3u8
延遲:>10秒
優點
● 效能好:和http一樣。
● 穿牆:和http一樣。
● 原生支援很好:iOS上支援完美,Android上支援差些。PC/flash上現在也有各種as外掛支援HLS。
缺點
● 實時性差:與ts切片長度有關,大約3個切片長度時間的延遲,基本上HLS的延遲在10秒以上。
● 檔案碎片:若分發HLS,碼流低,切片較小時,會導致太多的檔案碎片
流媒體伺服器
主要介紹
- NGINX-rtmp
- Node-media-server
- livego
- SRS
NGINX-rtmp
簡介:基於NGINX的流媒體伺服器
支援協議:RTMP/HLS/MPEG-DASH
支援平臺:Linux/FreeBSD/MacOS/Windows
官網:https://github.com/arut/nginx-rtmp-module
如果是windows平臺,可直接下載編譯好的檔案
https://github.com/illuspas/nginx-rtmp-win32
Node-media-server
簡介:A Node.js implementation of RTMP/HTTP-FLV/WS-FLV/HLS/DASH/MP4 Media Server
支援協議:RTMP/HTTP-FLV/WS-FLV/HLS/DASH
支援平臺:Windows/Linux/Unix
官網:https://github.com/illuspas/Node-Media-Server/
一分鐘部署一個流媒體服務
livego
簡介:純 Go 寫的直播伺服器
支援協議:RTMP/AMF/HLS/HTTP-FLV
支援平臺:Windows/Linux/MacOS
官網:https://github.com/gwuhaolin/livego
SRS
簡介:SRS定位是運營級的網際網路直播伺服器叢集,追求更好的概念完整性和最簡單實現的程式碼。
支援協議:RTMP/RTSP/HSL/HTTP-FLV
支援平臺:Linux/MacOS
官網:https://github.com/ossrs/srs
這個功能比較強大,官網文件很詳細,具體去官網看吧
如果想在windows體驗,可下載網友修改的版本
https://github.com/illuspas/srs-win32
導致延遲因素
網路延時
網路延時這裡指的是從主播端採集,到觀眾端播放,之間的時間差。這裡不考慮主播段採集對視訊進行編碼的時間,以及觀眾端觀看對視訊進行解碼的時間,僅考慮網路傳輸中的延時。例如說下圖中的網路延時:
另外,資料傳輸過程中還涉及到邏輯上的互動,例如包的重傳以及確認,以及快取上的一些邏輯等,會在這個基礎上又增加很多。
那麼來簡單估算一下大概的網路延時。眾所周知,光在真空中的速度約為300,000km/s,而在其他介質中光速會大大降低,所以在普通光纖中,工程上一般認為傳輸速度是200,000km/s。從現實上來說,可以參考如下:
路線 |
距離(km) |
往返時延(ms) |
北京到上海 |
1,200 |
12 |
北京到紐約 |
11,000 |
110 |
赤道周長 |
40,000 |
400 |
所以說,在節點較少、網路情況較好的情況下,那麼網路延時對應也是最小,加上一定的快取,可以控制延時在1s~2s左右。但是節點多、網路差的情況下,網路延時會對應增大,經驗來說延時可以達到15s以上。
網路抖動
網路抖動,是指資料包的到達順序、間隔和發出時不一致。比如說,傳送100個數據包,每個包間隔1s發出。結果第27個包在傳輸過程中遇到網路擁塞,造成包27不是緊跟著26到達的,而是延遲到87後面才達。在直播中,這種抖動的效果實際上跟丟包是一樣的。因為你不能依照接收順序把內容播放出來,否則會造成失真。
網路抖動,會造成播放延時對應增大。如果網路中抖動較大,會造成播放卡頓等現象。
如上圖所示,主播端t3和t5發出的包,分別在t3'和t5'到達,但是中間延時增大,即發生了網路抖動。這樣造成觀眾端觀看視訊的延時會不斷增大。
網路丟包
CDN直播中用到的RTMP、HLS、HTTP FLV等協議都是在TCP的基礎之上。TCP一個很重要的特性是可靠性,即不會發生資料丟失的問題。為了保證可靠性,TCP在傳輸過程中有3次握手,見下圖。首先客戶端會向服務端傳送連線請求,服務端同意後,客戶端會確認這次連線。這就是3次握手。接著,客戶端就開始傳送資料,每次傳送一批資料,得到服務端的“收到”確認後,繼續傳送下一批。TCP為了保證傳到,會有自動重傳機制。如果傳輸中發生了丟包,沒有收到對端發出的“收到”訊號,那麼就會自動重傳丟失的包,一直到超時。
由於網際網路的網路狀況是變化的,以及主播端的網路狀況是無法控制的。所以當網路中丟包率開始升高時,重傳會導致延時會不斷增大,甚至導致不斷嘗試重連等情況,這樣不能有效的快取,嚴重情況下會導致觀眾端視訊無法觀看。
RTMP累積延遲
此延遲只發生在RTMP協議中
RTMP有個弱點就是累積誤差,原因是RTMP基於TCP,而TCP不會丟包,(可能丟包,但是利用TCP的重傳機制避免)。
所以當網路狀態差時,伺服器會將包快取起來,導致累積的延遲;
待網路狀況好了,就一起發給客戶端。
這個的對策就是,當客戶端的緩衝區很大,就斷開重連。
GOP-Cache
影象群組(Group of pictures,GOP)
原理比較複雜,這裡就不班門弄斧了,具體可以Google
圖
RTMP延遲
圖片來自:https://www.processon.com/view/56ebb341e4b01c9aeb5f137f
看完上圖你大概就能明白了,rtmp的延遲是和gop掛鉤的。
那麼,為什麼rtsp延遲會比rtmp低呢?因為,它是精確控制的,可以跳出這個以gop組為單位的控制。
視訊基本屬性
幀率(frame rate)
幀指的是碼流中的單張畫面,幀率指單位時間內碼流的幀數,單位fps(frame per second)。我們看到的視訊是由一幀幀的畫面,也就是一張張的圖片構成;如果一秒鐘跑過去的圖片有24張,幀率就是24幀/秒(fps);只有8張,幀率就是8幀/秒(fps);幀率越大,畫面就越流暢,當然大到一定程度,也不需要過大了,一方面肉眼也看不出有毛區別,另一方面電腦吃不消啊!
常見幀率
電影:23.976fps
電視(PAL):25fps
電視(NTSC):29.97fps
CRT顯示器:60Hz-85Hz
液晶顯示器:60Hz-75Hz
3D顯示器: 120Hz
解析度(resolution)
解析度指的是畫面的尺寸大小,解析度越高,影象越大。
一般的,在位元速率一定的情況下,解析度越高,視訊質量越差。
解析度有影象解析度與顯示解析度兩種,影象解析度指影象的尺寸大小,顯示解析度指螢幕解析度。
對於視訊而言,有一些固定尺寸的解析度標準,如D1(720×576)、4CIF(704×576)、VGA(640×480)、SVGA(800×600)、VXGA(1600×1200)等,後來對於固定比例(16:9)的畫面,解析度的的表示方法為縱向高度加掃描方式,如720P(1280×720,逐行掃描)、1080P(1920×1080,逐行掃描)、1080I(1920×1080,隔行掃描),再到後面,使用橫向畫素描述,如2K(2048×1536或2560×1440或2560×1600)、4K(4096×2160或3840×2160)、8K(7680×4320)。
位元速率(bit rate)
位元速率即位元率,指單位時間內產生的資料位,單位bps(bit per second),1Mbps=1024kbps=1048576bps。一般的,解析度一定的情況下,位元速率越高,視訊質量越好。
(*注意bps與B/s的區別,1B/s=8bps。)
通常,720P的碼流位元速率在2~4Mbps左右,1080P的碼流位元速率在4~8Mbps左右,對於使用者來說則是寬頻要求,要看720P的視訊需要至少2M的頻寬,要看1080P的視訊需要至少4M的頻寬,當前國內的網路環境下,上下行速率不對等,如果主播要使用高清視訊,還得確保主播上行頻寬足夠。
編碼方式
平常我們總在想,如何讓視訊檔案更小,讓視訊更清晰呢?答案就在位元速率上,對位元速率進行處理,就叫做編碼方式,一般有CBR/ABR/VBR三種方式.
CBR全稱constant bitrate,意思是固定位元速率,就是在整個視訊當中,位元速率固定不變;
VBR全稱Variable Bitrate,意為可變位元速率。其實在視訊當中,畫面內容越豐富,所需位元速率越高,成像質量也會越好,畫面內容不怎麼豐富的地方用高位元速率就是浪費,所以可變位元速率根據畫面內容的豐富程度自動調節,保證成像質量的同時,讓檔案變得更小。所以要讓視訊檔案更小,內容更清晰,採用VBR的編碼方式,並設定科學的數值,就是解決問題的關鍵。
ABR全稱average bitrate ,意為平均位元速率,是一種介於CBR和VBR之間的折中方式。
Codec 視訊編碼方式
其中,MPEG-1的編碼用於老VCD,MPEG-2的編碼用於DVD,之後的MPEG-4被用於更多更廣泛的平臺,這裡的MPEG-4就是傳說中的MP4;
另外呢,還有一個叫做國際電傳視訊聯盟(ITU)主導的另一套編碼方式,稱為H.26X系列,之後與MPEG合作弄出了H.264編碼方式,成為如今最熱門的編碼方式。
Container format視訊封裝格式
參考:https://en.wikipedia.org/wiki/Comparison_of_video_container_formats
主要封裝格式一覽
名稱 |
推出機構 |
流媒體 |
支援的視訊編碼 |
支援的音訊編碼 |
目前使用領域 |
AVI |
Microsoft Inc. |
不支援 |
幾乎所有格式 |
幾乎所有格式 |
BT下載影視 |
MP4 |
MPEG |
支援 |
MPEG-2, MPEG-4, H.264, H.263等 |
AAC, MPEG-1 Layers I, II, III, AC-3等 |
網際網路視訊網站 |
TS |
MPEG |
支援 |
MPEG-1, MPEG-2, MPEG-4, H.264 |
MPEG-1 Layers I, II, III, AAC, |
IPTV,數字電視 |
FLV |
Adobe Inc. |
支援 |
Sorenson, VP6, H.264 |
MP3, ADPCM, Linear PCM, AAC等 |
網際網路視訊網站 |
MKV |
CoreCodec Inc. |
支援 |
幾乎所有格式 |
幾乎所有格式 |
網際網路視訊網站 |
RMVB |
Real Networks Inc. |
支援 |
RealVideo 8, 9, 10 |
AAC, Cook Codec, RealAudio Lossless |
BT下載影視 |
如何降低延遲時間
參考:
FFEMPEG方面
wiki:StreamingGuide
https://trac.ffmpeg.org/wiki/StreamingGuide
Low-Latency Live Streaming your Desktop using ffmpeg
http://fomori.org/blog/?p=1213
ffmpeg的轉碼延時測試與設定優化
https://blog.csdn.net/fireroll/article/details/51902018
FFmpeg推流延遲10秒問題記錄
https://blog.csdn.net/vanjoge/article/details/79545490
ffplay播放視訊源延時的引數設定
https://blog.csdn.net/cai6811376/article/details/52637158
Web直播系列4——ffmpeg實時推流+nginx負載均衡降低直播延時_1
https://blog.csdn.net/zzhang_12/article/details/79798027
ffmpeg拉流rtmp音訊實時資料有延時的解決方法
https://blog.csdn.net/a1317338022/article/details/78226834
如何實現1080P延遲低於500ms的實時超清直播傳輸技術
FFMPEG引數說明
參考:
https://blog.csdn.net/leixiaohua1020/article/details/12751349
https://trac.ffmpeg.org/wiki/Encode/H.264
主要引數
- -i——設定輸入檔名。
- -f——設定輸出格式。
- -y——若輸出檔案已存在時則覆蓋檔案。
- -fs——超過指定的檔案大小時則結束轉換。
- -t——指定輸出檔案的持續時間,以秒為單位。
- -ss——從指定時間開始轉換,以秒為單位。
- -t從-ss時間開始轉換(如-ss 00:00:01.00 -t 00:00:10.00即從00:00:01.00開始到00:00:11.00)。
- -title——設定標題。
- -timestamp——設定時間戳。
- -vsync——增減Frame使影音同步。
- -c——指定輸出檔案的編碼。
- -metadata——更改輸出檔案的元資料。
- -help——檢視幫助資訊。
視訊引數
- -b:v——設定視訊流量,預設為200Kbit/秒。(單位請引用下方注意事項)
- -r——設定幀率值,預設為25。
- -s——設定畫面的寬與高。
- -aspect——設定畫面的比例。
- -vn——不處理視訊,於僅針對聲音做處理時使用。
- -vcodec( -c:v )——設定視訊視訊編解碼器,未設定時則使用與輸入檔案相同之編解碼器。
聲音引數
- -b:a——設定每Channel(最近的SVN版為所有Channel的總合)的流量。(單位請引用下方注意事項)
- -ar——設定取樣率。
- -ac——設定聲音的Channel數。
- -acodec ( -c:a ) ——設定聲音編解碼器,未設定時與視訊相同,使用與輸入檔案相同之編解碼器。
- -an——不處理聲音,於僅針對視訊做處理時使用。
- -vol——設定音量大小,256為標準音量。(要設定成兩倍音量時則輸入512,依此類推。)
注意事項
- 以-b:v及-b:a首選項流量時,根據使用的ffmpeg版本,須注意單位會有kbits/sec與bits/sec的不同。(可用ffmpeg -h顯示說明來確認單位。)
例如,單位為bits/sec的情況時,欲指定流量64kbps時需輸入 -b:a 64k;單位為kbits/sec的情況時則需輸入 -b:a 64。
- 以-acodec及-vcodec所指定的編解碼器名稱,會根據使用的ffmpeg版本而有所不同。例如使用AAC編解碼器時,會有輸入aac與libfaac的情況。此外,編解碼器有分為僅供解碼時使用與僅供編碼時使用,因此一定要利用ffmpeg -formats確認輸入的編解碼器是否能運作。
直播中常見引數
-preset
按編碼速度的內建引數,內建的編碼設定有:
- ultrafast
- superfast
- veryfast
- faster
- fast
- medium
- slow
- slower
- veryslow
- placebo
按快到慢排列,預設為medium級,當然越慢效果越好,但是體積會增大,一般最求高質量用veryslow就夠了。
-tune
按不同的源或者不用的應用場景的內建引數
- film:電影、真人型別
- animation:動畫
- grain:需要保留大量的grain時用
- stillimage:靜態影象編碼時使用
- psnr:為提高psnr做了優化的引數
- ssim:為提高ssim做了優化的引數
- fastdecode:可以快速解碼的引數
- zerolatency:零延遲,用在需要非常低的延遲的情況下,比如電視電話會議的編碼
在命令列中輸入:ffmpeg -h encoder=libx264
參考:
https://my.oschina.net/u/3733374/blog/1581609
https://www.zhihu.com/question/23651189
https://blog.csdn.net/leixiaohua1020/article/details/18893769