flv。js源码知识点(下)
flv。js系列三:FLV格式解析
承接上两篇
flv。js源码知识点(上)
flv。js源码知识点(中)
这是最后一篇。flv。js中音视频额分离器是FLVDemuxer,看懂这里的代码之前先要了解FLV文件的数据格式及JS中如何读取指定二进制数据。1FLV文件格式
FLV是FlashVideo的简称,是Adobe公司推出的流媒体文件格式,我们下面对数据的操作都基于FLV规范文档。整体结构如下图所示,由FLVHeader和FLVBody组成。
1。1FLVHeader
FLVHeader是固定的9字节,其定义如下图:
对上图做一些说明,Type列定义该字段的长度,UI8代表8位无符号整型,一个字节。UI32代表32位无符号整型,四个字节。UB〔5〕代表一个字节的5位,UB〔1〕代表一个字节的1位。第一个字节固定是0x46表示F第二个字节固定是0x4c表示L第三个字节固定是0x56表示V第四个字节指定FLV格式版本第五个字节中TypeFlagsAudio表示是否有音频,TypeFlagsVideo表示是否有视频最后四个字节表示FLVHeader的长度固定是数字9
1。2FLVBody与Tag
FLVBody就是由多个PreviousTagSize和Tag组成,其中PreviousTagSize占4个字节,而且第一个PreviousTagSize的值为0。接下来我们看Tag的结构,Tag由TagHeader和TagData组成,其定义如下:
可以看到TagHeader的长度是11个字节。
C音视频开发学习地址:【免费】FFmpegWebRTCRTMPNDKAndroid音视频流媒体高级开发学习视频教程腾讯课堂
C音视频开发学习资料:点击领取音视频开发(资料文档视频教程面试题)(FFmpegWebRTCRTMPRTSPHLSRTP)
2二进制数据读取API
我们需要把ArrayBuffer类型的数据按照上面的FLV格式进行解析,需要借助于DateView视图类来完成二进制数据的读取和写入,下面看我们会遇到的API。
2。1构造函数
来自MDN:
newDataView(buffer〔,byteOffset〔,byteLength〕〕)。参数说明:buffer现有对象ArrayBuffer或SharedArrayBuffer用作支持新DataView对象的存储。byteOffset可选的到上述缓冲区中第一个字节的偏移量(以字节为单位),以供新视图引用。如果未指定,则缓冲区视图从第一个字节开始。byteLength可选的字节数组中的元素数。如果未指定,则视图的长度将与缓冲区的长度匹配。
demo:createanArrayBufferwithasizeinbytesconstbuffernewArrayBuffer(16);Createacoupleofviewsconstview1newDataView(buffer);constview2newDataView(buffer,12,4);frombyte12forthenext4bytesview1。setInt8(12,42);put42inslot12console。log(view2。getInt8(0));expectedoutput:42
2。2获取数据的API
dataview。getUint8(byteOffset)参数byteOffset,从视图开始处读取数据的偏移量(以字节为单位)。返回值,一个无符号的8位整数。dataview。getUint32(byteOffset〔,littleEndian〕)参数byteOffset,从视图开始处读取数据的偏移量(以字节为单位)。littleEndian,可选的指示32位int是按小字节序还是大字节序格式存储的。默认是false。返回值,一个无符号的32位整数。这里只讲了两个用到的API,当然Dateview还有设置和读取有符号或者无符号8位16位32位的API。
2。3Endian字节序
内存中每一个字节是一个单位,对应一个内存地址,8位最大能表示0255,如果要表示数字258就需要2个字节,字节序的作用就是规定这2个字节哪个表示高位哪个表示低位,如果内存地址低的表示低位就是小字节序littleEndian,相反就是大字节序。以表示258举例说明:
代码验证如下:varbufnewArrayBuffer(2);varviewnewDataView(buf);view。setInt16(0,258,true);littleendianwriteletlittleview。getUint8(0);letbigview。getUint8(1);console。log(little)打印2console。log(big)打印13位操作
二进制数据的位操作包括按位非()、按位与()、按位或()、按位异或()、左移()、右移()、无符号右移()。js的API中只提供了读取8、16,32位等固定位的数据,对于其他位数的数据则需要用位操作进行读取。
3。1读取字节中某一位是0或1
可以利用该字节的数与目标位所在的值进行与操作,这样就只保留字节中目标位的取值。例如读取第6和第8位的值。
letdatanewUint8Array(buffer)〔0〕;lethasAudio(data4)4;lethasVideo(data1)1;
3。2读取字节中连续几位所表示数值
先与这几位所表示的数值进行与操作,然后在右移到低位。比如读取一个字节中的前5位所表示的数,前5位的值为248。letdatanewUint8Array(buffer)〔0〕;lettarget(data248)3;
读取字节中其他位置的值也是同理。
3。3多字节拼接大数据
虽然有获取多字节数据的API,但当不满足需求时,可以通过位移和按位或操作进行大数据的拼接。例如FLVtag中有一个时间戳拼接的地方是后8位的二进制应该拼接在24位前面构成32位的数字。
letvnewDataView(chunk,offset);letts2v。getUint8(0);letts1v。getUint8(1);letts0v。getUint8(2);letts3v。getUint8(3);获取时间戳字段ts3是扩展字段是时间戳的高8位lettimestampts0(ts18)(ts216)(ts324);4总结
有了上面的FLV格式的文档,有了对二进制数据读取的方法,剩下的事情就是按照文档对每一个字段进行解析。
为什么单价破万的裘皮大衣,如今跌到几千都没人买?20年前,裘皮大衣就是衣服里的劳斯莱斯,动辄35万的价格,依然让无数贵妇趋之若鹜。然而近三年,裘皮大衣只用35千就能买到,价格暴跌十倍,可销量日渐惨淡。为什么?有人……
孩子刚上幼儿园,应该如何避免孩子与父母的焦虑情绪?小芝麻去幼儿园第一个星期的情景还历历在目!送分离焦虑情绪比较严重的孩子去幼儿园真的太难,那时候我还特意发了一条想法记录小芝麻上幼儿园第一个星期的反应。我想应该有很多小朋友……
家里有老年人的一定要耐心看完这篇文章家里的奶奶已经82高龄了,9月初不小心摔倒了一次,本以为只是破个皮,伤到筋,去医院拍完x光显示胯骨,手腕多处骨折。老人更容易出现骨折,主要是由于老人往往存在骨质疏松症的情……
在我们看不到的地方,还有那么多人在挣扎求生电视机,这么一个几乎要被遗忘的最普通电器,没想到有一天会以200元一台的热销重回大众视角,让全国网友位置诧异。在一个电视节目上,某艺人问了一个问题,穷人的消费主义是什么?这让我……
美国网友中国已是世界第二大经济体,为何信用卡却不太受欢迎?去银行办信用卡,对年轻人来说已经过时了。据央行数据,信用卡全行业发卡量季度环比增速从2017年四季度的6。51,一路下跌到2020年四季度的0。63。相对于互联网消费金融产品,……
科技和狠活之后的恐慌和焦虑自从某音上的科技和狠活的视频火了之后,人们开始看配料表。食品安全问题并不是新鲜话题,可谓是老生常谈,以前是教民众如何辨别产品的真假,现在更凶狠,是告诉我们真的产品,甚至是品牌产……
五十多岁的无奈五十多岁了,多半辈子辛辛苦苦,兢兢业业,为了俩儿子,多少年来守着小买卖,一年里难有几天休闲时光,早出晚归,受尽了人间苦难,挥洒了青春好时光,洒尽了满腔热血。这一切一切,并不是向……
专利质量堪忧?诺基亚专利在多国被挑战本文仅代表作者观点,不代表IPRdaily立场,未经作者许可,禁止转载诺基亚的5G专利费,到底是过高还是合理?来源:IPRdaily中文网(iprdaily。cn)……
名字与大众姓氏完美搭配王姓宝宝名字男孩名字王晏锦王嘉杉王瑜泽王乐旭王维浩王卓廷王彦岳王羽衡王森岩王澄博王宸泽王诺旭王彦鸣王宗俊王恺宥女孩名字王悦溪王佑……
纵欲过度伤元气,阳痿用什么办法解决?能治好吗?纵欲过度伤元气,阳痿用什么办法解决?能治好吗?我的解答:纵欲过度导致肾气亏虚,雄激素不足,就会出现阳痿的情况,持续的治疗23个月就能够有效的改善目前阳痿的症状,平时要保证……
精华液涂上只会用手拍?错!分享正确使用方法,赶紧来抄作业经常听到这样一句俗话:女人保养好就是老样了,女人不保养就是样子老。现在越来越多的女性开始注意自己的形象,她们很愿意为此付出时间与金钱,对于护肤更是精心。说到护肤,我……
女明星教你解决发际线焦虑现在的生活和工作压力都很大,很多年轻女孩最担心的问题就是发际线越拉越长,感觉自己快秃了。其实正确的发型不仅能解决头部问题,还能解决面部问题。当红女星明星杨幂在大爆剧三生三……