123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /**
- * mux.js
- *
- * Copyright (c) Brightcove
- * Licensed Apache-2.0 https://github.com/videojs/mux.js/blob/master/LICENSE
- */
- 'use strict';
- var
- tagTypes = {
- 0x08: 'audio',
- 0x09: 'video',
- 0x12: 'metadata'
- },
- hex = function(val) {
- return '0x' + ('00' + val.toString(16)).slice(-2).toUpperCase();
- },
- hexStringList = function(data) {
- var arr = [], i;
- while (data.byteLength > 0) {
- i = 0;
- arr.push(hex(data[i++]));
- data = data.subarray(i);
- }
- return arr.join(' ');
- },
- parseAVCTag = function(tag, obj) {
- var
- avcPacketTypes = [
- 'AVC Sequence Header',
- 'AVC NALU',
- 'AVC End-of-Sequence'
- ],
- compositionTime = (tag[1] & parseInt('01111111', 2) << 16) | (tag[2] << 8) | tag[3];
- obj = obj || {};
- obj.avcPacketType = avcPacketTypes[tag[0]];
- obj.CompositionTime = (tag[1] & parseInt('10000000', 2)) ? -compositionTime : compositionTime;
- if (tag[0] === 1) {
- obj.nalUnitTypeRaw = hexStringList(tag.subarray(4, 100));
- } else {
- obj.data = hexStringList(tag.subarray(4));
- }
- return obj;
- },
- parseVideoTag = function(tag, obj) {
- var
- frameTypes = [
- 'Unknown',
- 'Keyframe (for AVC, a seekable frame)',
- 'Inter frame (for AVC, a nonseekable frame)',
- 'Disposable inter frame (H.263 only)',
- 'Generated keyframe (reserved for server use only)',
- 'Video info/command frame'
- ],
- codecID = tag[0] & parseInt('00001111', 2);
- obj = obj || {};
- obj.frameType = frameTypes[(tag[0] & parseInt('11110000', 2)) >>> 4];
- obj.codecID = codecID;
- if (codecID === 7) {
- return parseAVCTag(tag.subarray(1), obj);
- }
- return obj;
- },
- parseAACTag = function(tag, obj) {
- var packetTypes = [
- 'AAC Sequence Header',
- 'AAC Raw'
- ];
- obj = obj || {};
- obj.aacPacketType = packetTypes[tag[0]];
- obj.data = hexStringList(tag.subarray(1));
- return obj;
- },
- parseAudioTag = function(tag, obj) {
- var
- formatTable = [
- 'Linear PCM, platform endian',
- 'ADPCM',
- 'MP3',
- 'Linear PCM, little endian',
- 'Nellymoser 16-kHz mono',
- 'Nellymoser 8-kHz mono',
- 'Nellymoser',
- 'G.711 A-law logarithmic PCM',
- 'G.711 mu-law logarithmic PCM',
- 'reserved',
- 'AAC',
- 'Speex',
- 'MP3 8-Khz',
- 'Device-specific sound'
- ],
- samplingRateTable = [
- '5.5-kHz',
- '11-kHz',
- '22-kHz',
- '44-kHz'
- ],
- soundFormat = (tag[0] & parseInt('11110000', 2)) >>> 4;
- obj = obj || {};
- obj.soundFormat = formatTable[soundFormat];
- obj.soundRate = samplingRateTable[(tag[0] & parseInt('00001100', 2)) >>> 2];
- obj.soundSize = ((tag[0] & parseInt('00000010', 2)) >>> 1) ? '16-bit' : '8-bit';
- obj.soundType = (tag[0] & parseInt('00000001', 2)) ? 'Stereo' : 'Mono';
- if (soundFormat === 10) {
- return parseAACTag(tag.subarray(1), obj);
- }
- return obj;
- },
- parseGenericTag = function(tag) {
- return {
- tagType: tagTypes[tag[0]],
- dataSize: (tag[1] << 16) | (tag[2] << 8) | tag[3],
- timestamp: (tag[7] << 24) | (tag[4] << 16) | (tag[5] << 8) | tag[6],
- streamID: (tag[8] << 16) | (tag[9] << 8) | tag[10]
- };
- },
- inspectFlvTag = function(tag) {
- var header = parseGenericTag(tag);
- switch (tag[0]) {
- case 0x08:
- parseAudioTag(tag.subarray(11), header);
- break;
- case 0x09:
- parseVideoTag(tag.subarray(11), header);
- break;
- case 0x12:
- }
- return header;
- },
- inspectFlv = function(bytes) {
- var i = 9, // header
- dataSize,
- parsedResults = [],
- tag;
- // traverse the tags
- i += 4; // skip previous tag size
- while (i < bytes.byteLength) {
- dataSize = bytes[i + 1] << 16;
- dataSize |= bytes[i + 2] << 8;
- dataSize |= bytes[i + 3];
- dataSize += 11;
- tag = bytes.subarray(i, i + dataSize);
- parsedResults.push(inspectFlvTag(tag));
- i += dataSize + 4;
- }
- return parsedResults;
- },
- textifyFlv = function(flvTagArray) {
- return JSON.stringify(flvTagArray, null, 2);
- };
- module.exports = {
- inspectTag: inspectFlvTag,
- inspect: inspectFlv,
- textify: textifyFlv
- };
|