在做视频缓存的时候,我们通常需要处理mp4的头信息,并调整mp4的格式。
mp4文件的格式如下图
从图中可以看出这个视频文件第一层有4部分,每一部分都是一个box,分别为:ftype,moov,free,mdat。其实mp4文件是有许多的box组成的。
而moov中存放了视频播放需要的头信息,如下图:
所以视频播放必须先得获取到视频的moov信息,而MP4的格式中moov信息一种是在最开始,一种是在尾部,在尾部则必须调整到视频头部才能顺序播放,同时moov里面的box信息也需要调整,
private processMoovBox(byte[] moov_atom, intindex) {
inti,atom_size,offset_count,current_offset;
String atom_type;
intmoov_atom_size = moov_atom.length-ftyp.length;
try{
for(i = index;i < moov_atom_size -4;i++) {
atom_type = convertHexToString(byteArr2HexStr(moov_atom,i));
if(atom_type.equals("stco")) {
atom_size = Integer.parseInt(byteArr2HexStr(moov_atom,i -4),16);
if(i + atom_size -4> moov_atom_size) {
return;
}
offset_count = Integer.parseInt(byteArr2HexStr(moov_atom,i +8),16);
for(intj =0;j < offset_count;j++) {
current_offset = Integer.parseInt(byteArr2HexStr(moov_atom,i +12+ j *4),16);
current_offset += moov_atom_size -freeLength;
moov_atom[i +12+ j *4+0] = (byte) ((current_offset >>24) &0xFF);
moov_atom[i +12+ j *4+1] = (byte) ((current_offset >>16) &0xFF);
moov_atom[i +12+ j *4+2] = (byte) ((current_offset >>8) &0xFF);
moov_atom[i +12+ j *4+3] = (byte) ((current_offset >>0) &0xFF);
}
i += atom_size -4;
}else if(atom_type.equals("co64")) {
atom_size = Integer.parseInt(byteArr2HexStr(moov_atom,i -4),16);
if(i + atom_size -4> moov_atom_size) {
return;
}
offset_count = Integer.parseInt(byteArr2HexStr(moov_atom,i +8),16);
for(intj =0;j < offset_count;j++) {
current_offset = Integer.parseInt(byteArr2HexStr(moov_atom,i +12+ j *8),16);
current_offset += moov_atom_size -freeLength;
moov_atom[i +12+ j *8+0] = (byte) ((current_offset >>56) &0xFF);
moov_atom[i +12+ j *8+1] = (byte) ((current_offset >>48) &0xFF);
moov_atom[i +12+ j *8+2] = (byte) ((current_offset >>40) &0xFF);
moov_atom[i +12+ j *8+3] = (byte) ((current_offset >>32) &0xFF);
moov_atom[i +12+ j *8+4] = (byte) ((current_offset >>24) &0xFF);
moov_atom[i +12+ j *8+5] = (byte) ((current_offset >>16) &0xFF);
moov_atom[i +12+ j *8+6] = (byte) ((current_offset >>8) &0xFF);
moov_atom[i +12+ j *8+7] = (byte) ((current_offset >>0) &0xFF);
}
i += atom_size -4;
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
这样根据视频流里面的数据就可以解析出mp4的每个字段大小及对应的位置,然后根据位置可下载对应的数据。