Movie Box (moov) 该box包含了文件媒体的metadata信息,“moov”是一个container box,具体内容信息由子box诠释。同File Type Box一样,该box有且只有一个,且只被包含在文件层。一般情况下,“moov”会紧随“ftyp”出现。
以下是读取下一个bax的大小和类型的代码:
1 2 3 4 5 6 7 it.read(buf) val  moovBoxSize = buf.toInt()Log.e("JIN" , "size = $moovBoxSize " ) it.read(buf) Log.e("JIN" , "type = ${buf.toCharString()} " ) 
 
然而类型却不是 moov 而是 free, 上面说了,一般情况下 ftype 后面是 moov。
那就跳过当前的box读取下一个box吧。
我又读取了下一个box, 这个 box 是 mdat, 看来,我要读取完整个文件来看看到底这个 mp4 文件有没有 moov 的 box 了。
重构了代码:
1 2 3 4 5 6 7 f.inputStream().also {     while  (it.available() > 0 ) {         val  box = Box(it, buf)         Log.e("JIN" , box.toString())     } } 
 
Box 对象的代码:
1 2 3 4 5 6 7 8 9 10 11 12 class  Box  (val  size: Int , val  type: String) {    constructor (inStream: InputStream, byterArray: ByteArray)             : this (inStream.read(byterArray).let { byterArray.toInt() },         inStream.read(byterArray).let { byterArray.toCharString() }) {         inStream.skip(size - 8L )     }     override  fun  toString ()  : String {         return  "$type : $size "      } } 
 
这里, 只读取了 size 和 type, 然后跳过了其他数据。
按照大端的方式转化4个字节为 Int 的方法:
1 2 3 4 5 6 7 fun  ByteArray.toInt ()  : Int  {    val  a = this [0 ].toUByte().toInt() * Math.pow(2.0 , 8.0  * 3 )     val  b = this [1 ].toUByte().toInt() * Math.pow(2.0 , 8.0  * 2 )     val  c = this [2 ].toUByte().toInt() * Math.pow(2.0 , 8.0 )     return  (this [3 ].toUByte().toInt() + a + b + c).toInt() } 
 
这里, 除了点问题, 每个字节,要转化成无符号数,再转成 Int, 之前没有转, 因为数小没出问题。
这样打印出了这个 mp4 的所有文件级别的 box:
ftyp: 32
free: 8
mdat: 11703979
moov: 16281这就有意思了,下一步该绘制 UI 了
明天: 每天一点点_音视频_MP4_视频数据BOX1