溫馨提示×

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

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

播放器技術(shù)分享(4):首開(kāi)時(shí)間

發(fā)布時(shí)間:2020-07-29 15:06:44 來(lái)源:網(wǎng)絡(luò) 閱讀:2092 作者:Jhuster 欄目:軟件技術(shù)

搞音視頻開(kāi)發(fā)好些年,分享過(guò)許多博客文章,比如:前幾年發(fā)布的《FFmpeg Tips》系列,《Android 音頻開(kāi)發(fā)》系列,《直播疑難雜癥排查》系列等等。最近想把多年來(lái)開(kāi)發(fā)和優(yōu)化播放器的經(jīng)驗(yàn)也分享出來(lái),希望能幫助到音視頻領(lǐng)域的初學(xué)者。第一期文章要推出的內(nèi)容主要涉及到播放器比較核心的幾個(gè)技術(shù)點(diǎn),大概的目錄如下:

1.  播放器技術(shù)分享(1):架構(gòu)設(shè)計(jì)

2. 播放器技術(shù)分享(2):緩沖區(qū)管理

3. 播放器技術(shù)分享(3):音畫(huà)同步

4. 播放器技術(shù)分享(4):首開(kāi)時(shí)間

5. 播放器技術(shù)分享(5):延時(shí)優(yōu)化

本篇是系列文章的第四篇,主要聊一聊如何優(yōu)化播放器的首開(kāi)時(shí)間。

1 首開(kāi)時(shí)間的定義

播放器技術(shù)分享(4):首開(kāi)時(shí)間

首開(kāi)時(shí)間:從點(diǎn)擊播放到第一幀畫(huà)面顯示出來(lái)的耗時(shí)。通常大家說(shuō)的 “首屏秒開(kāi)” 指的就是播放器的“首開(kāi)時(shí)間”在 1s 以內(nèi)。

首開(kāi)速度是用戶最簡(jiǎn)單、最直接的體驗(yàn),所以通常是播放器開(kāi)發(fā)中優(yōu)化的重點(diǎn)。

下面是一個(gè)典型的首開(kāi)速度和用戶感受的關(guān)系表:

播放器技術(shù)分享(4):首開(kāi)時(shí)間

2 首開(kāi)時(shí)間的影響因子

要優(yōu)化播放器的首開(kāi)時(shí)間,我們得先了解一下影響播放器首開(kāi)時(shí)間的因素有哪些,下圖簡(jiǎn)單展示了播放器向服務(wù)器申請(qǐng)播放一個(gè)視頻流的全過(guò)程。

播放器技術(shù)分享(4):首開(kāi)時(shí)間

想優(yōu)化播放器的首開(kāi)時(shí)間,首先關(guān)注一下播放流程中的每個(gè)環(huán)節(jié),如圖所示,可能的優(yōu)化點(diǎn)列表如下:

  1. 申請(qǐng)資源的播放 URL 地址的時(shí)機(jī)優(yōu)化 -> 爭(zhēng)取在用戶點(diǎn)擊播放之前拿到 URL

  2. DNS 解析優(yōu)化 -> 提前完成 DNS 解析,并緩存結(jié)果

  3. 服務(wù)器的連接和數(shù)據(jù)傳輸速度優(yōu)化 -> 主要是服務(wù)器節(jié)點(diǎn)與播放器之間的網(wǎng)絡(luò)傳輸優(yōu)化

  4. 視頻流的媒體信息解析優(yōu)化 -> 主要是解析提取算法的優(yōu)化

  5. 解碼和渲染策略優(yōu)化 -> GOP 緩存,確保首幀為關(guān)鍵幀解碼渲染

  6. 其他優(yōu)化手段 -> 測(cè)速選線、解碼算法性能等

在這個(gè)過(guò)程中,每一個(gè)環(huán)節(jié)都有一些影響因子會(huì)決定播放器的首開(kāi)時(shí)間,我們下面詳細(xì)展開(kāi)優(yōu)化思路。

