溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android視頻開發(fā)中如何進行MP4文件的解析

發(fā)布時間:2021-12-09 10:24:27 來源:億速云 閱讀:143 作者:柒染 欄目:大數(shù)據(jù)

本篇文章為大家展示了Android視頻開發(fā)中如何進行MP4文件的解析,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

我會主要介紹容器 (container format file) 格式文件的細節(jié),以最常見的 MP4 文件入手。然后會簡短的介紹一個標準的播放器的啟動,解析,播放流程。本篇還是以基礎知識為主,雖然很枯燥,但是對視頻開發(fā)的學習有非常大的好處,我自己個人的感受就是,如果在很多專有名字,概念都不熟悉的情況下,想要去閱讀播放器源碼會是相當困難的事情。比如 Exoplayer,谷歌的分包策略就是根據(jù)播放器的組件來分包。如果不熟悉播放器的基礎構建的話,連哪個部分的代碼在哪個包都不知道。希望大家如果真的想進階的話還是耐心的理解好每個基礎概念。

1. Mp4 格式文件的構成

在上期我們大概介紹了 Mp4 文件的結構

Android視頻開發(fā)中如何進行MP4文件的解析  

但是這樣抽象的介紹可能還是比較難理解,我們深入一些。

 
1.1 MP4 到底是個啥?

通俗的說,MP4 其實是一種格式的規(guī)范,這個規(guī)范是被 ISO 機構認證的,也就是說,只要你通過 Codec 生成了一個 mp4 文件,那么這個文件的格式必須是按照 ISO 機構的規(guī)矩來。。。。既然是規(guī)范,那么我們看看到底 ISO 對 mp4 做了什么規(guī)范:

請大家打開鏈接->ISO 的 mp4 文件規(guī)范 [1]

大家可能會有點懵逼,看不懂。其實這個規(guī)范很好理解,它定義了一個 MP4 文件里面,哪些數(shù)據(jù)應該放在什么位置 (以字節(jié)為單位),哪些數(shù)據(jù)的長度是多少。我截取了一段:

Android視頻開發(fā)中如何進行MP4文件的解析  

大家看,上面這一段規(guī)范定義了 ftyp 這個頭文件 header 所在的位置和長度 (以字節(jié)為單位)。至于這些頭文件是有什么用,我在上一篇文章大概提到過,他們屬于 meta data 的一部分。在本章我會更詳細的介紹。

所以說,任何容器,包括 mp4 都是類似的結構化文件,只不過不同的格式文件 ISO 對其有嚴格的要求,數(shù)據(jù)的擺放順序,排列等等不同而已。有興趣的同學可以對比一下 rmvb,mp4,mkv 這些格式的要求有什么不同,優(yōu)劣勢各是什么。

 

2. Mp4 頭文件的構成

關于 mp4 文件的頭文件格式(meta data),蘋果官網(wǎng)對其進行了詳細的描述(這個介紹是基于 QuickTime 播放器支持的 mp4 文件來介紹的,quciktime 播放器對 mp4 的要求有些許不同,但是差別不大,我們可以忽略):

Movie Atom[2]

我們不追究太多細節(jié),有興趣的同學可以自己查看,我們專注于一些基礎的信息。

首先,在 Meta Data 里面,每一個 Header,頭文件,我們都叫他們 Atom Header(不知道咋翻譯)。Atom Header 分為 Leaf Atom 和 Container Atom。前者代表一個連接著字符串信息的頭文件,后者是一個包含了若干個子 Atom 的頭文件,他們互相之間是有層級關系的 (參考上圖)。每次播放器獲取了 movie atom 之后 (moov),會根據(jù)層級關系,向下,或者向下讀取相關的其他信息。每一個頭文件都會對它的子頭文件保存位置的引用,所以只要根據(jù) mp4 文件的規(guī)范獲取了最頂級的頭文件 moov,就可以順勢往下讀取其他頭文件了。

我們來看看 mp4 的頭文件結構

Android視頻開發(fā)中如何進行MP4文件的解析  

看起來很復雜,但是對于一個播放器來說,很多信息都不是必須。我們需要知道的最重要的信息是采樣索引表(Sample Table Atoms).對應圖中“**stbl **”這個 atom header。這個索引表保存了 mp4 文件所有的采樣 (sample) 與視頻時間的對應關系 (一般以微秒為單位),還有包括每個采樣的大小,在 mp4 文件中的起始位置 (以自己為單位)。

 

