音視頻同步是我們觀(guān)看視頻的一個(gè)基本體驗,尤其對于視頻畫(huà)面中能看到聲源動(dòng)作(如:嘴型)的場(chǎng)景,音視頻同步問(wèn)題非常影響體驗。
在短視頻與直播APP中,采集端作為音視頻的生產(chǎn)者,如果采集端產(chǎn)生的音視頻源本身就無(wú)法保證同步,那么后面不管經(jīng)過(guò)什么處理,都很難再讓用戶(hù)看到音視頻同步的畫(huà)面了,因此,在采集端保證音視頻同步上尤其重要。
那么如何保證app在各種正常/非正常狀況下盡量保證輸出同步的音視頻?本文就是講述我們是如何解決上述問(wèn)題的。
音視頻同步的原理
音視頻采集的數據分別來(lái)自于麥克風(fēng)與攝像頭,而攝像頭與麥克風(fēng)其實(shí)是兩個(gè)獨立的硬件,而音視頻同步的原理是相信攝像頭與麥克風(fēng)采集數據是實(shí)時(shí)的,并在采集到數據時(shí)給他們一個(gè)時(shí)間戳來(lái)標明數據所屬的時(shí)間,而編碼封裝模塊只要不改動(dòng)音視頻時(shí)間的相對關(guān)系就能保證音頻與視頻在時(shí)間上的對應。如此封裝好數據之后,播放端就能夠根據音視頻的時(shí)間戳來(lái)播放對應的音視頻,從實(shí)現音視頻同步的效果。
時(shí)間戳參考標準
取格林威治時(shí)間做為對比標準,即音視頻時(shí)間戳都為采集時(shí)間點(diǎn)相對于格林威治標準時(shí)間的時(shí)間差;
取系統開(kāi)機時(shí)間做為對比標準,即音視頻時(shí)間戳都是采集時(shí)間點(diǎn)相對于手機開(kāi)機時(shí)間的時(shí)間差。目前iOS上AVCaptureSession這套API就是參考這個(gè)時(shí)間標準給的時(shí)間戳。
其它時(shí)間戳標準
基于“開(kāi)源項目1”的音視頻同步探討
原生某開(kāi)源框架
如圖:

簡(jiǎn)介
音/視頻被采集到之后會(huì )先經(jīng)過(guò)音/視頻處理模塊,音/視頻在被處理之后才進(jìn)入計算時(shí)間戳的模塊。
在第一幀到達時(shí)記一個(gè)計時(shí)起點(diǎn),然后根據采集的幀間隔對接下來(lái)每一幀的時(shí)間戳進(jìn)行計算:frameTimeStamp = lastFrameTimeStamp + frameDuration。
優(yōu)點(diǎn)
能輸出frame duration穩定的音視頻時(shí)間戳。
風(fēng)險
無(wú)論是音頻還是視頻,在手機過(guò)熱、性能不足等極端情況下有可能出現采集不穩定的情況,比如說(shuō)預計1s采集30幀,實(shí)際只采集到28幀,而音視頻的時(shí)間戳是通過(guò)累加來(lái)計算的,這樣就有會(huì )出現音視頻不同步的情況。
Video Process(人臉檢測、濾鏡、3D貼紙)有可能無(wú)法在一幀時(shí)間內處理完當前幀,這樣就會(huì )出現幀數比預期低的情況,從而出現音視頻不同步。
幀間隔涉及到無(wú)限小數時(shí),因為計算機的精度有限會(huì )引發(fā)的時(shí)間戳偏移,此偏移會(huì )隨著(zhù)幀數的增加而逐漸被放大。
基于開(kāi)源項目1的改進(jìn)方案1
如圖:

時(shí)間戳的獲取方法非常直接——每一幀都在改幀進(jìn)入時(shí)間戳計算模塊時(shí)獲取當前系統時(shí)間作為時(shí)間戳。
優(yōu)點(diǎn)
APP性能正常的情況下肯定不會(huì )出現音視頻不同步;
能夠實(shí)時(shí)糾正時(shí)間戳,只要APP正常運轉,就能立即恢復正確的時(shí)間戳。
風(fēng)險
依賴(lài)Video Process與Audio Process模塊處理時(shí)長(cháng)相近,而實(shí)際工程中因為人臉檢測、貼紙等原因,Video Process可能會(huì )出現阻塞的情況,從而導致臨時(shí)性的音視頻不同步
在A(yíng)udio Process與Video Process模塊處理幀耗時(shí)不均勻的情況下會(huì )出現音視頻時(shí)間戳不均勻的問(wèn)題,能否正常播放依賴(lài)于終端
基于開(kāi)源項目1的一個(gè)改進(jìn)方案2
如圖:

簡(jiǎn)介
音/視頻被采集到之后,先獲取采集模塊提供的音視頻時(shí)間戳,然后在音/視頻處理模塊透傳采集模塊獲取到的音/視頻時(shí)間戳,在時(shí)間戳計算模塊繼續透傳采集模塊給的時(shí)間戳。
優(yōu)點(diǎn)
除非采集模塊給出錯誤數據,否則音視頻都一定是同步的。
風(fēng)險
可能會(huì )出現音視頻時(shí)間戳不均勻的情況,尤其是在手機過(guò)熱、性能不足等極端情況下。
直播方向更進(jìn)一步的優(yōu)化探討
大致流程如圖:

簡(jiǎn)介
音/視頻被采集到之后,先獲取采集模塊提供的音視頻時(shí)間戳,然后在音/視頻處理模塊透傳采集模塊獲取到的音/視頻時(shí)間戳。
在時(shí)間戳計算模塊透傳視頻時(shí)間戳,并根據下文中提到的方法計算音頻時(shí)間戳。
音頻時(shí)間戳計算方法
實(shí)時(shí)計算時(shí)間戳:當前時(shí)間戳=起始時(shí)間戳+幀數*幀采樣數/采樣率;
如果時(shí)間戳偏移量超出閾值,糾正時(shí)間戳;
糾正頻率達到超出閾值,直接透傳采集時(shí)間戳。
優(yōu)點(diǎn)
能夠提供一個(gè)穩定的音頻時(shí)間戳,可以兼容幀間隔小幅抖動(dòng)造成的音頻時(shí)間戳不均勻;
兼容性能不足時(shí)導致實(shí)際采集幀數低于幀率。
風(fēng)險
糾正時(shí)間戳時(shí)可能會(huì )造成聲音卡頓的感覺(jué)。
總結
具體方案最好是針對實(shí)際應用場(chǎng)景有選擇性的做優(yōu)化,比如說(shuō),在可以控制播放器策略的情況,可以考慮根據自研播放器特性做時(shí)間戳處理。而如果播放器不可控,則盡量通過(guò)策略保障幀間隔穩定。 |