3 首開(kāi)優(yōu)化方法

3.1 優(yōu)化 URL 的獲取時(shí)機(jī)

播放器技術(shù)分享(4):首開(kāi)時(shí)間

如圖是一個(gè)播放列表,每個(gè)視頻都會(huì)對(duì)應(yīng)一個(gè)資源的 URL 播放地址,如果在用戶點(diǎn)擊視頻后,APP 再去后臺(tái)業(yè)務(wù)服務(wù)器去申請(qǐng)這個(gè) URL 播放地址,無(wú)疑增加了一次 HTTP 請(qǐng)求和應(yīng)答的耗時(shí),特別是網(wǎng)絡(luò)不穩(wěn)定的時(shí)候,耗時(shí)更加明顯。

因此,這是一個(gè)可以在 APP 層進(jìn)行的優(yōu)化點(diǎn):在拉取視頻播放列表的時(shí)候,“同時(shí)” 把視頻的 URL 播放地址也拉取下來(lái),在用戶點(diǎn)擊視頻后無(wú)需再向服務(wù)器申請(qǐng)播放地址,即可立即開(kāi)始播放了。

3.2 優(yōu)化 DNS 解析時(shí)間

視頻資源的 URL 地址,往往是包含域名的,比如:

http://jhuster.com/video/movie.mp4

播放器在播放前,需要先進(jìn)行 DNS 解析,把 jhuster.com 這個(gè)域名解析為一臺(tái)服務(wù)器的 IP 地址,然后才能通過(guò) TCP 連接上去,發(fā)送資源請(qǐng)求。

我們?cè)?17CE 網(wǎng)站上簡(jiǎn)單測(cè)測(cè)這個(gè)域名解析的時(shí)間:

播放器技術(shù)分享(4):首開(kāi)時(shí)間

可以看到,平均 DNS 解析時(shí)間在 673ms 左右,但是在很多地區(qū)(比如:佛山市電信,北京市電信)解析時(shí)間都超過(guò) 2s 了,可想而知,在這些地區(qū) DNS 解析緩慢對(duì)播放器首開(kāi)時(shí)間是致命的傷害。

為了確保所有地區(qū)的視頻播放不過(guò)于受 DNS 解析速度的影響,除了為視頻資源的域名購(gòu)買付費(fèi)的專業(yè) DNS 解析服務(wù)外,播放器層面也可以針對(duì)性地做一些優(yōu)化,如下圖所示:

播放器技術(shù)分享(4):首開(kāi)時(shí)間

播放器內(nèi)部新增一個(gè) DNS 結(jié)果緩存模塊

  1. 在異步線程定時(shí)執(zhí)行 DNS 解析,并把 “域名 & IP 表” 緩存在內(nèi)存中

  2. 視頻播放時(shí),直接查表,取出域名對(duì)應(yīng)的 IP 地址,送入播放器

注意事項(xiàng):

  1. 一個(gè) APP 的資源域名個(gè)數(shù)是收斂的,不是無(wú)限個(gè),所以可以在 APP 啟動(dòng)的時(shí)候,送入播放器提前去完成 DNS 解析和緩存

  2. 未提前配置的域名,在第一次解析的時(shí)候,依然會(huì)首開(kāi)慢,但該域名第二次即可從本地緩存中取了

  3. 需要注意緩存的 IP 地址的刷新:

    • DNS 解析有一個(gè) TTL 超時(shí)時(shí)間,到期前要記得重新解析刷新

    • 監(jiān)測(cè)手機(jī)網(wǎng)絡(luò)切換事件,比如:WiFi 切換到 4G 后,需要清空緩存

舉個(gè)例子:

DNS Cache Map:  <jhuster, 185.199.108.153:80>

如果要播放 URL:http://jhuster.com/video/movie.mp4

