Mp4視頻首幀加載時間過長問題分析

一.背景說明

用戶反映某課程視頻(mp4格式)從打開播放器到第一幀畫面顯示劝堪,加載時間過長纱兑,影響觀看體驗。

二.時間埋點

1.定位耗時問題拇惋,最直接的方法是在關(guān)鍵節(jié)點埋點,打印時間戳抹剩,找出耗時操作撑帖。項目使用的是IJKPlayer,需要注意的是埋點前需要關(guān)閉ffmpeg的打印日志吧兔,打印大量的日志會很耗性能(ffmpeg在給mp4文件創(chuàng)建索引表時會打印大量ctts磷仰,sttz等信息):
[IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG];
//改成Silent模式
[IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_SILENT];

埋點代碼如下(精確到毫秒):

struct  tm      *ptm;
struct  timeb   stTimeb;
ftime(&stTimeb);
ptm = localtime(&stTimeb.time);
printf("0:Local time is:%02d-%02d %02d:%02d:%02d.%03d\n",
            ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, stTimeb.millitm);
2.在ffplay初始化到第一幀畫面顯示之間埋點。幾個重要函數(shù)如下:

stream_openffplay入口函數(shù)境蔼。

avformat_open_input:用于打開多媒體數(shù)據(jù)并且獲得相關(guān)信息灶平。

av_read_frame:從文件中讀取出AVPacket

decode_video_internal:將AVPacket視頻包送入VideoToolBox中解碼箍土。

VTDecoderCallbackVideoToolBox解碼完成的回調(diào)函數(shù)逢享,此函數(shù)將解碼后的YUV數(shù)據(jù)送入OpenGL ES中渲染出畫面。

3.分別在本地模式和在線模式吴藻,打印時間戳:
3.png

縱向?qū)Ρ龋涸诰€模式下瞒爬,首幀顯示總耗時為4.967秒,速度較慢沟堡。其中avformat_open_input函數(shù)占總耗時的94%左右侧但。本地模式下,首幀顯示總耗時為0.257秒航罗,速度較快禀横。其中avformat_open_input函數(shù)占總耗時的34%左右。

橫向?qū)Ρ龋涸诰€模式下粥血,avformat_open_input函數(shù)的耗時為4.668秒柏锄,本地模式下為0.088秒酿箭,相差4.58秒。

三趾娃、分析avformat_open_input函數(shù)

1.avformat_open_input函數(shù)是ffmpeg框架中libavformat庫的核心函數(shù)缭嫡,作用是打開一個輸入流并且讀它的頭部信息。函數(shù)內(nèi)部做了3件事:

a.分配一個AVFormatContext的實例抬闷。

b.調(diào)用init_input函數(shù)初始化輸入流的信息妇蛀。這里會初始化AVInputFormat

c.根據(jù)上一步初始化好的AVInputFormat的類型饶氏,調(diào)用它的read_header方法讥耗,讀取文件頭。

2. 從以上流程看疹启,a.c的邏輯在本地播放與在線播放一致古程,所以不是耗時操作。而b中初始化流信息喊崖,需要根據(jù)探測到的視頻格式向服務(wù)器端請求視頻頭部信息挣磨。

四、分析視頻結(jié)構(gòu)

1.請求視頻頭部信息荤懂。在mp4格式下即為請求moov數(shù)據(jù)茁裙。使用Media Parser解析問題視頻如下:
WX20200426-185823@2x.png

ftyp(32個字節(jié)):描述的文件的版本、兼容協(xié)議等

free(8個字節(jié)):未知box节仿。

mdat(220572275個字節(jié)):實際媒體數(shù)據(jù)晤锥。解碼播放的數(shù)據(jù)都在這里面。

moov(2310446個字節(jié)):container box.不包含具體媒體數(shù)據(jù)廊宪,但包含本文件中所有媒體數(shù)據(jù)的宏觀描述信息矾瘾。

