引言
有些小伙伴們經(jīng)常在群里面問我,為什么用ZLMediaKit拉流代理告丢、推流轉(zhuǎn)發(fā)的流播放延時(shí)好幾秒枪蘑,長(zhǎng)的時(shí)候10多秒?為什么HLS延時(shí)更高岖免,動(dòng)輒延時(shí)半分鐘岳颇?本文的目的在于澄清大家對(duì)延時(shí)的誤解。
什么是延時(shí)
很多小伙伴們并不能明白什么叫延時(shí)颅湘,認(rèn)為隨便一個(gè)播放器播放出來的畫面跟原始流畫面時(shí)間差就是延時(shí)话侧,其實(shí)這是對(duì)延時(shí)最大的誤解。
延時(shí)不是表象闯参,很多人在測(cè)試延時(shí)時(shí)很不專業(yè)瞻鹏,對(duì)延時(shí)測(cè)試的專業(yè)性認(rèn)識(shí)不足,在此我特別提醒鹿寨,不是隨隨便便的播放器都有資格做延時(shí)測(cè)試的!
總而延時(shí)新博,一般整個(gè)延時(shí)有以下幾部分累加組成:
- 采集延時(shí)
在采集攝像頭或顯卡畫面時(shí),由于fps的限制和cpu性能脚草、內(nèi)存拷貝速度等客觀限制赫悄,采集畫面成YUV/RGB等數(shù)據(jù)時(shí)會(huì)有一定的延時(shí),一般延時(shí)為毫秒級(jí)別馏慨。由于一般編碼器對(duì)輸入數(shù)據(jù)格式存在限制涩蜘,譬如要求統(tǒng)一輸入YUV420P,這樣在做RGB->YUV420P轉(zhuǎn)換時(shí)熏纯,也會(huì)有轉(zhuǎn)換計(jì)算延時(shí)(這個(gè)可以通過libyuv庫來降低)同诫。總而延時(shí)樟澜,采集延時(shí)大概為毫秒級(jí)別误窖,如果fps為30叮盘,那么一般采集延時(shí)會(huì)有30毫秒以上的延時(shí),在內(nèi)存拷貝和顏色轉(zhuǎn)換時(shí)霹俺,又可能增加若干毫秒的延時(shí)柔吼。
- 編碼延時(shí)
在把原始畫面輸入到編碼器時(shí),并不會(huì)立即輸出編碼后的數(shù)據(jù)丙唧,特別是在開啟B幀時(shí)愈魏,由于需要參考后面的P幀,那么延時(shí)會(huì)更大想际,所以延時(shí)敏感的情況下一般不開啟B幀培漏,這種情況下編碼延時(shí)應(yīng)該是毫秒級(jí)別,不是很大胡本。
- 網(wǎng)絡(luò)上行傳輸延時(shí)
編碼后的數(shù)據(jù)牌柄,要經(jīng)過一定的協(xié)議打包才能寫入socket,然后傳輸給推流服務(wù)器或拉流代理服務(wù)器侧甫,協(xié)議打包會(huì)有一定的內(nèi)存拷貝和計(jì)算量珊佣,那么會(huì)增加延時(shí),不過這個(gè)延時(shí)很小披粟,基本忽略不計(jì)咒锻。數(shù)據(jù)在上傳到服務(wù)器時(shí),這個(gè)延時(shí)可大可小守屉,取決于網(wǎng)絡(luò)質(zhì)量虫碉。
- 服務(wù)器轉(zhuǎn)協(xié)議延時(shí)
服務(wù)器在收到數(shù)據(jù)后,要讀socket緩存胸梆、協(xié)議解析敦捧、解復(fù)用、重新打包等操作碰镜,不過總體而言兢卵,這個(gè)延時(shí)比較小,基本沒什么影響绪颖。有時(shí)秽荤,服務(wù)器為了提高性能,會(huì)采取合并寫的機(jī)制柠横,也就是收到一定量的數(shù)據(jù)后才會(huì)一并轉(zhuǎn)發(fā)窃款,這個(gè)延時(shí)一般為幾百毫秒,ZLMediaKit默認(rèn)300毫秒左右牍氛,不過ZLMediaKit默認(rèn)關(guān)閉合并寫晨继,也就是這個(gè)延時(shí)也很小。
- 網(wǎng)絡(luò)下行延時(shí)
流媒體在把視頻數(shù)據(jù)轉(zhuǎn)發(fā)給播放器時(shí)搬俊,會(huì)存在網(wǎng)絡(luò)發(fā)送紊扬,這個(gè)延時(shí)大小取決于網(wǎng)絡(luò)質(zhì)量蜒茄,ZLMediaKit在關(guān)閉低延時(shí)模式時(shí),還會(huì)增加MSG_MORE和關(guān)閉TCP_NODELAY導(dǎo)致的延時(shí)餐屎,不過ZLMediaKit默認(rèn)開啟低延時(shí)模式檀葛。
- 播放器延時(shí)
播放器延時(shí)主要有網(wǎng)路接收延時(shí)、協(xié)議解析解復(fù)用延時(shí)腹缩、解碼延時(shí)屿聋、緩存延時(shí)、渲染延時(shí)組成藏鹊,這些延時(shí)中緩存延時(shí)最大润讥,因?yàn)橐话愕牟シ牌鳛榱吮WC在網(wǎng)絡(luò)抖動(dòng)情況下視頻播放的流暢性,會(huì)以增加延時(shí)為代價(jià)伙判,增加播放緩存象对,這樣在網(wǎng)絡(luò)變差時(shí)黑忱,不至于播放緩沖卡頓宴抚。而且為了音視頻同步,也必須確保一定的緩存量甫煞。這種延時(shí)一般都是秒級(jí)別菇曲,一般5秒左右。
- 播放器GOP緩存延時(shí)
流媒體服務(wù)器為了能讓播放器立即出畫面抚吠,往往會(huì)緩存最近的一個(gè)I幀常潮,這個(gè)I幀往后的所有音視頻數(shù)據(jù)被稱作為GOP緩存。如果不緩存GOP楷力,那么播放器要等下一個(gè)I幀才能解碼成功或不花屏喊式,顯然為了提高播放體驗(yàn),這個(gè)GOP緩存是不能去掉的萧朝。而一般GOP短則1~3秒岔留,長(zhǎng)則10幾秒,這個(gè)跟采集端編碼器設(shè)置有關(guān)检柬,服務(wù)器改變不了献联。但是由于一般的播放器收到緩存后,并不會(huì)丟棄過多的畫面來確保低延時(shí)何址。況且播放器還希望有一定的緩存來確保播放的流暢性里逆,所以這個(gè)GOP緩存將會(huì)增大播放器的延時(shí)。
- 綜合延時(shí)
以上所有的延時(shí)累加用爪,就是你觀看到的直觀延時(shí)原押,那么你看到的延時(shí)很高,能怪是服務(wù)器的問題嗎偎血?在理想的網(wǎng)絡(luò)狀況下班眯,你觀看到的直觀延時(shí)希停,其實(shí)約等于播放器的播放緩存延時(shí),這個(gè)鍋得由播放器來背署隘。
怎么測(cè)試延時(shí)
用vlc等通用播放器測(cè)試延時(shí)是很不專業(yè)的宠能,這些播放器延時(shí)最少是秒級(jí)別的,為了播放流暢度和音視頻同步磁餐,這些播放器是不可能給你真實(shí)的延時(shí)數(shù)據(jù)违崇。
在此,我強(qiáng)烈推薦大家自己寫個(gè)無緩存的播放器測(cè)試延時(shí)诊霹,但是這顯然超過了大部人的能力羞延,所以ZLMediaKit提供了一個(gè)簡(jiǎn)單的播放器測(cè)試延時(shí):
test_player
什么? 你告訴我你不會(huì)編譯ZLMediaKit脾还? 那好伴箩,退而求其次,我推薦你用ffplay測(cè)試:
ffplay -i rtmp://xxxxxxx -fflags nobuffer
如果你不知道ffplay怎么安裝鄙漏,你可以從這里下載編譯好的.