可直接替換為播放: http://185.199.108.153/video/moive.mp4

坑在哪 ?

當(dāng)我們真的用 ip 地址去播放的時(shí)候,會(huì)發(fā)現(xiàn)服務(wù)器會(huì)拒絕訪問(wèn),例如報(bào)如下錯(cuò)誤:

播放器技術(shù)分享(4):首開(kāi)時(shí)間

原因:視頻資源的 CDN 服務(wù)商需要知道是 “誰(shuí)” 在申請(qǐng)這個(gè)視頻資源 -> 為了計(jì)量和計(jì)費(fèi),服務(wù)商的判斷訪問(wèn)依據(jù)是“域名”,所以直接使用 IP 訪問(wèn)會(huì)遇到上述問(wèn)題。

怎么解決 ?

  1. HTTP  協(xié)議:有個(gè) HOST 字段,記錄了服務(wù)器的域名

  2. RTMP 協(xié)議:有個(gè) tcUrl 參數(shù),記錄了完整的播放器地址(含 服務(wù)器的域名)

其實(shí) CDN 服務(wù)商并不是從 URL 取的域名,而是從 HTTP/RTMP 協(xié)議中的上述字段中 “提取” 的域名,因此,我們需要改造播放器底層的 HTTP/RTMP 代碼模塊,提供一個(gè)接口,可以把 URL 中原始的域名填入到上述協(xié)議字段中即可。

3.3 優(yōu)化服務(wù)器連接和數(shù)據(jù)傳輸時(shí)間

播放器通過(guò) DNS 解析拿到了服務(wù)器的 IP 地址,下一步就是通過(guò) TCP 連接服務(wù)器,然后發(fā)送請(qǐng)求讀取數(shù)據(jù)了。在這個(gè)過(guò)程中,與服務(wù)器的連接速度以及數(shù)據(jù)的傳輸時(shí)間非常重要,直接影響著首開(kāi)體驗(yàn)。

這個(gè)因素并不是在播放器層面可以執(zhí)行的優(yōu)化,因此就簡(jiǎn)單提一下,優(yōu)化的關(guān)鍵因素在于服務(wù)器的負(fù)載、CDN 的節(jié)點(diǎn)分布和帶寬情況了。這也是為什么一般的 APP 公司會(huì)采購(gòu)和使用 CDN 服務(wù)的原因了。

播放器技術(shù)分享(4):首開(kāi)時(shí)間

3.4 優(yōu)化媒體信息的讀取策略

視頻的媒體信息里都有啥 ?

  1. 是否包含:音頻、視頻

  2. 音頻、視頻的編碼格式,如 H.264,AAC 等

  3. 視頻的信息,如 分辨率、幀率、碼率

  4. 音頻的信息,如 采樣率、位寬、通道數(shù)

  5. 碼流的總時(shí)長(zhǎng)

  6. 其他附加信息,如 作者、日期等

可見(jiàn),媒體信息對(duì)于初始化播放器還是非常重要的。不同的音視頻封裝格式,媒體信息存放的位置也不太一樣,像 flv 格式,媒體信息往往直接存放在開(kāi)頭,因此是比較容易第一時(shí)間讀取到的。而 mp4 格式,常常會(huì)遇到 moov 在尾部的情況,這種是播放器優(yōu)化的重點(diǎn),如圖所示:

播放器技術(shù)分享(4):首開(kāi)時(shí)間

對(duì)于這種把媒體信息存放到了尾部的 mp4 文件,默認(rèn)的播放器需要把整個(gè) mp4 全部下載下來(lái)才能拿到媒體信息,對(duì)首開(kāi)是極其不友好的。

如何優(yōu)化呢 ?—— 雙 IO 技術(shù)

播放器技術(shù)分享(4):首開(kāi)時(shí)間

