1. 程式人生 > >MP4系列之--如何獲取mp4檔案資訊

MP4系列之--如何獲取mp4檔案資訊

        轉自http://zhangwenxin82.blog.163.com/blog/static/1145959562009612024837/,轉載請註明出處。

計算電影長度

方法1

mvhd - movie header atom中找到time scale和duration,duration除以time scale即是整部電影的長度。

time scale相當於定義了標準的1秒在這部電影裡面的刻度是多少。

例如audio track的time scale = 8000, duration = 560128,所以總長度是70.016,video track的time scale = 600, duration = 42000,所以總長度是70

方法2

首先計算出共有多少個幀,也就是sample(從sample size atoms中得到),然後整部電影的duration = 每個幀的duration之和(從Time-to-sample atoms中得出)例如audio track共有547個sample,每個sample的長度是1024,則總duration是560128,電影長度是70.016;video track共有1050個sample,每個sample的長度是40,則總duration是42000,電影長度是70

計算電影影象寬度和高度

tkhd – track header atom中找到寬度和高度即是。

計算電影聲音取樣頻率

tkhd – track header atom中找出audio track的time scale

即是聲音的取樣頻率

計算視訊幀率

首先計算出整部電影的duration,和幀的數目然後

幀率 = 整部電影的duration / 幀的數目

計算電影的位元率

整部電影的尺寸除以長度,即是位元率,此電影的位元率為846623/70 = 12094 bps

查詢sample

當播放一部電影或者一個track的時候,對應的media handler必須能夠正確的解析資料流,對一定的時間獲取對應的媒體資料。如果是視訊媒體, media handler可能會解析多個atom,才能找到給定時間的sample的大小和位置。具體步驟如下:

1.確定時間,相對於媒體時間座標系統

2.檢查time-to-sample atom來確定給定時間的sample序號。

3.檢查sample-to-chunk atom來發現對應該sample的chunk。

4.從chunk offset atom中提取該trunk的偏移量。

5.利用sample size atom找到sample在trunk內的偏移量和sample的大小。

例如,如果要找第1秒的視訊資料,過程如下:

1.  第1秒的視訊資料相對於此電影的時間為600

2.  檢查time-to-sample atom,得出每個sample的duration是40,從而得出需要尋找第600/40 = 15 + 1 = 16個sample

3.  檢查sample-to-chunk atom,得到該sample屬於第5個chunk的第一個sample,該chunk共有4個sample

4.  檢查chunk offset atom找到第5個trunk的偏移量是20472

5.  由於第16個sample是第5個trunk的第一個sample,所以不用檢查sample size atom,trunk的偏移量即是該sample的偏移量20472。如果是這個trunk的第二個sample,則從sample size atom中找到該trunk的前一個sample的大小,然後加上偏移量即可得到實際位置。

6.  得到位置後,即可取出相應資料進行解碼,播放

查詢關鍵幀

查詢過程與查詢sample的過程非常類似,只是需要利用sync sample atom來確定key frame的sample序號

  1. 確定給定時間的sample序號
  2. 檢查sync sample atom來發現這個sample序號之後的key frame
  3. 檢查sample-to-chunk atom來發現對應該sample的chunk
  4. 從chunk offset atom中提取該trunk的偏移量
  5. 利用sample size atom找到sample在trunk內的偏移量和sample的大小

   Random access

Seeking主要是利用sample table box裡面包含的子box來實現的,還需要考慮edit list的影響。

可以按照以下步驟seek某一個track到某個時間T,注意這個T是以movie header box裡定義的time scale為單位的:

  1. 如果track有一個edit list,遍歷所有的edit,找到T落在哪個edit裡面。將Edit的開始時間變換為以movie time scale為單位,得到EST,T減去EST,得到T',就是在這個edit裡面的duration,注意此時T'是以movie的time scale為單位的。然後將T'轉化成track媒體的time scale,得到T''。T''與Edit的開始時間相加得到以track媒體的time scale為單位的時間點T'''。
  2. 這個track的time-to-sample表說明了該track中每個sample對應的時間資訊,利用這個表就可以得到T'''對應的sample NT。
  3. sample NT可能不是一個random access point,這樣就需要其他表的幫助來找到最近的random access point。一個表是sync sample表,定義哪些sample是random access point。使用這個表就可以找到指定時間點最近的sync sample。如果沒有這個表,就說明所有的sample都是synchronization points,問題就變得更容易了。另一個shadow sync box可以幫助內容作者定義一些特殊的samples,它們不用在網路中傳輸,但是可以作為額外的random access point。這就改進了random access,同時不會影響正常的傳輸位元率。這個表指出了非random access point和random access point之間的關係。如果要尋找指定sample之前最近的shadow sync sample,就需要查詢這個表。總之,利用sync sample和shadow sync表,就可以seek到NT之前的最近的access point sample Nap。
  4. 找到用於access point的sample Nap之後,利用sample-to-chunk表來確定sample位於哪個chunk內。
  5. 找到chunk後,使用chunk offset找到這個chunk的開始位置。
  6. 使用sample-to-chunk表和sample size表中的資料,找到Nap在此chunk內的位置,再加上此chunk的開始位置,就找到了Nap在檔案中的位置。