mp4文件DASH切片程序
一、簡介
按照DASH標准文檔要求與現有的DASH切片(生成DASH切片參見mb4box命令簡介)來生成Initialization Segment與Media Segment兩種切片,Initialization Segment就是在原來的mp4文件里去除數據box同時添加mvex box的文件,Media Segment里面保存的是sample數據。
生成切片先要獲取兩個信息:
1、每個sample起始位置與大小。
sample的起始位置與大小獲取要涉及到stsc box,stco box和stsz box,通過stsc box獲取trunk列表以及每一個trunk包含sample個數,注意entry_count==1的情況,這樣一個trunk里只有一個sample,chunk與sample的數量相等。通過stco box可以獲取每一個trunk的起始位置與大小,通過stsz box可以獲取每個sample大小的列表,這3個列表都通過sample index關聯起來,sample index從從1開始計數。通過這3個box可以得到每一個sample的起始於大小。
2、每個sample的delta信息。
sample的delta信息可以通過stts box獲取,在解析時注意entry_count為1的情況,這種情況下所有的sample都有相同的delta值。
有了每個sample的位置大小與delta信息后就可以根據標准生成切片文件了。
二、分兩步走具體介紹
1、掃描mp4文件,記錄以下信息
1.1 每個box的start size信息,掃描后生成一個boxInfo的列表
數據結構
typedef struct {
std::string type;
long pos;
long size;
}BoxInfo;
1.2 解析stsc box生成stscInfo列表
StstInfo
typedef struct{
unsigned int first_chunk;
unsigned int samples_per_chunk;
unsigned int sample_description_index;
}StscInfo;
1.3 解析stco box生成chunkInfo 列表
typedef struct{
unsigned int chunk_index;
unsigned int offset;
unsigned int sample_count;
unsigned int sample_description_index;
}ChunkInfo;
1.4 解析stsz box生成sampleList
typedef struct{
unsigned int sample_index;
unsigned int offset;
unsigned int size;
unsigned int delta;
unsigned int chunk_index;
unsigned int sample_description_index;
}SampleInfo;
然后結合上面兩個列表完善sample的信息。
1.5 解析時注意有些box的flag選項會指示使用后續的那些可選參數
2、根據掃描的信息生成初始化切片與數據切片
剩下的就是力氣活了,按照標准組裝就可以了
生成切片注意:
media切片
moof TrackRunEntry Size是后面跟隨的mdat里每個sample的大小
sidx 的referenced_size是下面的moof size加上mdat size
trun DataOffset是表示mdat box里的數據相對與moof開始(length字節開始)的偏移量
tfdt baseMediaDecodeTime是之前所有切片時間和delta
trun sample_duration在播放時會統計,與tfdt 里的baseMediaDecodeTime比較
init切片
與原有的mp4相比去掉mdat box,在moov里添加mvex box指示存在數據切片。
三、mp4box命令
切片
mp4box -dash 10000 -rap -segment-name myDash 4.mp4
查看文件信息
mp4box -info x.mp4
生成xml文件格式的信息
mp4box -diso x.mp4
四、播放器
ExoPlayer
mp4client