溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

播放器適配經(jīng)驗(yàn)總結(jié)——IOS

發(fā)布時(shí)間:2020-08-06 13:47:13 來源:網(wǎng)絡(luò) 閱讀:1336 作者:luansxx 欄目:移動(dòng)開發(fā)

IOS平臺(tái)統(tǒng)一使用HLS協(xié)議,包括M3U8文件和分段TS文件

1、抖屏

現(xiàn)象:播放中畫面動(dòng)作抖動(dòng),好像畫面的順序錯(cuò)亂

范圍:Mp4文件轉(zhuǎn)成TS,沒有問題,ASF轉(zhuǎn)成TS文件,有該現(xiàn)象

原因:ASF沒有cts_delta字段,TS(PES)中的PTS直接使用DTS,H.264中幀的順序是DTS順序,與顯示順序是不同的,B幀會(huì)出現(xiàn)在P幀前面,但是在后面顯示

方案:自己根據(jù)幀率和幀的順序,計(jì)算PTS,或者恢復(fù)出cts_delta值

幀率可以通過SPS中獲?。?/p>

frame_rate=sps.vui_parameters.num_units_in_tick.time_scale/sps.vui_parameters.num_units_in_tick

當(dāng)然前提是sps.vui_parameters_present_flag&&sps.vui_parameters.timing_info_present_flag&&sps.vui_parameters.fixed_frame_rate_flag

前提不滿足的時(shí)候,可以用前后兩個(gè)幀的dts差來計(jì)算:

frame_rate=time_scale/dts_diff

幀的順序在每個(gè)幀內(nèi)部有字段表示,根據(jù)sps.pic_order_cnt_type有不同算法,現(xiàn)在只考慮sps.pic_order_cnt_type==0的情況,這時(shí)候slice.slice_header.pic_order_cnt_lsb表示順序

cts=(dtsofidr)+slice.slice_header.pic_order_cnt_lsb/2*time_scale/frame_rate

或者直接使用num_units_in_tick:

cts=(dtsofidr)+slice.slice_header.pic_order_cnt_lsb/2*sps.vui_parameters.num_units_in_tick

2、爆音

現(xiàn)象:播放過程中聲音異常,夾雜著輕微爆炸的聲音

范圍:Mp4文件轉(zhuǎn)成TS,沒有問題,ASF、FLV轉(zhuǎn)成TS文件,有該現(xiàn)象

原因:ASF、FLV時(shí)間戳是毫秒級(jí)精度,TS文件是90000分之一秒,相差90倍,直接乘以90轉(zhuǎn)換,精度不夠。IOS播放TS的時(shí)候,完全依賴TS時(shí)間戳。

比如采樣率22050的音頻,1024的采樣點(diǎn)一個(gè)Sample,那么前三個(gè)Sample的時(shí)間戳情況是:

Sample號(hào)精確時(shí)間戳(秒)ASF時(shí)間戳誤差TS時(shí)間戳誤差
0000
11024/22050-0.00043990.000004535
22048/220500.0001202-0.000002041

方案:自己根據(jù)采樣率計(jì)算TS的時(shí)間戳,問題完整解決。

音頻samplen的TS(PES)時(shí)間戳為n*90000*1024/采樣率

備注:一開始沒有找到這個(gè)原因,采用合并音頻幀的方法,幾十個(gè)音頻幀合并起來,基本能解決問題,其中原因是合并之后誤差減少,用上面的原因分析也是說得通的。

3、綠屏

現(xiàn)象:播放剛開始,會(huì)出現(xiàn)瞬間綠色畫面

范圍:播放某幾個(gè)文件時(shí);有時(shí)正常從頭播放沒有綠屏,但是從中間繼續(xù)播放會(huì)有綠屏。

原因:?jiǎn)栴}焦點(diǎn)集中在SEI的位置,Mp4只有第一個(gè)幀有SEI(只在第一個(gè)分段Mp4中有SEI),該幀的格式是:SEI+ISlice(IDRNalu),是同步幀。老版本bento4生成PES結(jié)果是AUD+SEI+SPS+PPS+ISlice(IDR);新版本版本bento4生成PES結(jié)果是AUD+SPS+PPS+SEI+ISlice(IDR)。雖然新版本有改動(dòng),也不能解決綠屏問題,還需要進(jìn)一步分析。

方案:

4、播放器crash

現(xiàn)象:播放器直接crash掉

范圍:MacOs平臺(tái),播放某幾個(gè)文件時(shí),在一個(gè)特定時(shí)間點(diǎn)。iphone、ipad并沒有問題,但是同一影片同一時(shí)間點(diǎn),會(huì)有播放丟幀現(xiàn)象

原因:?jiǎn)栴}本質(zhì)上在于媒資壓片(用Mp4Box生成Mp4文件)生成了不合常規(guī)的幀格式,在一個(gè)幀中出現(xiàn)了兩個(gè)slice:PSlice+ISlice(IDRNalu),該幀不在Mp4同步幀索引中,因此不算是同步幀。老版本的bento4生成PES的策略是在每個(gè)幀前面加上AUD,在IDR前面增加SPS、PPS,所以轉(zhuǎn)換結(jié)果是AUD+PSlice+SPS+PPS+ISlice(IDR);新版本的bento4生成PES的策略是在每個(gè)幀前面加上AUD,在同步幀增加SPS、PPS(在AUD后面),所以轉(zhuǎn)換結(jié)果是AUD+PSlice+ISlice(IDR)。Mac是QuickTime播放器在解析PES時(shí),不知道什么算法,會(huì)在第一種情形Crash,第二種情況丟失一個(gè)ISlice,出現(xiàn)圖像失常。請(qǐng)注意,如果Mp4的幀格式符合常規(guī),那么新老bento4生成的結(jié)果是一樣的。

最后確認(rèn)是老版本MP4Box的bug,它在生成的MP4文件時(shí)將I和P幀打在了一個(gè)Sample中。具體原因是這個(gè)版本的MP4Box是以0x00000001為起始碼尋找NAL包,碰到以0x000001開頭時(shí)(比如出問題的IDR幀)就會(huì)跳過去,而264標(biāo)準(zhǔn)中起始碼0x000001或0x00000001都應(yīng)支持的。

方案:更新Mp4Box

5、無圖像

現(xiàn)象:播放有聲音、無圖像

范圍:ipad、iphone,一個(gè)特定的頻道

原因:在FLV文件轉(zhuǎn)成TS文件時(shí),F(xiàn)LV文件在沒有同步幀上有SPS,PPS,轉(zhuǎn)換邏輯據(jù)此判斷H.264ES流中存在AUD(AccessUnitDelimiter),但是實(shí)際上不存在AUD,導(dǎo)致生成的TS文件中沒有AUD,ios平臺(tái)的播放器需要AUD,沒有就不能播放視頻。

方案:修正轉(zhuǎn)換邏輯,直接判斷有沒有AUD,并補(bǔ)充AUD。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI