不知不觉竟半年过去了,是时候把坑填了
——————————————————华丽的分割线————————————————
接上篇,本篇的目的是讲解如何把视频数据封装成BOX。
本篇更为枯燥,无关人员赶紧撤退。
啥是Box?
MP4
MP4由若干Box组成的。![](https://img.haomeiwen.com/i9175093/d88ec814c2db2bd7.jpg)
上图是MP4的格式,我们用到的是FMP4。
图片上的每个小方块就是一个Box。Box可以理解为一个类,由Header和Data组成。
class Box{
Header = new Header() //Box头部
Data= new ArrayBuffer() //Box数据
}
Header又由type和Size组成
class Header{
Type = new ArrayBuffer(4) //表示Box类型,如ftyp。4个字节分别存储的是字符的ASCII码值
Size = new ArrayBuffer(4)
//一般size由4个字节保存,
//但是会出现较大的BOX,当size为1时,通过额外的四个字节来表示size。
}
简单BOX的结构示意图
size | type | data |
---|---|---|
4 | 4 | n |
到这里可以创建一个Box类。
class Box{
constructor(type,...arr){
let len = 8;
let size = arr.reduce((total,num)=>total+num.byteLength,0);
let buffer = new Uint8Array(size);
//将BOX的长度设在最开始的4个字节
buffer [0] = (size >> 24) & 0xff;
buffer [1] = (size >> 16) & 0xff;
buffer [2] = (size >> 8) & 0xff;
buffer [3] = size & 0xff;
buffer.set(type,4); //开始设置4位的类型字节,字符的ASCII码值。
let offset = 8; //到此8个字节已经用掉
buffer.forEach(val => { //设置数据
buffer.set(val, offset);
offset += val.byteLength;
})
return buffer;
}
}
再写个根据类型转ascii码的函数
function _type(str){
return [
str.charCodeAt(0),
str.charCodeAt(1),
str.charCodeAt(2),
str.charCodeAt(3)]
}
那我们用的时候就简单了
new Box(_type('moov'),new Box(_type('mvhd'),data1),new Box(_type('track'),data2))
然后就是跟着MP4文档去封装BOX了。
网友评论