2.從圖中可以看出,moov在視頻文件尾部箭启。本地播放時壕翩,通過指針可快速定位到moov;在線播放則需要先加載一部分頭部數(shù)據(jù)傅寡,如fytp放妈,free,madat等荐操,計算出moov的偏移量芜抒,再通過Http Range Bytes請求moov數(shù)據(jù).
2.moov數(shù)據(jù)有2310446個字節(jié),約2.2M托启。在線播放時avformat_open_input需請求全部的moov數(shù)據(jù)宅倒,建立索引表后,再解析音視頻數(shù)據(jù)驾中。本地播放無需網(wǎng)絡(luò)請求唉堪。

五、結(jié)論及解決方案

1.mp4的結(jié)構(gòu)特性是導(dǎo)致長視頻首幀顯示過慢的主要原因肩民。

播放mp4音視頻數(shù)據(jù)前需要先加載moov數(shù)據(jù)唠亚,moov的大小和視頻長度成正比(如問題視頻為長度為46分01秒,moov數(shù)據(jù)約2.2M)持痰。在網(wǎng)絡(luò)較差的情況下灶搜,加載moov數(shù)據(jù)會耗費較長時間。

解決方案:避免加載體積過大的視頻頭工窍。

a.拆分長視頻成數(shù)個短視頻割卖。如46分鐘左右的視頻可拆分為3個15分鐘左右的短視頻。減少moov的長度患雏。

ffmpeg -ss 00:00:00 -t 00:15:00 -i test.mp4 -vcodec copy -acodec copy output.mp4

b.使用輕量級格式鹏溯,如分段FLV(愛奇藝,優(yōu)酷)淹仑,DASH(YouTube丙挽,B站)等方案。

2.moov在視頻文件尾部匀借,多了一次seek請求操作颜阐。相對于第一點,影響較小吓肋。
解決方案:服務(wù)器端將moov從文件尾部移到ftyp后面凳怨,ffmpeg命令行如下:
ffmpeg -i input.mp4 -c:a copy -c:v copy -movflags +faststart output.mp4
3.預(yù)加載,在適當(dāng)時機(jī)提前加載視頻頭部數(shù)據(jù)是鬼,寫入本地文件肤舞,播放器從本地讀取數(shù)據(jù),快速構(gòu)建索引表屑咳,進(jìn)入首幀解碼萨赁。

可參考KTVHTTPCache緩存方案。需要注意的是:
a.moov box在頭部位置,否則加載不到兆龙。
b.moov box數(shù)據(jù)量不能過大(長視頻)杖爽,比如moov box 數(shù)據(jù)量有好幾M,預(yù)加載1M紫皇,意義不大慰安。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市聪铺,隨后出現(xiàn)的幾起案子化焕,更是在濱河造成了極大的恐慌,老刑警劉巖铃剔,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撒桨,死亡現(xiàn)場離奇詭異查刻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凤类,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門穗泵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谜疤,你說我怎么就攤上這事佃延。” “怎么了夷磕?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵履肃,是天一觀的道長。 經(jīng)常有香客問我坐桩,道長尺棋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任绵跷,我火速辦了婚禮陡鹃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抖坪。我一直安慰自己萍鲸,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布擦俐。 她就那樣靜靜地躺著脊阴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚯瞧。 梳的紋絲不亂的頭發(fā)上嘿期,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機(jī)與錄音埋合,去河邊找鬼备徐。 笑死,一個胖子當(dāng)著我的面吹牛甚颂,可吹牛的內(nèi)容都是我干的蜜猾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼振诬,長吁一口氣:“原來是場噩夢啊……” “哼蹭睡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起赶么,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤肩豁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體清钥,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡琼锋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了祟昭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斩例。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖从橘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情础钠,我是刑警寧澤恰力,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站旗吁,受9級特大地震影響踩萎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜很钓,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一香府、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧码倦,春花似錦企孩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至推汽,卻和暖如春补疑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背歹撒。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工莲组, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人暖夭。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓锹杈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親迈着。 傳聞我的和親對象是個殘疾皇子嬉橙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容