mp4格式

MP4(MPEG-4 Part 14)是一種常見的多媒體容器格式,它是在“ISO/IEC 14496-14”標(biāo)準(zhǔn)文件中定義的,屬于MPEG-4的一部分,是“ISO/IEC 14496-12(MPEG-4 Part 12 ISO base media file format)”標(biāo)準(zhǔn)中所定義的媒體格式的一種實現(xiàn),后者定義了一種通用的媒體文件結(jié)構(gòu)標(biāo)準(zhǔn)。MP4是一種描述較為全面的容器格式,被認(rèn)為可以在其中嵌入任何形式的數(shù)據(jù),各種編碼的視頻、音頻等都不在話下,不過我們常見的大部分的MP4文件存放的AVC(H.264)MPEG-4(Part 2)編碼的視頻和AAC編碼的音頻。MP4格式的官方文件后綴名是“.mp4”,還有其他的以mp4為基礎(chǔ)進(jìn)行的擴(kuò)展或者是縮水版本的格式,包括:M4V,3GP,F4V等。

首先看一下軟件對于mp4文件的解析如圖1所示:

圖1

從圖中可以看出這個視頻文件第一層有4部分,每一部分都是一個box,分別為:ftype,moov,free,mdat。其實mp4文件是有許多的box組成的。如圖2所示:

圖2

box的基本結(jié)構(gòu)如圖3所示,其中,size指明了整個box所占用的大小,包括header部分,type指明了box的類型。如果box很大(例如存放具體視頻數(shù)據(jù)的mdat box),超過了uint32的最大數(shù)值,size就被設(shè)置為1,并用接下來的8位uint64來存放大小。


圖3

一個mp4文件有可能包含非常多的box,在很大程度上增加了解析的復(fù)雜性,這個網(wǎng)頁上http://mp4ra.org/atoms.html記錄了一些當(dāng)前注冊過的box類型??吹竭@么多box,如果要全部支持,一個個解析,怕是頭都要爆了。還好,大部分mp4文件沒有那么多的box類型,下圖就是一個簡化了的,常見的mp4文件結(jié)構(gòu)如圖4所示

圖4

一般來說,解析媒體文件,最關(guān)心的部分是視頻文件的寬高、時長、碼率、編碼格式、幀列表、關(guān)鍵幀列表,以及所對應(yīng)的時戳和在文件中的位置,這些信息,在mp4中,是以特定的算法分開存放在stbl box下屬的幾個box中的,需要解析stbl下面所有的box,來還原媒體信息。下表是對于以上幾個重要的box存放信息的說明:

圖5

其實除了moov在前面的還有moov在后面的情況,如果要實現(xiàn)邊下邊播,就得把moov的box移到前面,因為只有獲得了moov的信息,播放器才可以獲取到播放器的信息來進(jìn)行播放。具體代碼如下:

- (NSData*)exchangestco:(NSMutableData*) moovdata{

inti, atom_size, offset_count, current_offset;

NSString*atom_type;

longlongmoov_atom_size = moovdata.length;

Byte*buffer = (Byte*)malloc(5);

buffer[4] =0;

Byte*buffer01 = (Byte*)malloc(moov_atom_size);

[moovdatagetBytes:buffer01 length:moov_atom_size];

for(i =4; i < moov_atom_size -4; i++) {

NSRangerange;

range.location= i;

range.length=4;

[moovdatagetBytes:buffer range:range];

atom_type = [selftosType:buffer];

if([atom_typeisEqualToString:@"stco"]) {

range.location= i-4;

range.length =4;

[moovdatagetBytes:bufferrange:range];

atom_size = [selftoSize:buffer];

if(i + atom_size -4> moov_atom_size) {

WBLog(LOG_ERROR,@"error i + atom_size - 4 > moov_atom_size");

returnnil;

}

range.location= i+8;

range.length=4;

[moovdatagetBytes:bufferrange:range];

offset_count = [selftoSize:buffer];

for(intj =0; j < offset_count; j++) {

range.location= i +12+ j *4;

range.length=4;

[moovdatagetBytes:bufferrange:range];

current_offset= [selftoSize:buffer];

current_offset += moov_atom_size;

buffer01[i +12+ j *4+0] = (Byte) ((current_offset >>24) &0xFF);

buffer01[i +12+ j *4+1] = (Byte) ((current_offset >>16) &0xFF);

buffer01[i +12+ j *4+2] = (Byte) ((current_offset >>8) &0xFF);

buffer01[i +12+ j *4+3] = (Byte) ((current_offset >>0) &0xFF);

}

i += atom_size -4;

}

elseif([atom_typeisEqualToString:@"co64"]) {

range.location= i-4;

range.length=4;

[moovdatagetBytes:bufferrange:range];

atom_size = [selftoSize:buffer];

if(i + atom_size -4> moov_atom_size) {

WBLog(LOG_ERROR,@"error i + atom_size - 4 > moov_atom_size");

returnnil;

}

range.location= i+8;

range.length=4;

[moovdatagetBytes:bufferrange:range];

offset_count = [selftoSize:buffer];

for(intj =0; j < offset_count; j++) {

range.location= i +12+ j *8;

range.length=4;

[moovdatagetBytes:bufferrange:range];

current_offset = [selftoSize:buffer];

current_offset += moov_atom_size;

buffer01[i +12+ j *8+0] = (Byte)((current_offset >>56) &0xFF);

buffer01[i +12+ j *8+1] = (Byte)((current_offset >>48) &0xFF);

buffer01[i +12+ j *8+2] = (Byte)((current_offset >>40) &0xFF);

buffer01[i +12+ j *8+3] = (Byte)((current_offset >>32) &0xFF);

buffer01[i +12+ j *8+4] = (Byte)((current_offset >>24) &0xFF);

buffer01[i +12+ j *8+5] = (Byte)((current_offset >>16) &0xFF);

buffer01[i +12+ j *8+6] = (Byte)((current_offset >>8) &0xFF);

buffer01[i +12+ j *8+7] = (Byte)((current_offset >>0) &0xFF);

}

i += atom_size -4;

}

}

NSData*moov = [NSDatadataWithBytes:buffer01length:moov_atom_size];

free(buffer);

free(buffer01);

returnmoov;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在做視頻緩存的時候,我們通常需要處理mp4的頭信息,并調(diào)整mp4的格式。 mp4文件的格式如下圖 從圖中可以看出這...
    NN90閱讀 2,786評論 0 3
  • 譯者注:這里面的內(nèi)容主要是分析mp4/3gp文件的層級結(jié)構(gòu),詳細(xì)的介紹了各種不同的box的結(jié)構(gòu)等,網(wǎng)上有一些參考資...
    HaloMartin閱讀 2,957評論 0 2
  • 已經(jīng)到了一定境界 自動腦子YY 不需要任何媒介 我沒資格說生活到底像不像屎 你會明白我到底要說什么 ?!?/div>
    不吃番茄jiang閱讀 185評論 0 0
  • 千年滄海 靜默遙等花開 如今櫝鑲 訴說遠(yuǎn)古的無奈 無情總說愛 最是離人齋 塵封的磁帶 是否蘊藏?zé)o盡思念 致鴻哀 鵝...
    烏雙沐恩閱讀 465評論 4 5
  • 一個小屁孩,還不會怎么說話,只會少量的疊詞,不過走路跑起來可歡了,十分活躍。 一開始就圍著茶幾轉(zhuǎn)來轉(zhuǎn)去的,然后就玩...
    一城主閱讀 218評論 0 0

友情鏈接更多精彩內(nèi)容