3. 標準播放器的啟動流程

那么既然我們已經(jīng)知道一個容器文件的格式規(guī)范了,播放器就可以通過解析容器的頭文件來控制播放 (playback) 了。

 
3.1 播放器

通常播放器由三個部分構成

  1. 讀取器 (Extractor)
  2. 渲染器 (TrackRenderer)
  3. 加載控制器 (Load Controller)
  4. 數(shù)據(jù)源 (Source)

讀取器負責從 source 文件讀取數(shù)據(jù),加載控制器負責控制讀取數(shù)據(jù)的策略 (比如說在線視頻播放的時候緩沖策略),渲染器負責接收讀取器讀取的數(shù)據(jù),并渲染到屏幕上。

Android視頻開發(fā)中如何進行MP4文件的解析  
 
3.2 播放器的播放過程

在播放器可以把數(shù)據(jù)提交給渲染器之前,播放器需要把必需的頭文件全部解析并存入內存,比如之前說的采樣索引表。一般播放器在解析完畢后,會構建三個個表,一個存放時間對應采樣索引,一個存放采樣索引對應在 mp4 文件中的起始位置 (以字節(jié)為單位),一個存放采樣索引對應大小 (以字節(jié)為單位)。以下圖為例

假設播放器需要從第 1 微秒開始播放,那么需要把第 1 微秒的數(shù)據(jù)放入渲染器。所以會查找下面這三個表。

Android視頻開發(fā)中如何進行MP4文件的解析  

通過表 1,我們知道該微秒對應第 1 個采樣(sample),從第一個和第二個表我們知道,第 1 個采樣的數(shù)據(jù)范圍 (在 mp4 文件內) 是從第 0 字節(jié)到 300(0+300)字節(jié),那么播放器就會去讀取這個范圍的數(shù)據(jù)并且放入渲染器中進行渲染。

同時,加載器會基于當前已經(jīng)緩存的數(shù)據(jù),決定是否還需要不停的讀取數(shù)據(jù)進入內存。一般來說每個播放器都有默認的緩存值,也會有一個基準線,只有當緩存足夠數(shù)據(jù)才能放進渲染器進行渲染。

最后同理,當我們拖動滑動控制器 (SeekBar) 想快進的時候,我們和第一步一樣,通過我們想滑動的時間獲取采樣的索引,再重新開始讀取數(shù)據(jù)。

綜上所述,播放器在正式播放視頻文件之前,必須要把頭文件全部讀取并解析 (這會是一段非常耗時的程序),這也是在線視頻播放的等待時間的瓶頸。在接下來的章節(jié)我會介紹自適應視頻播放 (Adaptive Streaming),這個技術的發(fā)明使得了分段式 mp4 文件 (Fragmented Mp4) 技術得以誕生,大大的減少了在線視頻播放的等待時間。

 

4.在線視頻播放的技術基礎 (online video streaming)

在線視頻的播放其實和播放本地視頻的局別就是 Extractor 讀取的 Source,數(shù)據(jù)源不一樣,在線播放需要下載數(shù)據(jù)到內存,再交由 Extractor 讀取分析。但是既然是在線視頻播放,我們肯定不能把整個容器文件下載到內存或者硬盤再開始解析播放。我們希望能控制下載的進度,比如我當前在看第 10s 的視頻內容,所以我只想緩存/下載視頻內容到第 20s 的位置。

我們俗稱的漸進式下載 (Progressive Downloading) 就解決了這一難題。

說的好像是很嚇人的黑科技?。。。?!

Android視頻開發(fā)中如何進行MP4文件的解析  

其實就是 HTTP1.1 協(xié)議支持的分段式下載而已。。。。。

Android視頻開發(fā)中如何進行MP4文件的解析  

在 HTTP 請求里面假如一個叫 RANGE 的 header,放入起始字節(jié)和結束字節(jié),就可以只下載對應部分的數(shù)據(jù),這一 header 的支持也是各種下載軟件實現(xiàn)斷點下載的基礎。每次斷網(wǎng)的時候記錄下來已經(jīng)下載的數(shù)據(jù)的字節(jié)數(shù),下次再下載的時候從字節(jié)數(shù)+1 處重新下載并且寫入原有文件就可以了。

上述內容就是Android視頻開發(fā)中如何進行MP4文件的解析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

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

AI