軟編碼Flv 到Mp4 容器(五) fmp4 ftyp box 和moov>mvhd box詳解

https://github.com/332065255/flv2fmp4

代碼庫


軟編碼Flv 到Mp4 容器(一)
軟編碼Flv 到Mp4 容器(二) flv tag拆解
軟編碼Flv 到Mp4 容器(三) flv metadata tag解析
軟編碼Flv 到Mp4 容器(四) fmp4 總覽和基礎講解
軟編碼Flv 到Mp4 容器(五) fmp4 ftyp box 和moov>mvhd box詳解
軟編碼Flv 到Mp4 容器(六) fmp4 moov>trak>tkhd box 和 moov>trak>mdia>mdhd box講解
軟編碼Flv 到Mp4 容器(七) fmp4 mdia>hdlr box 和 mdia>minf> smhd 和dinf box講解
軟編碼Flv 到Mp4 容器(八) fmp4 mdia>stbl>stsd box 講解
軟編碼Flv 到Mp4 容器(九) fmp4 stts stsc stsz stco box 講解
軟編碼Flv 到Mp4 容器(十) fmp4 mvex box 講解
軟編碼Flv 到Mp4 容器(十一) fmp4 moof box詳解
軟編碼Flv 到Mp4 容器(十二) fmp4 mdat box詳解
軟編碼Flv 到Mp4 容器(十三) fmp4 生成ftyp和moov所必要的 flv數據


 - ftyp
 - moov
     - mvhd
     - trak
         - tkhd
         - mdia
             - mdhd
             - hdlr
             - minf
                 - smhd
                 - dinf
                     - dref
                         - url
                 - stbl
                     -  stsd
                         - mp4a(avc1)
                             - esds(avcC)
                     - stts
                     - stsc
                     - stsz
                     - stco


     - mvex
        -trex
 - moof
    - mfhd
    - traf
        -tfhd
        -tfdt
        -sdtp
        -trun
 - mdat

首先對應標題的box在 fmp4容器中的位置


ftyp box

