UNPKG

kontainer-js

Version:

A media file format generator/parser that exposes a React-like API.

402 lines (305 loc) 12 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = undefined; var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _get2 = require('babel-runtime/helpers/get'); var _get3 = _interopRequireDefault(_get2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); var _Element2 = require('./Element'); var _Element3 = _interopRequireDefault(_Element2); var _Buffer = require('../../core/Buffer'); var _Buffer2 = _interopRequireDefault(_Buffer); var _Reader = require('../../core/Reader'); var _Reader2 = _interopRequireDefault(_Reader); var _Writer = require('../../core/Writer'); var _Writer2 = _interopRequireDefault(_Writer); var _Util = require('../../core/Util'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function decodeFlags(flags) { return { keyframe: !!(flags & 0x80), invisible: !!(flags & 0x08), lacing: flags >> 1 & 0x03, discardable: !!(flags & 0x01) }; } function encodeFlags(flags) { var byte = 0; if (flags.keyframe) { byte |= 0x80; } if (flags.invisible) { byte |= 0x08; } byte |= TypeBlock.LACING_EBML << 1; if (flags.discardable) { byte |= 0x01; } return byte; } function getEBMLFrameSizeCode(byteLength) { switch (byteLength) { case 1: return 63; case 2: return 8191; case 3: return 1048575; case 4: return 134217727; case 5: return 17179869183; case 6: return 2199023255551; case 7: return 281474976710655; } } function readEBMLFrameSize(buffer, offset, signed) { var msb = buffer[offset]; for (var i = 1; i <= 7; i++) { if (msb >>> 8 - i & 0x01) { // search the most left 1 bit buffer[offset] &= 0xFF >>> i; // drop left i bits var readBytesNum = void 0, frameSize = void 0; if (signed) { var _Reader$readNumber = _Reader2.default.readNumber(buffer, offset, i, true); var _Reader$readNumber2 = (0, _slicedToArray3.default)(_Reader$readNumber, 2); readBytesNum = _Reader$readNumber2[0]; frameSize = _Reader$readNumber2[1]; frameSize -= getEBMLFrameSizeCode(i); } else { var _Reader$readNumber3 = _Reader2.default.readNumber(buffer, offset, i, false); var _Reader$readNumber4 = (0, _slicedToArray3.default)(_Reader$readNumber3, 2); readBytesNum = _Reader$readNumber4[0]; frameSize = _Reader$readNumber4[1]; } buffer[offset] = msb; // restore return [readBytesNum, frameSize]; } } (0, _Util.throwException)('Invalid EBML frame size'); } function writeEBMLFrameSize(size, buffer, offset, sizeLen, signed) { if (signed) { size += getEBMLFrameSizeCode(sizeLen); } var writtenBytesNum = _Writer2.default.writeNumber(size, buffer, offset, sizeLen); if (buffer) { buffer[offset] &= 0xFF >>> sizeLen; // drop left sizeLen bits buffer[offset] |= 0x01 << 8 - sizeLen; // set the most left bit to 1 } return writtenBytesNum; } function getNecessaryBytesNumForEBMLFrameSize(value) { var bytesNum = 0; if (value >= -63 && value <= 63) { bytesNum = 1; } else if (value >= -8191 && value <= 8191) { bytesNum = 2; } else if (value >= -1048575 && value <= 1048575) { bytesNum = 3; } else if (value >= -134217727 && value <= 134217727) { bytesNum = 4; } else if (value >= -17179869183 && value <= 17179869183) { bytesNum = 5; } else if (value >= -2199023255551 && value <= 2199023255551) { bytesNum = 6; } else if (value >= -281474976710655 && value <= 281474976710655) { bytesNum = 7; } else { (0, _Util.throwException)('Matroska.TypeBlock.serialize(' + value + '): largesize(>=2^53) is not supported.'); } return bytesNum; } function readFrameSizeList(buffer, offset, length, lacing, numberOfFramesInLace) { var base = offset; if (lacing === TypeBlock.LACING_NONE) { return [0, []]; } else if (lacing === TypeBlock.LACING_FIXED_SIZE) { return [0, new Array(numberOfFramesInLace).fill(Math.floor(length / numberOfFramesInLace))]; } var frameSizeList = []; var tempSize = 0; for (var i = 0; i < numberOfFramesInLace; i++) { if (i !== 0 && i === numberOfFramesInLace - 1) { break; } if (lacing === TypeBlock.LACING_XIPH) { var byte = buffer[base++]; tempSize += byte; if (byte !== 255) { frameSizeList.push(tempSize); tempSize = 0; } } else if (lacing === TypeBlock.LACING_EBML) { var _readEBMLFrameSize = readEBMLFrameSize(buffer, base, i > 0); var _readEBMLFrameSize2 = (0, _slicedToArray3.default)(_readEBMLFrameSize, 2); var readBytesNum = _readEBMLFrameSize2[0]; var frameSize = _readEBMLFrameSize2[1]; if (i === 0) { frameSizeList.push(frameSize); } else { frameSizeList.push(frameSizeList[i - 1] + frameSize); } base += readBytesNum; } } var theLastFrameSize = offset + length - base - frameSizeList.reduce(function (a, b) { return a + b; }, 0); if (theLastFrameSize > 0) { frameSizeList.push(theLastFrameSize); } return [base - offset, frameSizeList]; } var TypeBlock = function (_Element) { (0, _inherits3.default)(TypeBlock, _Element); function TypeBlock() { var _Object$getPrototypeO; (0, _classCallCheck3.default)(this, TypeBlock); for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) { params[_key] = arguments[_key]; } return (0, _possibleConstructorReturn3.default)(this, (_Object$getPrototypeO = (0, _getPrototypeOf2.default)(TypeBlock)).call.apply(_Object$getPrototypeO, [this].concat(params))); } (0, _createClass3.default)(TypeBlock, [{ key: 'serialize', value: function serialize(buffer) { var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; var props = this.props; var trackNumber = props.trackNumber; var timecode = props.timecode; var flags = props.flags; var frames = props.frames; var trackNumberLength = _Element3.default.getNecessaryBytesNumForSize(trackNumber); var frameSizeList = []; var frameSizeLengthList = []; var frameLength = 0; for (var i = 0; i < frames.length; i++) { var len = frames[i].length; if (i === 0) { frameSizeList.push(len); frameSizeLengthList.push(getNecessaryBytesNumForEBMLFrameSize(len)); } else if (i < frames.length - 1) { var diff = len - frames[i - 1].length; frameSizeList.push(diff); frameSizeLengthList.push(getNecessaryBytesNumForEBMLFrameSize(diff)); } frameLength += len; } var totalSize = trackNumberLength + 2 // timecode + 1 // flags + 1 // numberOfFramesInLaceMinusOne + frameSizeLengthList.reduce(function (a, b) { return a + b; }, 0) + frameLength; var base = offset; (0, _get3.default)((0, _getPrototypeOf2.default)(TypeBlock.prototype), 'setElementSize', this).call(this, totalSize); base += (0, _get3.default)((0, _getPrototypeOf2.default)(TypeBlock.prototype), 'serialize', this).call(this, buffer, base); base += _Element3.default.writeElementSize(trackNumber, buffer, base, trackNumberLength); base += _Writer2.default.writeNumber(timecode, buffer, base, 2); base += _Writer2.default.writeNumber(encodeFlags(flags), buffer, base, 1); base += _Writer2.default.writeNumber(frames.length - 1, buffer, base, 1); for (var _i = 0; _i < frames.length; _i++) { if (_i === 0 || _i < frames.length - 1) { base += writeEBMLFrameSize(frameSizeList[_i], buffer, base, frameSizeLengthList[_i], _i > 0); } } if (buffer) { var tempBase = base; for (var _i2 = 0; _i2 < frames.length; _i2++) { var frame = frames[_i2]; _Buffer2.default.wrap(buffer).copyFrom(frame, 0, frame.length, tempBase); tempBase += frame.length; } } base += frameLength; return this.size; } }], [{ key: 'parse', value: function parse(buffer) { var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; var base = offset, readBytesNum = void 0, props = void 0, trackNumber = void 0, timecode = void 0, flags = void 0, numberOfFramesInLaceMinusOne = void 0, frameSizeList = void 0; var _Element$parse = _Element3.default.parse(buffer, base); var _Element$parse2 = (0, _slicedToArray3.default)(_Element$parse, 2); readBytesNum = _Element$parse2[0]; props = _Element$parse2[1]; base += readBytesNum; _Reader2.default.ASSERT(buffer, base, props.size); var endOfElement = base + props.size; var _Element$readElementS = _Element3.default.readElementSize(buffer, base); var _Element$readElementS2 = (0, _slicedToArray3.default)(_Element$readElementS, 2); readBytesNum = _Element$readElementS2[0]; trackNumber = _Element$readElementS2[1]; base += readBytesNum; var _Reader$readNumber5 = _Reader2.default.readNumber(buffer, base, 2, true); var _Reader$readNumber6 = (0, _slicedToArray3.default)(_Reader$readNumber5, 2); readBytesNum = _Reader$readNumber6[0]; timecode = _Reader$readNumber6[1]; base += readBytesNum; flags = buffer[base++]; var _decodeFlags = decodeFlags(flags); var keyframe = _decodeFlags.keyframe; var invisible = _decodeFlags.invisible; var lacing = _decodeFlags.lacing; var discardable = _decodeFlags.discardable; if (lacing === TypeBlock.LACING_NONE) { frameSizeList = []; var frameSize = endOfElement - base; if (frameSize > 0) { frameSizeList.push(frameSize); } } else { var _Reader$readNumber7 = _Reader2.default.readNumber(buffer, base, 1); var _Reader$readNumber8 = (0, _slicedToArray3.default)(_Reader$readNumber7, 2); readBytesNum = _Reader$readNumber8[0]; numberOfFramesInLaceMinusOne = _Reader$readNumber8[1]; base += readBytesNum; var _readFrameSizeList = readFrameSizeList(buffer, base, endOfElement - base, lacing, numberOfFramesInLaceMinusOne + 1); var _readFrameSizeList2 = (0, _slicedToArray3.default)(_readFrameSizeList, 2); readBytesNum = _readFrameSizeList2[0]; frameSizeList = _readFrameSizeList2[1]; base += readBytesNum; } var frames = []; frameSizeList.forEach(function (frameSize) { var buf = _Buffer2.default.wrap(buffer).copy(base, frameSize); base += frameSize; frames.push(buf.getView()); }); props.trackNumber = trackNumber; props.timecode = timecode; props.flags = { keyframe: keyframe, invisible: invisible, discardable: discardable }; props.frames = frames; return [base - offset, props]; } }]); return TypeBlock; }(_Element3.default); exports.default = TypeBlock; TypeBlock.LACING_NONE = 0; TypeBlock.LACING_XIPH = 1; TypeBlock.LACING_EBML = 3; TypeBlock.LACING_FIXED_SIZE = 2;