UNPKG

rx-player

Version:
369 lines (368 loc) 13.9 kB
"use strict"; /** * Copyright 2015 CANAL+ Group * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAVC1Box = createAVC1Box; exports.createAVCCBox = createAVCCBox; exports.createDREFBox = createDREFBox; exports.createENCABox = createENCABox; exports.createENCVBox = createENCVBox; exports.createESDSBox = createESDSBox; exports.createFRMABox = createFRMABox; exports.createFTYPBox = createFTYPBox; exports.createFreeBox = createFreeBox; exports.createHDLRBox = createHDLRBox; exports.createMDHDBox = createMDHDBox; exports.createMP4ABox = createMP4ABox; exports.createMVHDBox = createMVHDBox; exports.createSAIOBox = createSAIOBox; exports.createSAIZBox = createSAIZBox; exports.createSCHMBox = createSCHMBox; exports.createSMHDBox = createSMHDBox; exports.createSTSDBox = createSTSDBox; exports.createTENCBox = createTENCBox; exports.createTKHDBox = createTKHDBox; exports.createTREXBox = createTREXBox; exports.createTfdtBox = createTfdtBox; exports.createVMHDBox = createVMHDBox; var isobmff_1 = require("../../../parsers/containers/isobmff"); var byte_parsing_1 = require("../../../utils/byte_parsing"); var string_parsing_1 = require("../../../utils/string_parsing"); /** * @param {Number} width * @param {Number} height * @param {Number} hRes - horizontal resolution, eg 72 * @param {Number} vRes - vertical resolution, eg 72 * @param {string} encName * @param {Number} colorDepth - eg 24 * @param {Uint8Array} avcc - Uint8Array representing the avcC atom * @returns {Uint8Array} */ function createAVC1Box(width, height, hRes, vRes, encName, colorDepth, avcc) { return (0, isobmff_1.createBox)("avc1", (0, byte_parsing_1.concat)(6, // 6 bytes reserved (0, byte_parsing_1.itobe2)(1), 16, // drefIdx + QuickTime reserved, zeroes (0, byte_parsing_1.itobe2)(width), // size 2 w (0, byte_parsing_1.itobe2)(height), // size 2 h (0, byte_parsing_1.itobe2)(hRes), 2, // reso 4 h (0, byte_parsing_1.itobe2)(vRes), 2 + 4, // reso 4 v + QuickTime reserved, zeroes [0, 1, encName.length], // frame count (default 1) (0, string_parsing_1.strToUtf8)(encName), // 1byte len + encoder name str 31 - encName.length, // + padding (0, byte_parsing_1.itobe2)(colorDepth), // color depth [0xff, 0xff], // reserved ones avcc)); } /** * @param {Number} width * @param {Number} height * @param {Number} hRes - horizontal resolution, eg 72 * @param {Number} vRes - vertical resolution, eg 72 * @param {string} encName * @param {Number} colorDepth - eg 24 * @param {Uint8Array} avcc - Uint8Array representing the avcC atom * @param {Uint8Array} sinf - Uint8Array representing the sinf atom * @returns {Uint8Array} */ function createENCVBox(width, height, hRes, vRes, encName, colorDepth, avcc, sinf) { return (0, isobmff_1.createBox)("encv", (0, byte_parsing_1.concat)(6, // 6 bytes reserved (0, byte_parsing_1.itobe2)(1), 16, // drefIdx + QuickTime reserved, zeroes (0, byte_parsing_1.itobe2)(width), // size 2 w (0, byte_parsing_1.itobe2)(height), // size 2 h (0, byte_parsing_1.itobe2)(hRes), 2, // reso 4 h (0, byte_parsing_1.itobe2)(vRes), 2 + 4, // reso 4 v + QuickTime reserved, zeroes [0, 1, encName.length], // frame count (default 1) (0, string_parsing_1.strToUtf8)(encName), // 1byte len + encoder name str 31 - encName.length, // + padding (0, byte_parsing_1.itobe2)(colorDepth), // color depth [0xff, 0xff], // reserved ones avcc, // avcc atom, sinf)); } /** * @param {Number} drefIdx * @param {Number} channelsCount * @param {Number} sampleSize * @param {Number} packetSize * @param {Number} sampleRate * @param {Uint8Array} esds - Uint8Array representing the esds atom * @returns {Uint8Array} */ function createMP4ABox(drefIdx, channelsCount, sampleSize, packetSize, sampleRate, esds) { return (0, isobmff_1.createBox)("mp4a", (0, byte_parsing_1.concat)(6, (0, byte_parsing_1.itobe2)(drefIdx), 8, (0, byte_parsing_1.itobe2)(channelsCount), (0, byte_parsing_1.itobe2)(sampleSize), 2, (0, byte_parsing_1.itobe2)(packetSize), (0, byte_parsing_1.itobe2)(sampleRate), 2, esds)); } /** * @param {Number} drefIdx * @param {Number} channelsCount * @param {Number} sampleSize * @param {Number} packetSize * @param {Number} sampleRate * @param {Uint8Array} esds - Uint8Array representing the esds atom * @param {Uint8Array} [sinf] - Uint8Array representing the sinf atom, * only if name == "enca" * @returns {Uint8Array} */ function createENCABox(drefIdx, channelsCount, sampleSize, packetSize, sampleRate, esds, sinf) { return (0, isobmff_1.createBox)("enca", (0, byte_parsing_1.concat)(6, (0, byte_parsing_1.itobe2)(drefIdx), 8, (0, byte_parsing_1.itobe2)(channelsCount), (0, byte_parsing_1.itobe2)(sampleSize), 2, (0, byte_parsing_1.itobe2)(packetSize), (0, byte_parsing_1.itobe2)(sampleRate), 2, esds, sinf)); } /** * @param {Uint8Array} url * @returns {Uint8Array} */ function createDREFBox(url) { // only one description here... FIXME return (0, isobmff_1.createBox)("dref", (0, byte_parsing_1.concat)(7, [1], url)); } /** * @param {string} majorBrand * @param {Array.<string>} brands * @returns {Uint8Array} */ function createFTYPBox(majorBrand, brands) { var content = byte_parsing_1.concat.apply(void 0, __spreadArray([], __read([(0, string_parsing_1.strToUtf8)(majorBrand), [0, 0, 0, 1]].concat(brands.map(string_parsing_1.strToUtf8))), false)); return (0, isobmff_1.createBox)("ftyp", content); } /** * @param {string} schemeType - four letters (eg "cenc" for Common Encryption) * @param {Number} schemeVersion - eg 65536 * @returns {Uint8Array} */ function createSCHMBox(schemeType, schemeVersion) { return (0, isobmff_1.createBox)("schm", (0, byte_parsing_1.concat)(4, (0, string_parsing_1.strToUtf8)(schemeType), (0, byte_parsing_1.itobe4)(schemeVersion))); } /** * Create tfdt box from a decoding time. * @param {number} decodeTime * @returns {Uint8Array} */ function createTfdtBox(decodeTime) { return (0, isobmff_1.createBox)("tfdt", (0, byte_parsing_1.concat)([1, 0, 0, 0], (0, byte_parsing_1.itobe8)(decodeTime))); } /** * @returns {Uint8Array} */ function createVMHDBox() { var arr = new Uint8Array(12); arr[3] = 1; // QuickTime... return (0, isobmff_1.createBox)("vmhd", arr); } /** * @param {Number} trackId * @returns {Uint8Array} */ function createTREXBox(trackId) { // default sample desc idx = 1 return (0, isobmff_1.createBox)("trex", (0, byte_parsing_1.concat)(4, (0, byte_parsing_1.itobe4)(trackId), [0, 0, 0, 1], 12)); } /** * @param {Number} length * @returns {Uint8Array} */ function createFreeBox(length) { return (0, isobmff_1.createBox)("free", new Uint8Array(length - 8)); } /** * @param {Number} stream * @param {string} codecPrivateData - hex string * @returns {Uint8Array} */ function createESDSBox(stream, codecPrivateData) { return (0, isobmff_1.createBox)("esds", (0, byte_parsing_1.concat)(4, [0x03, 0x19], (0, byte_parsing_1.itobe2)(stream), [0x00, 0x04, 0x11, 0x40, 0x15], 11, [0x05, 0x02], (0, string_parsing_1.hexToBytes)(codecPrivateData), [0x06, 0x01, 0x02])); } /** * @param {string} dataFormat - four letters (eg "avc1") * @returns {Uint8Array} */ function createFRMABox(dataFormat) { return (0, isobmff_1.createBox)("frma", (0, string_parsing_1.strToUtf8)(dataFormat)); } /** * @param {Uint8Array} sps * @param {Uint8Array} pps * @param {Number} nalLen - NAL Unit length: 1, 2 or 4 bytes * eg: avcc(0x4d, 0x40, 0x0d, 4, 0xe1, "674d400d96560c0efcb80a70505050a0", * 1, "68ef3880") * @returns {Uint8Array} */ function createAVCCBox(sps, pps, nalLen) { var nal; if (nalLen === 2) { nal = 0x1; } else if (nalLen === 4) { nal = 0x3; } else { nal = 0x0; } // Deduce AVC Profile from SPS var h264Profile = sps[1]; var h264CompatibleProfile = sps[2]; var h264Level = sps[3]; return (0, isobmff_1.createBox)("avcC", (0, byte_parsing_1.concat)([1, h264Profile, h264CompatibleProfile, h264Level, (0x3f << 2) | nal, 0xe0 | 1], (0, byte_parsing_1.itobe2)(sps.length), sps, [1], (0, byte_parsing_1.itobe2)(pps.length), pps)); } /** * @param {string} type - "video"/"audio"/"hint" * @returns {Uint8Array} */ function createHDLRBox(type) { var name; var handlerName; switch (type) { case "video": name = "vide"; handlerName = "VideoHandler"; break; case "audio": name = "soun"; handlerName = "SoundHandler"; break; default: name = "hint"; handlerName = ""; break; } return (0, isobmff_1.createBox)("hdlr", (0, byte_parsing_1.concat)(8, (0, string_parsing_1.strToUtf8)(name), 12, (0, string_parsing_1.strToUtf8)(handlerName), 1)); } /** * @param {number} timescale * @returns {Uint8Array} */ function createMDHDBox(timescale) { return (0, isobmff_1.createBox)("mdhd", (0, byte_parsing_1.concat)(12, (0, byte_parsing_1.itobe4)(timescale), 8)); } /** * @param {Number} timescale * @param {Number} trackId * @returns {Uint8Array} */ function createMVHDBox(timescale, trackId) { return (0, isobmff_1.createBox)("mvhd", (0, byte_parsing_1.concat)(12, (0, byte_parsing_1.itobe4)(timescale), 4, [0, 1], 2, // we assume rate = 1; [1, 0], 10, // we assume volume = 100%; [0, 1], 14, // default matrix [0, 1], 14, // default matrix [64, 0, 0, 0], 26, (0, byte_parsing_1.itobe2)(trackId + 1))); } /** * @param {Uint8Array} mfhd * @param {Uint8Array} tfhd * @param {Uint8Array} tfdt * @param {Uint8Array} trun * @returns {Uint8Array} */ function createSAIOBox(mfhd, tfhd, tfdt, trun) { return (0, isobmff_1.createBox)("saio", (0, byte_parsing_1.concat)(4, [0, 0, 0, 1], // ?? (0, byte_parsing_1.itobe4)(mfhd.length + tfhd.length + tfdt.length + trun.length + 8 + 8 + 8 + 8))); } /** * @param {Uint8Array} sencContent - including 8 bytes flags and entries count * @returns {Uint8Array} */ function createSAIZBox(sencContent) { if (sencContent.length === 0) { return (0, isobmff_1.createBox)("saiz", new Uint8Array(0)); } var flags = (0, byte_parsing_1.be4toi)(sencContent, 0); var entries = (0, byte_parsing_1.be4toi)(sencContent, 4); var arr = new Uint8Array(entries + 9); arr.set((0, byte_parsing_1.itobe4)(entries), 5); var i = 9; var j = 8; var pairsCnt; var pairsLen; while (j < sencContent.length) { j += 8; // assuming IV is 8 bytes TODO handle 16 bytes IV // if we have extradata for each entry if ((flags & 0x2) === 0x2) { pairsLen = 2; pairsCnt = (0, byte_parsing_1.be2toi)(sencContent, j); j += pairsCnt * 6 + 2; } else { pairsCnt = 0; pairsLen = 0; } arr[i] = pairsCnt * 6 + 8 + pairsLen; i++; } return (0, isobmff_1.createBox)("saiz", arr); } /** * @returns {Uint8Array} */ function createSMHDBox() { return (0, isobmff_1.createBox)("smhd", new Uint8Array(8)); } /** * @param {Array.<Uint8Array>} reps - arrays of Uint8Array, * typically [avc1] or [encv, avc1] * @returns {Uint8Array} */ function createSTSDBox(reps) { // only one description here... FIXME var arrBase = [7, [reps.length]]; return (0, isobmff_1.createBox)("stsd", byte_parsing_1.concat.apply(void 0, __spreadArray([], __read(arrBase.concat(reps)), false))); } /** * @param {Number} width * @param {Number} height * @param {Number} trackId * @returns {Uint8Array} */ function createTKHDBox(width, height, trackId) { return (0, isobmff_1.createBox)("tkhd", (0, byte_parsing_1.concat)((0, byte_parsing_1.itobe4)(1 + 2 + 4), 8, // we assume track is enabled, // in media and in preview. (0, byte_parsing_1.itobe4)(trackId), 20, // we assume trackId = 1; [1, 0, 0, 0], // we assume volume = 100%; [0, 1, 0, 0], 12, // default matrix [0, 1, 0, 0], 12, // default matrix [64, 0, 0, 0], // ?? (0, byte_parsing_1.itobe2)(width), 2, // width (TODO handle fixed) (0, byte_parsing_1.itobe2)(height), 2)); } /** * @param {Number} algId - eg 1 * @param {Number} ivSize - eg 8 * @param {string} keyId - Hex KID 93789920e8d6520098577df8f2dd5546 * @returns {Uint8Array} */ function createTENCBox(algId, ivSize, keyId) { return (0, isobmff_1.createBox)("tenc", (0, byte_parsing_1.concat)(6, [algId, ivSize], keyId)); }