Box Type: `ftyp’ //box類型
Container: File //父級box
Mandatory: Yes //是否強制性存在
Quantity: Exactly one //僅有一個

aligned(8) class FileTypeBox
   extends Box(‘ftyp’) {
   unsigned int(32)  major_brand;  //4字節的品牌名稱
   unsigned int(32)  minor_version; //4字節的版本號
   unsigned int(32) compatible_brands[]; //內容4字節的兼容品牌數組
}

上段代碼是官方pdf的ftyp box定義

FTYP = new Uint8Array([
            0x69, 0x73, 0x6F, 0x6D, 
            // major_brand: isom        isom    MP4  Base Media v1 
            //[IS0 14496-12:2003]   ISO YES video/mp4
            0x0, 0x0, 0x0, 0x1, // minor_version: 0x01
            0x69, 0x73, 0x6F, 0x6D, // isom
            0x61, 0x76, 0x63, 0x31 // avc1
        ]);

fmp4的ftyp就是上面所寫, 4字節長度+4字節’ftyp’+FTYP對象,就是完整的ftyp box


moov box

Box Type: ‘moov’ //box名稱
Container: File //box父級,這裏是頂級
Mandatory: Yes //是否強制存在
Quantity: Exactly one //僅有一個

aligned(8) class MovieBox extends Box(‘moov’){ }

由上可見moov box是一個容器box,所以它本身沒有任何描述,4字節moov box長度(這裏的長度是指包含moov裏面全部box的總長度,而不是隻有’moov’4個字節的長度)+4字節的’moov’就是moov的全部描述


moov>mvhd box

Box Type: ‘mvhd’ //box名稱
Container: Movie Box (‘moov’) //box父級,這裏是moov
Mandatory: Yes //是否強制存在
Quantity: Exactly one //僅有一個

aligned(8) class MovieHeaderBox extends FullBox(‘mvhd’, version, 0) { if (version==1) {
   unsigned int(64)  creation_time;
   unsigned int(64)  modification_time;
   unsigned int(32)  timescale;
   unsigned int(64)  duration;
} else { // version==0      //通常版本爲0
   unsigned int(32)  creation_time;   //媒體創建時間 相對於UTC時間1904-01-01零點的秒數)
   unsigned int(32)  modification_time; //修改時間
   unsigned int(32)  timescale;//刻度值,可以理解爲1秒的長度
   unsigned int(32)  duration;//時長
}
template int(32)  rate = 0x00010000; //typically 1.0  //播放速率,高16和低16分別表示小數點前後整數部分和小數部分
template int(16)  volume = 0x0100;   //typically, full volume  //聲音,高8位和低8位分別表示小數點前後整數和小數部分
const bit(16)  reserved = 0;  //2字節保留位
const unsigned int(32)[2]  reserved = 0; //4+4字節保留位
template int(32)[9]  matrix ={ 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 };          
              // Unity matrix視頻變換矩陣
bit(32)[6]  pre_defined = 0;  //6*4保留位
unsigned int(32)  next_track_ID; //4字節的下一個track id
}

上面代碼是mp4官方文檔定義的

首先我們看到,mvhd box繼承的是full box(‘mvhd’,version,0)
full box 是box的增強box,後面跟4個字節,第一個字節是版本,後面3個字節是保留位

var MVHD= new Uint8Array([
            0x00, 0x00, 0x00, 0x00, // version(0) + flags     1位的box版本+3位flags   box版本,0或1,一般爲0。(以下字節數均按version=0)
            0x00, 0x00, 0x00, 0x00, // creation_time    創建時間  (相對於UTC時間1904-01-01零點的秒數)
            0x00, 0x00, 0x00, 0x00, // modification_time   修改時間
            (timescale >>> 24) & 0xFF, // timescale: 4 bytes        文件媒體在1秒時間內的刻度值,可以理解爲1秒長度
            (timescale >>> 16) & 0xFF,
            (timescale >>> 8) & 0xFF,
            (timescale) & 0xFF,
            (duration >>> 24) & 0xFF, // duration: 4 bytes  該track的時間長度,用duration和time scale值可以計算track時長,比如audio track的time scale = 8000, duration = 560128,時長爲70.016,video track的time scale = 600, duration = 42000,時長爲70
            (duration >>> 16) & 0xFF,
            (duration >>> 8) & 0xFF,
            (duration) & 0xFF,
            0x00, 0x01, 0x00, 0x00, // Preferred rate: 1.0   推薦播放速率,高16位和低16位分別爲小數點整數部分和小數部分,即[16.16] 格式,該值爲1.0(0x00010000)表示正常前向播放
            0x01, 0x00, 0x00, 0x00, // PreferredVolume(1.0, 2bytes) + reserved(2bytes)  與rate類似,[8.8] 格式,1.0(0x0100)表示最大音量 
            0x00, 0x00, 0x00, 0x00, // reserved: 4 + 4 bytes    保留位
            0x00, 0x00, 0x00, 0x00,
            0x00, 0x01, 0x00, 0x00, // ----begin composition matrix----
            0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, //視頻變換矩陣   線性代數
            0x00, 0x00, 0x00, 0x00,
            0x00, 0x01, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00,
            0x40, 0x00, 0x00, 0x00, // ----end composition matrix----
            0x00, 0x00, 0x00, 0x00, // ----begin pre_defined 6 * 4 bytes----
            0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, //pre-defined 保留位
            0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, // ----end pre_defined 6 * 4 bytes----
            0xFF, 0xFF, 0xFF, 0xFF // next_track_ID 下一個track使用的id號
        ])

mvhd是一個full box,所以它沒有子box了,它最終的表現是 4字節長度+4字節’mvhd’+MVHD對象,就是一個完整的mvhd box

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章