軟編碼Flv 到Mp4 容器(二) flv tag拆解

https://github.com/332065255/flv2fmp4

代碼庫


軟編碼Flv 到Mp4 容器(一)
軟編碼Flv 到Mp4 容器(二) flv tag拆解
軟編碼Flv 到Mp4 容器(三) flv metadata tag解析
軟編碼Flv 到Mp4 容器(四) fmp4 總覽和基礎講解
軟編碼Flv 到Mp4 容器(五) fmp4 ftyp box 和moov>mvhd box詳解
軟編碼Flv 到Mp4 容器(六) fmp4 moov>trak>tkhd box 和 moov>trak>mdia>mdhd box講解
軟編碼Flv 到Mp4 容器(七) fmp4 mdia>hdlr box 和 mdia>minf> smhd 和dinf box講解
軟編碼Flv 到Mp4 容器(八) fmp4 mdia>stbl>stsd box 講解
軟編碼Flv 到Mp4 容器(九) fmp4 stts stsc stsz stco box 講解
軟編碼Flv 到Mp4 容器(十) fmp4 mvex box 講解
軟編碼Flv 到Mp4 容器(十一) fmp4 moof box詳解
軟編碼Flv 到Mp4 容器(十二) fmp4 mdat box詳解
軟編碼Flv 到Mp4 容器(十三) fmp4 生成ftyp和moov所必要的 flv數據


接上篇文章,這章主要是對flv二進制數據進行tag拆解

首先接上章的入口類

import flvparse from './flv/flvParse'
window.flvParse = {
    setFlv: function(uint8) {
        flvparse.setFlv(uint8);
    },
    nextTag: function() {

    }
}

對外暴露出flvParse,外面的html拿到flv二進制數組後,扔給flvParse.js類

import tag from './flvTag.js'
class FlvParse {
    constructor() {
        this.tempUint8 = [];
        this.arrTag = [];
        this.index = 0;
        this.tempArr = [];
    }

    /**
     * 接受 外部的flv二進制數據
     */
    setFlv(uint8) {
        this.tempUint8 = uint8;
        this.parse();
    }

    /**
     * 開始解析
     */
    parse() {
        this.read(9); //略掉9個字節的flv header tag
        this.read(4); //略掉第一個4字節的 tag size
        while (this.index < this.tempUint8.length) {
            let t = new tag();
            t.tagType = (this.read(1)[0]); //取出tag類型
            t.dataSize = [].concat((this.read(3))); //取出包體大小
            t.Timestamp = [].concat(this.read(4)); //取出解碼時間
            t.StreamID = [].concat(this.read(3)); //取出stream id
            t.body = [].concat(this.read(this.getBodySum(t.dataSize))); //取出body
            this.arrTag.push(t);
            this.read(4);
        }
    }
    read(length) {
        this.tempArr.length = 0;
        for (let i = 0; i < length; i++) {
            this.tempArr.push(this.tempUint8[this.index]);
            this.index += 1;
        }
        return this.tempArr;
    }

    /**
     * 計算tag包體大小
     */
    getBodySum(arr) {
        let _str = "";
        _str += (arr[0].toString(16).length == 1 ? "0" + arr[0].toString(16) : arr[0].toString(16));
        _str += (arr[1].toString(16).length == 1 ? "0" + arr[1].toString(16) : arr[1].toString(16));
        _str += (arr[2].toString(16).length == 1 ? "0" + arr[2].toString(16) : arr[2].toString(16));
        return parseInt(_str, 16);
    }
}
export default new FlvParse();

flvTag.js類

export default class FlvTag {
    constructor() {
        this.tagType = -1;
        this.dataSize = -1;
        this.Timestamp = -1;
        this.StreamID = -1;
        this.body = -1;
    }
}

大體思路就是,拿掉開頭9個字節的flvheader tag
拿掉開頭4字節的tag size
剩下的就按照標準格式來讀取就好,這樣就能把一個flv 二進制數組分拆成一個個的tag,以備後用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章