kontainer-js
Version:
A media file format generator/parser that exposes a React-like API.
287 lines (227 loc) • 8.15 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
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 _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _Component2 = require('../../core/Component');
var _Component3 = _interopRequireDefault(_Component2);
var _Writer = require('../../core/Writer');
var _Writer2 = _interopRequireDefault(_Writer);
var _Reader = require('../../core/Reader');
var _Reader2 = _interopRequireDefault(_Reader);
var _Util = require('../../core/Util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getElementIdLength(buffer, offset) {
var firstByte = buffer[offset];
for (var i = 1; i < 5; i++) {
if (firstByte >>> 8 - i & 0x01) {
return i;
}
}
(0, _Util.throwException)('Invalid Element id');
}
function writeMaskedSize(size, buffer, offset, sizeLen, len) {
var msb = size >>> (len - 1) * 8;
msb &= 0xFF >>> sizeLen;
msb |= 0x01 << 8 - sizeLen;
var maskedSize = 0;
for (var i = 1; i <= len; i++) {
if (i === 1) {
maskedSize = msb;
} else {
maskedSize <<= 8;
maskedSize |= size >>> (len - i) * 8 & 0xFF;
}
}
return _Writer2.default.writeNumber(maskedSize, buffer, offset, len);
}
function checkUnknownSize(buffer, offset, length) {
for (var i = 0; i < length; i++) {
var byte = buffer[offset + i];
if (i === 0) {
if (byte !== (~(0xFF << 8 - length) & 0xFF)) {
return false;
}
} else {
if (byte !== 0xFF) {
return false;
}
}
}
return true;
}
var Element = function (_Component) {
(0, _inherits3.default)(Element, _Component);
function Element(id, name, props) {
(0, _classCallCheck3.default)(this, Element);
var _this = (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(Element).call(this, name, props));
_this.id = id;
_this.size = 0;
_this.sizeLen = props.initialSizeLen || 0;
return _this;
}
(0, _createClass3.default)(Element, [{
key: 'serialize',
value: function serialize(buffer) {
var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
//console.log(`--- Element.serialize enter. type=${this.type}`);
var elementId = this.id;
var base = offset;
var writtenBytesNum = void 0;
if (buffer) {
for (var i = 0; i < elementId.length; i++) {
buffer[base + i] = elementId[i];
}
}
base += elementId.length;
var sizeLen = this.sizeLen;
var size = this.size - elementId.length - sizeLen;
base += Element.writeElementSize(size, buffer, base, sizeLen);
//console.log(`--- Element.serialize exit. type=${this.type}, size=${base - offset}`);
return base - offset;
}
}, {
key: 'getSize',
value: function getSize() {
return this.size;
}
}, {
key: 'setSize',
value: function setSize(size) {
if (this.size === 0) {
// For master elements.
this.size = size;
}
}
}, {
key: 'setElementSize',
value: function setElementSize(size) {
this.sizeLen = Element.getNecessaryBytesNumForSize(size);
this.size = size + this.id.length + this.sizeLen;
}
// Parses buffer and returns props.
}], [{
key: 'readElementId',
value: function readElementId(buffer, offset) {
var len = getElementIdLength(buffer, offset);
_Reader2.default.ASSERT(buffer, offset, len);
var elementId = [];
for (var i = 0; i < len; i++) {
elementId.push(buffer[offset + i]);
}
return [len, elementId];
}
}, {
key: 'readElementSize',
value: function readElementSize(buffer, offset) {
var msb = buffer[offset];
for (var i = 1; i <= 8; i++) {
if (msb >>> 8 - i & 0x01) {
// search the most left 1 bit
_Reader2.default.ASSERT(buffer, offset, i);
buffer[offset] &= 0xFF >>> i; // drop left i bits
if (checkUnknownSize(buffer, offset, i)) {
// the size is encoded to all 1's, which indicates that the size of the Element is unknown
buffer[offset] = msb; // restore
return [i, -1];
}
var _Reader$readNumber = _Reader2.default.readNumber(buffer, offset, i);
var _Reader$readNumber2 = (0, _slicedToArray3.default)(_Reader$readNumber, 2);
var readBytesNum = _Reader$readNumber2[0];
var size = _Reader$readNumber2[1];
buffer[offset] = msb; // restore
return [readBytesNum, size];
}
}
(0, _Util.throwException)('Invalid Element size');
}
}, {
key: 'writeElementSize',
value: function writeElementSize(size, buffer, offset, sizeLen) {
var base = offset;
if (sizeLen > 4) {
var left = size / 4294967296;
var right = size % 4294967296;
base += writeMaskedSize(left, buffer, base, sizeLen, sizeLen - 4);
base += _Writer2.default.writeNumber(right, buffer, base, 4);
} else {
base += writeMaskedSize(size, buffer, base, sizeLen, sizeLen);
}
return base - offset;
}
}, {
key: 'getNecessaryBytesNumForSize',
value: function getNecessaryBytesNumForSize(value) {
var bytesNum = 0;
if (value < (1 << 7) - 1) {
bytesNum = 1;
} else if (value < (1 << 14) - 1) {
bytesNum = 2;
} else if (value < (1 << 21) - 1) {
bytesNum = 3;
} else if (value < (1 << 28) - 1) {
bytesNum = 4;
} else if (value < (1 << 35) - 1) {
bytesNum = 5;
} else if (value < (1 << 42) - 1) {
bytesNum = 6;
} else if (value < (1 << 49) - 1) {
bytesNum = 7;
} else if (value <= Math.MAX_SAFE_INTEGER) {
bytesNum = 8;
} else {
(0, _Util.throwException)('Matroska.Element.serialize(' + value + '): largesize(>=2^53) is not supported.');
}
return bytesNum;
}
}, {
key: 'parse',
value: function parse(buffer) {
var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
var size = void 0;
var elementId = void 0;
var base = offset;
var readBytesNum = void 0;
var _Element$readElementI = Element.readElementId(buffer, base);
var _Element$readElementI2 = (0, _slicedToArray3.default)(_Element$readElementI, 2);
readBytesNum = _Element$readElementI2[0];
elementId = _Element$readElementI2[1];
base += readBytesNum;
var _Element$readElementS = Element.readElementSize(buffer, base);
var _Element$readElementS2 = (0, _slicedToArray3.default)(_Element$readElementS, 2);
readBytesNum = _Element$readElementS2[0];
size = _Element$readElementS2[1];
base += readBytesNum;
return [base - offset, {
size: size,
elementId: elementId
}];
}
}, {
key: 'getMimeType',
value: function getMimeType(element) {
var results = element.querySelectorAll('TrackType');
var audioOnly = results.every(function (trackType) {
return trackType.props.kind === 'audio';
});
if (audioOnly) {
return 'audio/webm';
}
return 'video/webm';
}
}]);
return Element;
}(_Component3.default);
exports.default = Element;