这里推荐4个比较好用的工具:
MP4 Info
软件截图:
Mp4 Explorer
软件截图:
一个16进制文本查看器,这个任意一个软件就行
Python 只需要准备好环境就行,可以用这样对应的黑框就行
软件截图:
我们先自己写一个工具类,用来读取 Buffer 里面的数据。
因为我们需要分析 MP4 文件里面的数据,当我们把读取到的一部分数据,对这部分数据进行解析操作。
// TimeBufferStream.h
class TimeBufferStream {
private:
void *Buffer;
unsigned int len;
unsigned int index=0;
public:
TimeBufferStream(void *b, unsigned int len);
bool IsEnd();
void GetLenData(void *dst, unsigned int len);
unsigned char GetUChar();
unsigned short GetUShort();
unsigned int GetUInt();
};
// TimeBufferStream.cpp
TimeBufferStream::TimeBufferStream(void *b, unsigned int len)
: Buffer(b), len(len) {
}
bool TimeBufferStream::IsEnd() {
return index >= len;
}
void TimeBufferStream::GetLenData(void *dst, unsigned int len) {
auto *_dst = (unsigned char *) dst;
auto *_src = (unsigned char *) Buffer;
for (int i = 0; i < len; ++i) {
if (IsEnd()) return;
if(_dst){
_dst[i] = _src[index++];
}
}
}
unsigned char TimeBufferStream::GetUChar() {
unsigned char temp = 0;
GetLenData(&temp, 1);
return temp;
}
unsigned short TimeBufferStream::GetUShort() {
unsigned short temp = 0;
GetLenData(&temp, 2);
temp = (temp>>8)|(temp&0xff)<<8;;
return temp;
}
unsigned int TimeBufferStream::GetUInt() {
unsigned int temp = 0;
GetLenData(&temp, 4);
temp = (temp&0xff000000)>>24|(temp&0xff0000)>>16<<8|(temp&0xff00)>>8<<16|(temp&0xff)<<24;
return temp;
} ```
接口分析:
构造函数:传入对应的 buffer 指针和当前 buffer 的长度。
IsEnd():判断 buffer 是否读取完毕。
GetLenData(void *dst, unsigned int len):从 buffer 读取 len 个字节到 dst 当中。
GetUChar():读取 buffer 一个字节的长度 返回一个无符号字节。
GetUShort():读取 buffer 两个字节的长度 返回一个无符号短整形。
GetUInt():读取 buffer 两个字节的长度 返回一个无符号整形。
上面涉及到的移位操作,是由于大端模式和小端模式导致的。
这里我简单介绍一下:
比如一个 unsigned char c[4] = {0x0, 0x0, 0x0, 0x5}
0-7bit | 8-15bit | 16-23bit | 24-31bit |
---|---|---|---|
0x0 | 0x0 | 0x0 | 0x5 |
我们知道一个无符号整形的长度也是4个字节,
如果我们直接按照以下代码执行:
unsigned char c[4] = {0x0, 0x0, 0x0, 0x5};
auto * numb = (unsigned int*)c;
printf("numb=%ud", *numb); // print numb=83886080d
结果打印出来的并不是我们想要的5,而是 83886080 这么大,这就是因为在 int 内存排布里面 0x5 在高地址位,在大端模式下 0x05<<24 = 83886080,这不太符合我们的直觉,毕竟我们其实想要的是按照我们的习惯,例如:123,从左到右是百位,十位,个位,从大到小从高位到地位这样排布。内存从左到右,从低位到高位,也要符合我们的习惯,所以便有上面的移位操作进行大端转小端操作。(这里看不太明白也没关系,只要知道可以正确解析出我们的数据即可)