首先我們來初步認識一些名詞巍沙,了解一些流媒體技術相關的基本概念,其次通過一個實例加深對基本概念的理解和記憶痴荐。
名詞
名詞 | 說明 |
---|---|
AVI | Audio Video Interleave,音頻視頻交錯 |
MPEG | Moving Picture Experts Group,現(xiàn)泛指一系列視頻編碼標準正式審核程序 |
RMVB | RealMedia Variable Bitrate,多媒體封裝格式的一種動態(tài)比特率擴展 |
MP4 | MPEG-4第14部分的一種標準數(shù)字多媒體容器格式 |
MOV | 即QuickTime的影片格式用于存儲常用數(shù)字媒體類型 |
FLV | FLASH VIDEO,用作流媒體格式 |
WebM | Google提出的開放免費的媒體文件格式 |
WMV | Windows Media Video,微軟開發(fā)的一組數(shù)字影片的編解碼格式 |
MKV | Matroska媒體系列中的一種文件格式 |
H.264 | 一種較流行的視頻壓縮標準 |
MPEG-4 | 一套用于音頻驳棱、視頻信息的壓縮編碼的國際標準 |
基本概念
概念 | 說明 | 補充說明 |
---|---|---|
幀 | 可以簡單理解對于每一張圖片或畫面都可以理解成是一幀 | 暫無 |
幀率FPS | 每秒鐘播放的圖片數(shù)畫面數(shù),比如FPS 120那就是每秒切換播放了120張圖片 | 可以理解成每秒傳輸?shù)膸瑪?shù) |
像素 | 圖片由像素構成农曲,每個像素由RGB組成社搅,每個8位,三原色構圖共24位 | 像素便是一個圖像中的最小單位 |
視頻 | 個人觀點單位時間內(nèi)同一像素下由N幀組成的內(nèi)容呈現(xiàn) | 暫無 |
視頻編碼 | 根據(jù)各種算法將視頻壓縮的一個過程 (視頻為何要編碼乳规?減小視頻占用的容量大小形葬,視頻的編碼過程本身就是一個壓縮的過程。) | 將原始視頻格式轉換為另一種視頻文件格式的形式 |
流派 | 主流倆大類暮的,ITU的VCEG笙以,ISO的MPEG | ITU與MPEG聯(lián)合制定了H.264/MPEG-4 AVC |
接流 | 使用某一網(wǎng)絡協(xié)議將編碼完畢的視頻流從主播端傳到服務器端的過程 | 個人理解對服務端來說是接流,對主播端來說是推流操作 |
轉碼 | 服務器端接到視頻流后對視頻流進行一定的處理冻辩,從一個編碼格式轉換為另一個編碼格式的過程 | 因為客戶端存在差異性的原因 |
拉流 | 流處理完畢之后猖腕,客戶端請求視頻資源的過程 | 暫無 |
分發(fā)網(wǎng)絡 | 如果某一時間段內(nèi)請求該視屏資源的觀眾非常多,那么從單一服務器節(jié)點上拉流導致節(jié)點壓力大恨闪,所以加入分發(fā)網(wǎng)絡也就是CDN倘感,將資源預先加載到CDN的邊緣節(jié)點 | 可以顯著降低真實服務器的壓力,提升用戶質量 |
解碼 | 當客戶端將視頻拉下來后就需要解碼才能播放咙咽,將二進制文件轉換為視頻的過程 | 暫無 |
I幀 | Intra-coded picture 關鍵幀老玛,里面是完整的圖片 | 最完整,只需要本幀即可完成解碼 |
P幀 | Predictive-coded Picture 前向預測編碼幀钧敞,表示這一幀和之前一個I幀或P幀的差別 | 解碼的時侯需要用之前緩存的畫面疊加上和本幀定義的差別才可以生成最終的畫面 |
B幀 | Bidirectionally predicted picture 雙向預測內(nèi)插編碼幀蜡豹,記錄本幀與前后幀的區(qū)別 | 通過前后畫面的數(shù)據(jù)與本幀數(shù)據(jù)的疊加才能取得最終畫面 |
DTS | Decoding Time Stamp 解碼時間戳 | 告訴播放器該在什么時候解碼這一幀的數(shù)據(jù) |
PTS | Presentation Time Stamp 顯示時間戳 | 告訴播放器該在什么時候顯示這一幀的數(shù)據(jù) |
NALU | 網(wǎng)絡提取層單元,二進制流的結構是由一個個的NALU組成的 | 這種格式就是為了傳輸犁享,按照幀和片依次排列 |
NALU Type | 在NALU頭里面余素,0x07表示SPS,序列參數(shù)集炊昆,包括一個圖像序列的所有信息桨吊,0x08表示PPS,圖像參數(shù)集凤巨,包括一個圖像的所有分片的所有相關信息 | 在傳輸視頻流之前必須傳輸這倆個參數(shù)视乐,否則無法解碼 |
推流 | 將二進制數(shù)據(jù)流打包成網(wǎng)絡包傳輸?shù)綄Χ?/td> | 將NALU放到Message里面發(fā)送,這個也被稱為RTMP Packet包 |
RTMP | RTMP通過協(xié)商版本號敢茁,時間戳來建立連接 | 一般RTMP的包會被拆分成Chunk進行傳輸 |
這里又涉及到直播的三種常見協(xié)議佑淀,這里簡單總結對比下。
常見協(xié)議
RTMP | HTTP-HLS | HTTP-FLV | |
---|---|---|---|
協(xié)議 | TCP長連接 | HTTP短連接 | HTTP長連接 |
基本原理 | 每個時刻收到的數(shù)據(jù)立即轉發(fā) | 集合一段時間內(nèi)的數(shù)據(jù)生成ts切片彰檬,更新索引 | 同RTMP相似 |
延時 | 1~3s | 5~20s | 1~3秒 |
web支持 | 網(wǎng)頁中需要插件 | 支持網(wǎng)頁訪問 | 網(wǎng)頁中需要插件 |
其它 | 延遲小適合交互強的直播 | 延遲大適合交互較弱的直播 | 延遲小適合交互強的直播 |
簡單實例
1.確認系統(tǒng)版本
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
2.安裝配置Tengine
1.需要下載nginx的nginx-rtmp-module模塊用來支持RTMP協(xié)議
git地址:https://github.com/arut/nginx-rtmp-module
編譯安裝添加參數(shù):--add-module=/path/to/nginx-rtmp-module
Tengine編譯安裝過程此處省略~
2.修改nginx的配置文件
[root@iZ2ze0a8w2ct7mzctse5r5Z src]# cat /usr/local/tengine/conf/nginx.conf
在配置文件中http的server區(qū)域添加如下
location /hls { //配置推流地址
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /data/wwwroot/hls;
expires -1;
add_header Cache-Control no-cache;
}
location /stat { //推流狀態(tài)查看
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/local/extend_module/nginx-rtmp-module/;
}
在配置文件http區(qū)域之后添加rtmp區(qū)域
rtmp {
server {
listen 1935; //監(jiān)聽端口1935
chunk_size 4096; //chunk的大小設定
application hls {
live on;
hls on; //實時回訪
hls_path /data/wwwroot/hls; //媒體塊的存放位置伸刃,這個目錄是安裝完nginx自建的
hls_fragment 3s; //每個ts文件為3秒
}
}
}
3.檢測nginx的配置文件并重啟
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# nginx -t
nginx: the configuration file /usr/local/tengine/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/tengine/conf/nginx.conf test is successful
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# systemctl reload nginx.service
3.使用OBS Studio推流
1.mac下的軟件下載
wget https://cdn-fastly.obsproject.com/downloads/obs-mac-24.0.2-installer.pkg
2.使用
操作很簡單谎砾,但是這里需要注意設置中推流的服務器和串流密鑰的設置
舉例:
服務器:rtmp://47.94.38.112:1935/hls
串流密鑰:ssxx
那么訪問的地址就是:http://DomainName(域名)/hls/ssxx.m3u8
總結
希望大家能和我一樣通過這個例子對視頻直播流媒體技術相關的基礎概念有一個基本的認知
也希望我花時間整理的文章能幫到大家∨趼~~~
補充說明
關于H.264
編碼名詞 | 說明 |
---|---|
空間冗余 | 圖像的相鄰像素之間有較強的關聯(lián)性景图,一張圖片相鄰的像素基本是漸變的不是突變的,所以沒必要每個像素都完整的保留 |
時間冗余 | 視頻中相鄰圖片之間的內(nèi)容相似碉哑,連續(xù)出現(xiàn)的圖片也不是突變的挚币,可以根據(jù)已有的圖片進行預測和推斷 |
視覺冗余 | 人的視覺系統(tǒng)允許某些細節(jié)的丟失也就是允許丟失一些數(shù)據(jù) |
編碼冗余 | 不同像素值出現(xiàn)的概率不同,概率高的用的字節(jié)少扣典,概率低的用的字節(jié)多 |
幀內(nèi)預測 | 去除空間冗余 |
幀間預測 | 去除時間冗余 |
變換 | 去除空間冗余 |
量化 | 去除視覺冗余妆毕,通過降低圖像質量提高壓縮比 |
熵編碼 | 去除編碼冗余 |
GOP | 關鍵幀間隔,從I幀開頭到下一個I幀結束贮尖,是一些按順序排序的圖像幀的組合笛粘。GOP值,表示倆個關鍵幀之間的間隔 |
I幀 | 關鍵幀里面是完整的圖片远舅,只需要本幀數(shù)據(jù)即可以完成編碼 闰蛔;幀內(nèi)編碼幀,無需參考其他圖像可以進行獨立編碼图柏,也就是說是不依賴前后幀的獨立的一幀圖像 |
P幀 | 前向預測編碼幀序六,表示這一幀和前一關鍵幀的差別,解碼時需要用之前緩存的畫面疊加和本幀定義的差別生成最終畫面蚤吹;需要參考I幀才能進行編碼例诀,采用運動預測的方式進行幀間編碼,基于幀間預測計算得到的幀 |
B幀 | 雙向預測內(nèi)插編碼幀裁着,記錄本幀與前后幀的差別繁涂,要解碼B幀需要前后畫面的數(shù)據(jù)與本幀數(shù)據(jù)的疊加取得最終畫面;采用運動預測的方式進行幀間雙向預測編碼 |
NALU | Network Abstraction Layer Unit,網(wǎng)絡提取層單元二驰,H264的基本結構扔罪,由起始標志符和NALU頭和Palyload承載的數(shù)據(jù)構成 |
原始碼流 | 由一個接一個的NALU組成,我的理解NALU序列 |
片 | 在一幀中分成多個片 |
宏塊 | 在一片中分成多個宏塊 |
子塊 | 在一個宏塊中分成多個子塊桶雀,這樣做的目的是為了方便進行空間上的編碼 |
NALU頭 | 0x07表示SPS序列參數(shù)集矿酵,包含一個圖像序列的所有信息;0x08表示PPS圖像參數(shù)集矗积,包含一個圖像的所有分片的所有信息 |
pts | 表示該幀播放的相對時間戳 |
dts | 表示該幀解碼的相對時間戳 |
在字節(jié)大小方面全肮,P幀,B幀遠小于I幀棘捣,GOP太大會導致首屏播放時間變長辜腺,GOP太小會導致I幀的比例增大,壓縮比降低,同碼率下視頻播放的質量降低评疗。理論上pts是單調(diào)遞增的测砂,推流源流時間戳異常會導致pts突變。也會導致錄制的時長有問題壤巷,導致轉碼水印異常邑彪,花屏等問題瞧毙。
如何修復錄制文件:
1.剔除異常幀胧华。
2.對記錄的每個視頻幀重新設置pts。
常用測試命令
1.查看一個視頻中關鍵幀的分布情況:
ffprobe -v error -show_frames "rtmp://rtstest.kivensu.club/rtstest0211/rtstest0211?auth_key=1644576853-0-0-635196d1093d1d1f980e427c9bd7af76" | grep pict_type
2.查看pts宙彪,dts矩动。
ffprobe -show_frames https://cloud.video.taobao.com/play/u/null/p/1/e/6/t/1/d/ud/344704485848.mp4
pkt_pts=1945600
pkt_dts=1945600
3.視頻截取
use stream copying & input seeking
ffmpeg -ss 00:01:01 -i gemfield.mp4 -t 4 -c copy cut1.mp4
use stream copying & output seeking
ffmpeg -i gemfield.mp4 -ss 00:01:01 -t 4 -c:v copy cut2.mp4
use transcoding & input seeking
ffmpeg -ss 00:01:01 -i gemfield.mp4 -t 4 -c:v libx264 cut3.mp4
use transcoding & output seeking
ffmpeg -i gemfield.mp4 -ss 00:01:01 -t 4 -c:v libx264 cut4.mp4