<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在線(xiàn)直播網(wǎng)站源碼開(kāi)發(fā),音視頻同步的處理方案及選擇

          共 3821字,需瀏覽 8分鐘

           ·

          2022-02-09 17:34

          如果在直播場(chǎng)景中,音視頻不同步就會(huì)給觀眾造成不好的觀感,不利于在線(xiàn)直播網(wǎng)站源碼的長(zhǎng)期發(fā)展,所以今天我們就一起來(lái)了解一下,在在線(xiàn)直播網(wǎng)站源碼開(kāi)發(fā)時(shí),音視頻同步的三種處理方案。

          通常有以下三種:

          1.視頻時(shí)鐘同步到音頻時(shí)鐘

          以在線(xiàn)直播網(wǎng)站源碼音頻時(shí)鐘為標(biāo)準(zhǔn)時(shí)鐘,音頻自然播放。視頻幀播放時(shí)判斷當(dāng)前視頻幀播放結(jié)束后的時(shí)間與當(dāng)前的音頻時(shí)鐘時(shí)間對(duì)比,如果視頻當(dāng)前幀播放完時(shí)間比音頻時(shí)鐘時(shí)間早,則讓當(dāng)前視頻播放線(xiàn)程暫時(shí)時(shí)間差,以保證播放完后與音頻時(shí)鐘同步。如果在線(xiàn)直播網(wǎng)站源碼當(dāng)前視頻幀播放完時(shí)間比音頻時(shí)間晚,則丟棄當(dāng)前視頻幀讀取下一幀再判斷,以保證播放完后與音頻時(shí)鐘同步。

          2.音頻時(shí)鐘同步到視頻時(shí)鐘

          以在線(xiàn)直播網(wǎng)站源碼視頻時(shí)鐘為標(biāo)準(zhǔn),視頻自然播放。同步邏輯則與第1點(diǎn)的同步邏輯一致:即音頻快了就暫停音頻播放線(xiàn)程等待時(shí)間差,慢了則丟棄當(dāng)前音頻幀。以保證在線(xiàn)直播網(wǎng)站源碼當(dāng)前音頻幀播放完與視頻幀時(shí)鐘同步。

          3.以外部時(shí)鐘為準(zhǔn),音頻與視頻時(shí)鐘同時(shí)同步到外部時(shí)鐘。

          同步邏輯與1、2點(diǎn)一致。需要注意的是外部時(shí)鐘應(yīng)盡量使用毫秒時(shí)鐘以確保在線(xiàn)直播網(wǎng)站源碼中音視頻同步的精準(zhǔn)。

          同步方案選擇

          以上3種方案都可以實(shí)現(xiàn)在線(xiàn)直播網(wǎng)站源碼音頻與視頻的同步處理,但怎么選擇更適合的方案呢?

          人的眼睛與耳朵對(duì)圖像與聲音的敏感程度不一樣,當(dāng)畫(huà)面偶爾缺少一幀或者幾幀時(shí)人的眼睛可能不太容易察覺(jué)。這是因?yàn)楫?huà)面的連貫性比較強(qiáng),兩幀畫(huà)面之前的差異有時(shí)候很小,眼睛比耳機(jī)敏感度更低。當(dāng)聲音發(fā)生一變化,比如缺失了一點(diǎn)聲音或者聲音異常的,人的耳朵馬上就察覺(jué)到了。

          在大多數(shù)在線(xiàn)直播網(wǎng)站源碼上聲音的播放開(kāi)銷(xiāo)都比渲染畫(huà)面小。聲音的數(shù)據(jù)處理過(guò)程更簡(jiǎn)單,數(shù)量量也更小。聲音線(xiàn)程播放聲音卡頓的概率很小。

          在線(xiàn)直播網(wǎng)站源碼聲音的播放緩存對(duì)象是重復(fù)利用的,而這個(gè)利用則是由實(shí)際播放聲音的具體線(xiàn)程來(lái)回調(diào)的。不同于視頻每一幀的渲染,聲音的暫停與丟棄相比視頻實(shí)現(xiàn)成本更高。

          綜合上以的三點(diǎn),本文選擇第1點(diǎn)同步方案視頻時(shí)鐘同步到音頻時(shí)鐘

          編碼實(shí)現(xiàn)音視頻同步

          在線(xiàn)直播網(wǎng)站源碼音頻視頻同步基礎(chǔ)

          FFmpeg里有兩種時(shí)間戳:DTS(Decoding Time Stamp)和PTS(Presentation Time Stamp)。 顧名思義,前者是解碼的時(shí)間,后者是顯示的時(shí)間。要仔細(xì)理解這兩個(gè)概念,需要先了解FFmpeg中的packet和frame的概念。

          FFmpeg中用AVPacket結(jié)構(gòu)體來(lái)描述解碼前或編碼后的壓縮包,用AVFrame結(jié)構(gòu)體來(lái)描述解碼后或編碼前的信號(hào)幀。 對(duì)于在線(xiàn)直播網(wǎng)站源碼的視頻來(lái)說(shuō),AVFrame就是視頻的一幀圖像。這幀圖像什么時(shí)候顯示給用戶(hù),就取決于它的PTS。DTS是AVPacket里的一個(gè)成員,表示這個(gè)壓縮包應(yīng)該什么時(shí)候被解碼。
          如果在線(xiàn)直播網(wǎng)站源碼視頻里各幀的編碼是按輸入順序(也就是顯示順序)依次進(jìn)行的,那么解碼和顯示時(shí)間應(yīng)該是一致的。可事實(shí)上,在大多數(shù)編解碼標(biāo)準(zhǔn)(如H.264或HEVC)中,編碼順序和輸入順序并不一致。 于是才會(huì)需要PTS和DTS這兩種不同的時(shí)間戳。

          基本概念:

          • I幀 :幀內(nèi)編碼幀 又稱(chēng)intra picture,I 幀通常是每個(gè) GOP(MPEG
            所使用的一種視頻壓縮技術(shù))的第一個(gè)幀,經(jīng)過(guò)適度地壓縮,做為隨機(jī)訪問(wèn)的參考點(diǎn),可以當(dāng)成圖象。I幀可以看成是一個(gè)圖像經(jīng)過(guò)壓縮后的產(chǎn)物。
          • P幀: 前向預(yù)測(cè)編碼幀,又稱(chēng)predictive-frame,通過(guò)充分將低于圖像序列中前面已編碼幀的時(shí)間冗余信息來(lái)壓縮傳輸數(shù)據(jù)量的編碼圖像,也叫預(yù)測(cè)幀;
          • B幀: 雙向預(yù)測(cè)內(nèi)插編碼幀 又稱(chēng)bi-directional interpolated prediction
            frame,既考慮與源圖像序列前面已編碼幀,也顧及源圖像序列后面已編碼幀之間的時(shí)間冗余信息來(lái)壓縮傳輸數(shù)據(jù)量的編碼圖像,也叫雙向預(yù)測(cè)幀;
          • PTS:Presentation Time Stamp。PTS主要用于度量解碼后的視頻幀什么時(shí)候被顯示出來(lái)
          • DTS:Decode Time Stamp。DTS主要是標(biāo)識(shí)讀入內(nèi)存中的bit流在什么時(shí)候開(kāi)始送入在線(xiàn)直播網(wǎng)站源碼解碼器中進(jìn)行解碼。

          在沒(méi)有B幀存在的情況下DTS的順序和PTS的順序應(yīng)該是一樣的。

          IPB幀的不同:

          • I幀:自身可以通過(guò)在線(xiàn)直播網(wǎng)站源碼視頻解壓算法解壓成一張單獨(dú)的完整的圖片。
          • P幀:需要參考其前面的一個(gè)I frame 或者B frame來(lái)生成一張完整的圖片。
          • B幀:則要參考其前一個(gè)I或者P幀及其后面的一個(gè)P幀來(lái)生成一張完整的圖片。

          兩個(gè)I幀之間形成一個(gè)GOP,在x264中同時(shí)可以通過(guò)參數(shù)來(lái)設(shè)定bf的大小,即:I 和p或者兩個(gè)P之間B的數(shù)量。

          通過(guò)上述基本可以說(shuō)明如果有B frame 存在的情況下一個(gè)GOP的最后一個(gè)frame一定是P。

          DTS和PTS的不同:

          DTS主要用于在線(xiàn)直播網(wǎng)站源碼視頻的解碼,在解碼階段使用.PTS主要用于視頻的同步和輸出.在display的時(shí)候使用.在沒(méi)有B frame的情況下.DTS和PTS的輸出順序是一樣的.

          音頻與視頻數(shù)據(jù)緩沖對(duì)象增加時(shí)鐘數(shù)據(jù)

          @interface FFQueueAudioObject : NSObject@property (nonatomic, assign, readonly)float pts;@property (nonatomic, assign, readonly)float duration;- (instancetype)initWithLength:(int64_t)length pts:(float)pts duration:(float)duration;- (uint8_t *)data;- (int64_t)length;- (void)updateLength:(int64_t)length;@end
          
          @interface FFQueueVideoObject : NSObject@property (nonatomic, assign)double unit;@property (nonatomic, assign)double pts;@property (nonatomic, assign)double duration;- (instancetype)init;- (AVFrame *)frame;@end
          

          分別在上面的音頻與視頻緩沖對(duì)象上增加變量pts與duration。

          • pts: 當(dāng)前幀播放或顯示的時(shí)間。
          • duration: 當(dāng)前幀播放或顯示持續(xù)的時(shí)長(zhǎng)。在線(xiàn)直播網(wǎng)站源碼音頻幀內(nèi)包括多個(gè)音頻數(shù)據(jù)包,而視頻則可以通過(guò)FPS計(jì)算得到每一幀的顯示持續(xù)時(shí)長(zhǎng)。

          視頻時(shí)鐘同步到音頻時(shí)鐘

          pthread_mutex_lock(&(self->mutex));/// 讀取當(dāng)前的音頻時(shí)鐘時(shí)間double ac = self->audio_clock;pthread_mutex_unlock(&(self->mutex));FFQueueVideoObject *obj = NULL;/// 統(tǒng)計(jì)路過(guò)的視頻幀數(shù)量int readCount = 0;/// 首先讀取一幀視頻數(shù)據(jù)obj = [self.videoFrameCacheQueue dequeue];readCount ++;/// 計(jì)算當(dāng)前視頻帖播放結(jié)束時(shí)的時(shí)間點(diǎn)double vc = obj.pts + obj.duration;if(ac - vc > self->tolerance_scope) {
              /// 視頻太慢,丟棄當(dāng)前幀繼續(xù)讀取下一幀
              /// 這里認(rèn)為讀取下一幀或者更下一幀不會(huì)造成視頻緩沖隊(duì)列枯竭,所以未做等待處理
              /// 因?yàn)闀r(shí)時(shí)同步能形成的時(shí)間差比較有限
              while (ac - vc > self->tolerance_scope) {
                  FFQueueVideoObject *_nextObj = [self.videoFrameCacheQueue dequeue];
                  if(!_nextObj) break;
                  obj = _nextObj;
                  vc = obj.pts + obj.duration;
                  readCount ++;
              }} else if (vc - ac > self->tolerance_scope) {
            /// 視頻太快,暫停一下再接著渲染顯示當(dāng)前視頻幀
              float sleep_time = vc - ac;
              usleep(sleep_time * 1000 * 1000);} else {
            /// 在誤差范圍之后, 不需要處理}
          

          tolerance_scope為可允許的誤差值,即在線(xiàn)直播網(wǎng)站源碼音頻與視頻時(shí)間差小于這個(gè)數(shù)據(jù)則認(rèn)為是同步的。這是因?yàn)橐_(dá)到絕對(duì)的時(shí)間一致性是不可能的,在計(jì)算時(shí)間的過(guò)程中有精度的丟失。

          獲取當(dāng)前在線(xiàn)直播網(wǎng)站源碼音頻時(shí)鐘的時(shí)間(該時(shí)間為當(dāng)前音頻幀播放結(jié)束后的時(shí)間)
          讀取一幀視頻幀,計(jì)算出該視頻幀播放完之后的時(shí)間
          判斷在線(xiàn)直播網(wǎng)站源碼音頻時(shí)間與視頻時(shí)間的差值,進(jìn)行同步處理

          到此,在線(xiàn)直播網(wǎng)站源碼音視頻同步的完成了,希望對(duì)大家的在線(xiàn)直播網(wǎng)站源碼開(kāi)發(fā)有幫助。
          本文轉(zhuǎn)載自網(wǎng)絡(luò),轉(zhuǎn)載僅為分享干貨知識(shí),如有侵權(quán)歡迎聯(lián)系云豹科技進(jìn)行刪除處理

          ?

          瀏覽 17
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲自拍中文字幕 | 色色资源网 | 91无码人妻精品1国产四虎 | 成人三级在线视频 | 久久高清无码视频 |