如圖所示,對(duì)于 moov 媒體信息在尾部的 mp4 文件,播放器讀取一定數(shù)據(jù)后,如果判斷 moov 在尾部,則可以暫停這個(gè)線程,同時(shí)啟動(dòng)第二線程通過(guò) http range 字段讀取尾部的 moov,從而拿到關(guān)鍵的媒體信息,這樣的技術(shù)策略的好處是:

  1. 無(wú)需下載整個(gè) mp4 即可播放 moov 在尾部的視頻

  2. 第一個(gè) IO 已下載的部分可繼續(xù)利用,不用丟棄

3.5 優(yōu)化媒體信息的解析時(shí)間

媒體信息解析的工作量在哪 ?

  1. 判斷碼流的封裝格式,比如 mp4,flv,m3u8 等等

  2. 根據(jù)封裝格式的協(xié)議約定,提取數(shù)據(jù)中的媒體信息

為了提高對(duì)非標(biāo)準(zhǔn)碼流的兼容性,ffmpeg 使用了一套非常復(fù)雜的解析策略,即使從碼流中已經(jīng)提取到了 metadata,依然會(huì)做各種 double check,比如,多次 try_decode_frame 測(cè)試是否真的可以成功解碼數(shù)據(jù),從而導(dǎo)致底層基于 ffmpeg 的播放器,首開(kāi)速度會(huì)在這里降下來(lái)。

如何優(yōu)化呢 ?如果是基于 ffmpeg 內(nèi)核的播放器,那么常用的手段如下:

  1. 減小 probesize

  2. 減小 analyzeduration

  3. 預(yù)設(shè)碼流的音視頻格式

3.6 優(yōu)化首幀解碼和渲染

我們知道,編碼后的視頻幀是分 I、B、P 幀的,I 幀是關(guān)鍵幀,可獨(dú)立解碼出圖像;B/P 幀分別是前向預(yù)測(cè)幀/雙向參考幀,是需要參考 I 幀或前后幀才能解碼出圖像的。

因此,為了盡快解碼出首幀畫(huà)面,需要確保送入編碼器的首幀即是 I 幀。


播放器技術(shù)分享(4):首開(kāi)時(shí)間

如圖所示,在直播場(chǎng)景下,如果觀眾在 C 時(shí)間點(diǎn)拉流,則正好可以拉取到一個(gè) I 幀,迅速完成解碼播放,實(shí)現(xiàn)秒開(kāi)。但是如果不巧,正好在 A 時(shí)間點(diǎn)或者 B 時(shí)間點(diǎn)拉流,則會(huì)導(dǎo)致無(wú)法解碼,一直要等到下一個(gè) I 幀才能完成解碼渲染。

因此,一般的直播云廠商,都會(huì)在服務(wù)端緩存一個(gè) GOP 的數(shù)據(jù),無(wú)論任何時(shí)候,播放器申請(qǐng)播放,都會(huì)首先下發(fā)這樣一個(gè)以 I 幀開(kāi)頭的 GOP 數(shù)據(jù),從而加快了播放器的解碼和首開(kāi)。

對(duì)于播放器而言,需要注意的時(shí)候,當(dāng)?shù)谝粠€沒(méi)有渲染之前,先不要主動(dòng)緩沖,而是盡快先渲染首幀。

4 總結(jié)

當(dāng)然,還有很多其他的播放器首開(kāi)時(shí)間的優(yōu)化策略,測(cè)速選線、解碼算法性能等,用的不是很廣泛,這里就不展開(kāi)介紹了。關(guān)于播放器的首開(kāi)時(shí)間優(yōu)化,就分享這么多了,如有疑問(wèn)的小伙伴歡迎來(lái)信 lujun.hust@gmail.com 交流。另外,也歡迎大家關(guān)注我的新浪微博 @盧_俊 或者 微信公眾號(hào) @Jhuster 獲取最新的文章和資訊。

播放器技術(shù)分享(4):首開(kāi)時(shí)間


向AI問(wèn)一下細(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