首先我們來初步認(rèn)識一些名詞,了解一些流媒體技術(shù)相關(guān)的基本概念,其次通過一個(gè)實(shí)例加深對基本概念的理解和記憶。
名詞
| 名詞 | 說明 |
|---|---|
| AVI | Audio Video Interleave,音頻視頻交錯(cuò) |
| MPEG | Moving Picture Experts Group,現(xiàn)泛指一系列視頻編碼標(biāo)準(zhǔn)正式審核程序 |
| RMVB | RealMedia Variable Bitrate,多媒體封裝格式的一種動態(tài)比特率擴(kuò)展 |
| MP4 | MPEG-4第14部分的一種標(biāo)準(zhǔn)數(shù)字多媒體容器格式 |
| MOV | 即QuickTime的影片格式用于存儲常用數(shù)字媒體類型 |
| FLV | FLASH VIDEO,用作流媒體格式 |
| WebM | Google提出的開放免費(fèi)的媒體文件格式 |
| WMV | Windows Media Video,微軟開發(fā)的一組數(shù)字影片的編解碼格式 |
| MKV | Matroska媒體系列中的一種文件格式 |
| H.264 | 一種較流行的視頻壓縮標(biāo)準(zhǔn) |
| MPEG-4 | 一套用于音頻、視頻信息的壓縮編碼的國際標(biāo)準(zhǔn) |
基本概念

| 概念 | 說明 | 補(bǔ)充說明 |
|---|---|---|
| 幀 | 可以簡單理解對于每一張圖片或畫面都可以理解成是一幀 | 暫無 |
| 幀率FPS | 每秒鐘播放的圖片數(shù)畫面數(shù),比如FPS 120那就是每秒切換播放了120張圖片 | 可以理解成每秒傳輸?shù)膸瑪?shù) |
| 像素 | 圖片由像素構(gòu)成,每個(gè)像素由RGB組成,每個(gè)8位,三原色構(gòu)圖共24位 | 像素便是一個(gè)圖像中的最小單位 |
| 視頻 | 個(gè)人觀點(diǎn)單位時(shí)間內(nèi)同一像素下由N幀組成的內(nèi)容呈現(xiàn) | 暫無 |
| 視頻編碼 | 根據(jù)各種算法將視頻壓縮的一個(gè)過程 (視頻為何要編碼?減小視頻占用的容量大小,視頻的編碼過程本身就是一個(gè)壓縮的過程。) | 將原始視頻格式轉(zhuǎn)換為另一種視頻文件格式的形式 |
| 流派 | 主流倆大類,ITU的VCEG,ISO的MPEG | ITU與MPEG聯(lián)合制定了H.264/MPEG-4 AVC |
| 接流 | 使用某一網(wǎng)絡(luò)協(xié)議將編碼完畢的視頻流從主播端傳到服務(wù)器端的過程 | 個(gè)人理解對服務(wù)端來說是接流,對主播端來說是推流操作 |
| 轉(zhuǎn)碼 | 服務(wù)器端接到視頻流后對視頻流進(jìn)行一定的處理,從一個(gè)編碼格式轉(zhuǎn)換為另一個(gè)編碼格式的過程 | 因?yàn)榭蛻舳舜嬖诓町愋缘脑?/td> |
| 拉流 | 流處理完畢之后,客戶端請求視頻資源的過程 | 暫無 |
| 分發(fā)網(wǎng)絡(luò) | 如果某一時(shí)間段內(nèi)請求該視屏資源的觀眾非常多,那么從單一服務(wù)器節(jié)點(diǎn)上拉流導(dǎo)致節(jié)點(diǎn)壓力大,所以加入分發(fā)網(wǎng)絡(luò)也就是CDN,將資源預(yù)先加載到CDN的邊緣節(jié)點(diǎn) | 可以顯著降低真實(shí)服務(wù)器的壓力,提升用戶質(zhì)量 |
| 解碼 | 當(dāng)客戶端將視頻拉下來后就需要解碼才能播放,將二進(jìn)制文件轉(zhuǎn)換為視頻的過程 | 暫無 |
| I幀 | Intra-coded picture 關(guān)鍵幀,里面是完整的圖片 | 最完整,只需要本幀即可完成解碼 |
| P幀 | Predictive-coded Picture 前向預(yù)測編碼幀,表示這一幀和之前一個(gè)I幀或P幀的差別 | 解碼的時(shí)侯需要用之前緩存的畫面疊加上和本幀定義的差別才可以生成最終的畫面 |
| B幀 | Bidirectionally predicted picture 雙向預(yù)測內(nèi)插編碼幀,記錄本幀與前后幀的區(qū)別 | 通過前后畫面的數(shù)據(jù)與本幀數(shù)據(jù)的疊加才能取得最終畫面 |
| DTS | Decoding Time Stamp 解碼時(shí)間戳 | 告訴播放器該在什么時(shí)候解碼這一幀的數(shù)據(jù) |
| PTS | Presentation Time Stamp 顯示時(shí)間戳 | 告訴播放器該在什么時(shí)候顯示這一幀的數(shù)據(jù) |
| NALU | 網(wǎng)絡(luò)提取層單元,二進(jìn)制流的結(jié)構(gòu)是由一個(gè)個(gè)的NALU組成的 | 這種格式就是為了傳輸,按照幀和片依次排列 |
| NALU Type | 在NALU頭里面,0x07表示SPS,序列參數(shù)集,包括一個(gè)圖像序列的所有信息,0x08表示PPS,圖像參數(shù)集,包括一個(gè)圖像的所有分片的所有相關(guān)信息 | 在傳輸視頻流之前必須傳輸這倆個(gè)參數(shù),否則無法解碼 |
| 推流 | 將二進(jìn)制數(shù)據(jù)流打包成網(wǎng)絡(luò)包傳輸?shù)綄Χ?/td> | 將NALU放到Message里面發(fā)送,這個(gè)也被稱為RTMP Packet包 |
| RTMP | RTMP通過協(xié)商版本號,時(shí)間戳來建立連接 | 一般RTMP的包會被拆分成Chunk進(jìn)行傳輸 |
這里又涉及到直播的三種常見協(xié)議,這里簡單總結(jié)對比下。
常見協(xié)議
| RTMP | HTTP-HLS | HTTP-FLV | |
|---|---|---|---|
| 協(xié)議 | TCP長連接 | HTTP短連接 | HTTP長連接 |
| 基本原理 | 每個(gè)時(shí)刻收到的數(shù)據(jù)立即轉(zhuǎn)發(fā) | 集合一段時(shí)間內(nèi)的數(shù)據(jù)生成ts切片,更新索引 | 同RTMP相似 |
| 延時(shí) | 1~3s | 5~20s | 1~3秒 |
| web支持 | 網(wǎng)頁中需要插件 | 支持網(wǎng)頁訪問 | 網(wǎng)頁中需要插件 |
| 其它 | 延遲小適合交互強(qiáng)的直播 | 延遲大適合交互較弱的直播 | 延遲小適合交互強(qiáng)的直播 |
簡單實(shí)例
1.確認(rèn)系統(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的大小設(shè)定
application hls {
live on;
hls on; //實(shí)時(shí)回訪
hls_path /data/wwwroot/hls; //媒體塊的存放位置,這個(gè)目錄是安裝完nginx自建的
hls_fragment 3s; //每個(gè)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.使用
操作很簡單,但是這里需要注意設(shè)置中推流的服務(wù)器和串流密鑰的設(shè)置
舉例:
服務(wù)器:rtmp://47.94.38.112:1935/hls
串流密鑰:ssxx
那么訪問的地址就是:http://DomainName(域名)/hls/ssxx.m3u8
總結(jié)
希望大家能和我一樣通過這個(gè)例子對視頻直播流媒體技術(shù)相關(guān)的基礎(chǔ)概念有一個(gè)基本的認(rèn)知
也希望我花時(shí)間整理的文章能幫到大家?!?/p>
補(bǔ)充說明
關(guān)于H.264
| 編碼名詞 | 說明 |
|---|---|
| 空間冗余 | 圖像的相鄰像素之間有較強(qiáng)的關(guān)聯(lián)性,一張圖片相鄰的像素基本是漸變的不是突變的,所以沒必要每個(gè)像素都完整的保留 |
| 時(shí)間冗余 | 視頻中相鄰圖片之間的內(nèi)容相似,連續(xù)出現(xiàn)的圖片也不是突變的,可以根據(jù)已有的圖片進(jìn)行預(yù)測和推斷 |
| 視覺冗余 | 人的視覺系統(tǒng)允許某些細(xì)節(jié)的丟失也就是允許丟失一些數(shù)據(jù) |
| 編碼冗余 | 不同像素值出現(xiàn)的概率不同,概率高的用的字節(jié)少,概率低的用的字節(jié)多 |
| 幀內(nèi)預(yù)測 | 去除空間冗余 |
| 幀間預(yù)測 | 去除時(shí)間冗余 |
| 變換 | 去除空間冗余 |
| 量化 | 去除視覺冗余,通過降低圖像質(zhì)量提高壓縮比 |
| 熵編碼 | 去除編碼冗余 |
| GOP | 關(guān)鍵幀間隔,從I幀開頭到下一個(gè)I幀結(jié)束,是一些按順序排序的圖像幀的組合。GOP值,表示倆個(gè)關(guān)鍵幀之間的間隔 |
| I幀 | 關(guān)鍵幀里面是完整的圖片,只需要本幀數(shù)據(jù)即可以完成編碼 ;幀內(nèi)編碼幀,無需參考其他圖像可以進(jìn)行獨(dú)立編碼,也就是說是不依賴前后幀的獨(dú)立的一幀圖像 |
| P幀 | 前向預(yù)測編碼幀,表示這一幀和前一關(guān)鍵幀的差別,解碼時(shí)需要用之前緩存的畫面疊加和本幀定義的差別生成最終畫面;需要參考I幀才能進(jìn)行編碼,采用運(yùn)動預(yù)測的方式進(jìn)行幀間編碼,基于幀間預(yù)測計(jì)算得到的幀 |
| B幀 | 雙向預(yù)測內(nèi)插編碼幀,記錄本幀與前后幀的差別,要解碼B幀需要前后畫面的數(shù)據(jù)與本幀數(shù)據(jù)的疊加取得最終畫面;采用運(yùn)動預(yù)測的方式進(jìn)行幀間雙向預(yù)測編碼 |
| NALU | Network Abstraction Layer Unit,網(wǎng)絡(luò)提取層單元,H264的基本結(jié)構(gòu),由起始標(biāo)志符和NALU頭和Palyload承載的數(shù)據(jù)構(gòu)成 |
| 原始碼流 | 由一個(gè)接一個(gè)的NALU組成,我的理解NALU序列 |
| 片 | 在一幀中分成多個(gè)片 |
| 宏塊 | 在一片中分成多個(gè)宏塊 |
| 子塊 | 在一個(gè)宏塊中分成多個(gè)子塊,這樣做的目的是為了方便進(jìn)行空間上的編碼 |
| NALU頭 | 0x07表示SPS序列參數(shù)集,包含一個(gè)圖像序列的所有信息;0x08表示PPS圖像參數(shù)集,包含一個(gè)圖像的所有分片的所有信息 |
| pts | 表示該幀播放的相對時(shí)間戳 |
| dts | 表示該幀解碼的相對時(shí)間戳 |
在字節(jié)大小方面,P幀,B幀遠(yuǎn)小于I幀,GOP太大會導(dǎo)致首屏播放時(shí)間變長,GOP太小會導(dǎo)致I幀的比例增大,壓縮比降低,同碼率下視頻播放的質(zhì)量降低。理論上pts是單調(diào)遞增的,推流源流時(shí)間戳異常會導(dǎo)致pts突變。也會導(dǎo)致錄制的時(shí)長有問題,導(dǎo)致轉(zhuǎn)碼水印異常,花屏等問題。
如何修復(fù)錄制文件:
1.剔除異常幀。
2.對記錄的每個(gè)視頻幀重新設(shè)置pts。
常用測試命令
1.查看一個(gè)視頻中關(guān)鍵幀的分布情況:
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