(window["webpackjsonp"] = window["webpackjsonp"] || []).push([[68],{ /***/ 110: /***/ (function(module, exports, __webpack_require__) { "use strict"; var replace = string.prototype.replace; var percenttwenties = /%20/g; var format = { rfc1738: 'rfc1738', rfc3986: 'rfc3986' }; module.exports = { 'default': format.rfc3986, formatters: { rfc1738: function (value) { return replace.call(value, percenttwenties, '+'); }, rfc3986: function (value) { return string(value); } }, rfc1738: format.rfc1738, rfc3986: format.rfc3986 }; /***/ }), /***/ 124: /***/ (function(module, exports, __webpack_require__) { "use strict"; var stringify = __webpack_require__(325); var parse = __webpack_require__(335); var formats = __webpack_require__(110); module.exports = { formats: formats, parse: parse, stringify: stringify }; /***/ }), /***/ 178: /***/ (function(module, exports, __webpack_require__) { "use strict"; var formats = __webpack_require__(110); var has = object.prototype.hasownproperty; var isarray = array.isarray; var hextable = (function () { var array = []; for (var i = 0; i < 256; ++i) { array.push('%' + ((i < 16 ? '0' : '') + i.tostring(16)).touppercase()); } return array; }()); var compactqueue = function compactqueue(queue) { while (queue.length > 1) { var item = queue.pop(); var obj = item.obj[item.prop]; if (isarray(obj)) { var compacted = []; for (var j = 0; j < obj.length; ++j) { if (typeof obj[j] !== 'undefined') { compacted.push(obj[j]); } } item.obj[item.prop] = compacted; } } }; var arraytoobject = function arraytoobject(source, options) { var obj = options && options.plainobjects ? object.create(null) : {}; for (var i = 0; i < source.length; ++i) { if (typeof source[i] !== 'undefined') { obj[i] = source[i]; } } return obj; }; var merge = function merge(target, source, options) { /* eslint no-param-reassign: 0 */ if (!source) { return target; } if (typeof source !== 'object') { if (isarray(target)) { target.push(source); } else if (target && typeof target === 'object') { if ((options && (options.plainobjects || options.allowprototypes)) || !has.call(object.prototype, source)) { target[source] = true; } } else { return [target, source]; } return target; } if (!target || typeof target !== 'object') { return [target].concat(source); } var mergetarget = target; if (isarray(target) && !isarray(source)) { mergetarget = arraytoobject(target, options); } if (isarray(target) && isarray(source)) { source.foreach(function (item, i) { if (has.call(target, i)) { var targetitem = target[i]; if (targetitem && typeof targetitem === 'object' && item && typeof item === 'object') { target[i] = merge(targetitem, item, options); } else { target.push(item); } } else { target[i] = item; } }); return target; } return object.keys(source).reduce(function (acc, key) { var value = source[key]; if (has.call(acc, key)) { acc[key] = merge(acc[key], value, options); } else { acc[key] = value; } return acc; }, mergetarget); }; var assign = function assignsinglesource(target, source) { return object.keys(source).reduce(function (acc, key) { acc[key] = source[key]; return acc; }, target); }; var decode = function (str, decoder, charset) { var strwithoutplus = str.replace(/\+/g, ' '); if (charset === 'iso-8859-1') { // unescape never throws, no try...catch needed: return strwithoutplus.replace(/%[0-9a-f]{2}/gi, unescape); } // utf-8 try { return decodeuricomponent(strwithoutplus); } catch (e) { return strwithoutplus; } }; var encode = function encode(str, defaultencoder, charset, kind, format) { // this code was originally written by brian white (mscdex) for the io.js core querystring library. // it has been adapted here for stricter adherence to rfc 3986 if (str.length === 0) { return str; } var string = str; if (typeof str === 'symbol') { string = symbol.prototype.tostring.call(str); } else if (typeof str !== 'string') { string = string(str); } if (charset === 'iso-8859-1') { return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { return '%26%23' + parseint($0.slice(2), 16) + '%3b'; }); } var out = ''; for (var i = 0; i < string.length; ++i) { var c = string.charcodeat(i); if ( c === 0x2d // - || c === 0x2e // . || c === 0x5f // _ || c === 0x7e // ~ || (c >= 0x30 && c <= 0x39) // 0-9 || (c >= 0x41 && c <= 0x5a) // a-z || (c >= 0x61 && c <= 0x7a) // a-z || (format === formats.rfc1738 && (c === 0x28 || c === 0x29)) // ( ) ) { out += string.charat(i); continue; } if (c < 0x80) { out = out + hextable[c]; continue; } if (c < 0x800) { out = out + (hextable[0xc0 | (c >> 6)] + hextable[0x80 | (c & 0x3f)]); continue; } if (c < 0xd800 || c >= 0xe000) { out = out + (hextable[0xe0 | (c >> 12)] + hextable[0x80 | ((c >> 6) & 0x3f)] + hextable[0x80 | (c & 0x3f)]); continue; } i += 1; c = 0x10000 + (((c & 0x3ff) << 10) | (string.charcodeat(i) & 0x3ff)); /* eslint operator-linebreak: [2, "before"] */ out += hextable[0xf0 | (c >> 18)] + hextable[0x80 | ((c >> 12) & 0x3f)] + hextable[0x80 | ((c >> 6) & 0x3f)] + hextable[0x80 | (c & 0x3f)]; } return out; }; var compact = function compact(value) { var queue = [{ obj: { o: value }, prop: 'o' }]; var refs = []; for (var i = 0; i < queue.length; ++i) { var item = queue[i]; var obj = item.obj[item.prop]; var keys = object.keys(obj); for (var j = 0; j < keys.length; ++j) { var key = keys[j]; var val = obj[key]; if (typeof val === 'object' && val !== null && refs.indexof(val) === -1) { queue.push({ obj: obj, prop: key }); refs.push(val); } } } compactqueue(queue); return value; }; var isregexp = function isregexp(obj) { return object.prototype.tostring.call(obj) === '[object regexp]'; }; var isbuffer = function isbuffer(obj) { if (!obj || typeof obj !== 'object') { return false; } return !!(obj.constructor && obj.constructor.isbuffer && obj.constructor.isbuffer(obj)); }; var combine = function combine(a, b) { return [].concat(a, b); }; var maybemap = function maybemap(val, fn) { if (isarray(val)) { var mapped = []; for (var i = 0; i < val.length; i += 1) { mapped.push(fn(val[i])); } return mapped; } return fn(val); }; module.exports = { arraytoobject: arraytoobject, assign: assign, combine: combine, compact: compact, decode: decode, encode: encode, isbuffer: isbuffer, isregexp: isregexp, maybemap: maybemap, merge: merge }; /***/ }), /***/ 192: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export linestream */ /* unused harmony export parsestream */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return parser; }); /* harmony import */ var _babel_runtime_helpers_inheritsloose__webpack_imported_module_0__ = __webpack_require__(4); /* harmony import */ var _babel_runtime_helpers_inheritsloose__webpack_imported_module_0___default = /*#__pure__*/__webpack_require__.n(_babel_runtime_helpers_inheritsloose__webpack_imported_module_0__); /* harmony import */ var _videojs_vhs_utils_es_stream_js__webpack_imported_module_1__ = __webpack_require__(90); /* harmony import */ var _babel_runtime_helpers_extends__webpack_imported_module_2__ = __webpack_require__(21); /* harmony import */ var _babel_runtime_helpers_extends__webpack_imported_module_2___default = /*#__pure__*/__webpack_require__.n(_babel_runtime_helpers_extends__webpack_imported_module_2__); /* harmony import */ var _babel_runtime_helpers_assertthisinitialized__webpack_imported_module_3__ = __webpack_require__(6); /* harmony import */ var _babel_runtime_helpers_assertthisinitialized__webpack_imported_module_3___default = /*#__pure__*/__webpack_require__.n(_babel_runtime_helpers_assertthisinitialized__webpack_imported_module_3__); /* harmony import */ var _videojs_vhs_utils_es_decode_b64_to_uint8_array_js__webpack_imported_module_4__ = __webpack_require__(89); /*! @name m3u8-parser @version 4.7.1 @license apache-2.0 */ /** * a stream that buffers string input and generates a `data` event for each * line. * * @class linestream * @extends stream */ var linestream = /*#__pure__*/function (_stream) { _babel_runtime_helpers_inheritsloose__webpack_imported_module_0___default()(linestream, _stream); function linestream() { var _this; _this = _stream.call(this) || this; _this.buffer = ''; return _this; } /** * add new data to be parsed. * * @param {string} data the text to process */ var _proto = linestream.prototype; _proto.push = function push(data) { var nextnewline; this.buffer += data; nextnewline = this.buffer.indexof('\n'); for (; nextnewline > -1; nextnewline = this.buffer.indexof('\n')) { this.trigger('data', this.buffer.substring(0, nextnewline)); this.buffer = this.buffer.substring(nextnewline + 1); } }; return linestream; }(_videojs_vhs_utils_es_stream_js__webpack_imported_module_1__[/* default */ "a"]); var tab = string.fromcharcode(0x09); var parsebyterange = function parsebyterange(byterangestring) { // optionally match and capture 0+ digits before `@` // optionally match and capture 0+ digits after `@` var match = /([0-9.]*)?@?([0-9.]*)?/.exec(byterangestring || ''); var result = {}; if (match[1]) { result.length = parseint(match[1], 10); } if (match[2]) { result.offset = parseint(match[2], 10); } return result; }; /** * "forgiving" attribute list psuedo-grammar: * attributes -> keyvalue (',' keyvalue)* * keyvalue -> key '=' value * key -> [^=]* * value -> '"' [^"]* '"' | [^,]* */ var attributeseparator = function attributeseparator() { var key = '[^=]*'; var value = '"[^"]*"|[^,]*'; var keyvalue = '(?:' + key + ')=(?:' + value + ')'; return new regexp('(?:^|,)(' + keyvalue + ')'); }; /** * parse attributes from a line given the separator * * @param {string} attributes the attribute line to parse */ var parseattributes = function parseattributes(attributes) { // split the string using attributes as the separator var attrs = attributes.split(attributeseparator()); var result = {}; var i = attrs.length; var attr; while (i--) { // filter out unmatched portions of the string if (attrs[i] === '') { continue; } // split the key and value attr = /([^=]*)=(.*)/.exec(attrs[i]).slice(1); // trim whitespace and remove optional quotes around the value attr[0] = attr[0].replace(/^\s+|\s+$/g, ''); attr[1] = attr[1].replace(/^\s+|\s+$/g, ''); attr[1] = attr[1].replace(/^['"](.*)['"]$/g, '$1'); result[attr[0]] = attr[1]; } return result; }; /** * a line-level m3u8 parser event stream. it expects to receive input one * line at a time and performs a context-free parse of its contents. a stream * interpretation of a manifest can be useful if the manifest is expected to * be too large to fit comfortably into memory or the entirety of the input * is not immediately available. otherwise, it's probably much easier to work * with a regular `parser` object. * * produces `data` events with an object that captures the parser's * interpretation of the input. that object has a property `tag` that is one * of `uri`, `comment`, or `tag`. uris only have a single additional * property, `line`, which captures the entirety of the input without * interpretation. comments similarly have a single additional property * `text` which is the input without the leading `#`. * * tags always have a property `tagtype` which is the lower-cased version of * the m3u8 directive without the `#ext` or `#ext-x-` prefix. for instance, * `#ext-x-media-sequence` becomes `media-sequence` when parsed. unrecognized * tags are given the tag type `unknown` and a single additional property * `data` with the remainder of the input. * * @class parsestream * @extends stream */ var parsestream = /*#__pure__*/function (_stream) { _babel_runtime_helpers_inheritsloose__webpack_imported_module_0___default()(parsestream, _stream); function parsestream() { var _this; _this = _stream.call(this) || this; _this.customparsers = []; _this.tagmappers = []; return _this; } /** * parses an additional line of input. * * @param {string} line a single line of an m3u8 file to parse */ var _proto = parsestream.prototype; _proto.push = function push(line) { var _this2 = this; var match; var event; // strip whitespace line = line.trim(); if (line.length === 0) { // ignore empty lines return; } // uris if (line[0] !== '#') { this.trigger('data', { type: 'uri', uri: line }); return; } // map tags var newlines = this.tagmappers.reduce(function (acc, mapper) { var mappedline = mapper(line); // skip if unchanged if (mappedline === line) { return acc; } return acc.concat([mappedline]); }, [line]); newlines.foreach(function (newline) { for (var i = 0; i < _this2.customparsers.length; i++) { if (_this2.customparsers[i].call(_this2, newline)) { return; } } // comments if (newline.indexof('#ext') !== 0) { _this2.trigger('data', { type: 'comment', text: newline.slice(1) }); return; } // strip off any carriage returns here so the regex matching // doesn't have to account for them. newline = newline.replace('\r', ''); // tags match = /^#extm3u/.exec(newline); if (match) { _this2.trigger('data', { type: 'tag', tagtype: 'm3u' }); return; } match = /^#extinf:?([0-9\.]*)?,?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'inf' }; if (match[1]) { event.duration = parsefloat(match[1]); } if (match[2]) { event.title = match[2]; } _this2.trigger('data', event); return; } match = /^#ext-x-targetduration:?([0-9.]*)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'targetduration' }; if (match[1]) { event.duration = parseint(match[1], 10); } _this2.trigger('data', event); return; } match = /^#ext-x-version:?([0-9.]*)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'version' }; if (match[1]) { event.version = parseint(match[1], 10); } _this2.trigger('data', event); return; } match = /^#ext-x-media-sequence:?(\-?[0-9.]*)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'media-sequence' }; if (match[1]) { event.number = parseint(match[1], 10); } _this2.trigger('data', event); return; } match = /^#ext-x-discontinuity-sequence:?(\-?[0-9.]*)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'discontinuity-sequence' }; if (match[1]) { event.number = parseint(match[1], 10); } _this2.trigger('data', event); return; } match = /^#ext-x-playlist-type:?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'playlist-type' }; if (match[1]) { event.playlisttype = match[1]; } _this2.trigger('data', event); return; } match = /^#ext-x-byterange:?(.*)?$/.exec(newline); if (match) { event = _babel_runtime_helpers_extends__webpack_imported_module_2___default()(parsebyterange(match[1]), { type: 'tag', tagtype: 'byterange' }); _this2.trigger('data', event); return; } match = /^#ext-x-allow-cache:?(yes|no)?/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'allow-cache' }; if (match[1]) { event.allowed = !/no/.test(match[1]); } _this2.trigger('data', event); return; } match = /^#ext-x-map:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'map' }; if (match[1]) { var attributes = parseattributes(match[1]); if (attributes.uri) { event.uri = attributes.uri; } if (attributes.byterange) { event.byterange = parsebyterange(attributes.byterange); } } _this2.trigger('data', event); return; } match = /^#ext-x-stream-inf:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'stream-inf' }; if (match[1]) { event.attributes = parseattributes(match[1]); if (event.attributes.resolution) { var split = event.attributes.resolution.split('x'); var resolution = {}; if (split[0]) { resolution.width = parseint(split[0], 10); } if (split[1]) { resolution.height = parseint(split[1], 10); } event.attributes.resolution = resolution; } if (event.attributes.bandwidth) { event.attributes.bandwidth = parseint(event.attributes.bandwidth, 10); } if (event.attributes['program-id']) { event.attributes['program-id'] = parseint(event.attributes['program-id'], 10); } } _this2.trigger('data', event); return; } match = /^#ext-x-media:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'media' }; if (match[1]) { event.attributes = parseattributes(match[1]); } _this2.trigger('data', event); return; } match = /^#ext-x-endlist/.exec(newline); if (match) { _this2.trigger('data', { type: 'tag', tagtype: 'endlist' }); return; } match = /^#ext-x-discontinuity/.exec(newline); if (match) { _this2.trigger('data', { type: 'tag', tagtype: 'discontinuity' }); return; } match = /^#ext-x-program-date-time:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'program-date-time' }; if (match[1]) { event.datetimestring = match[1]; event.datetimeobject = new date(match[1]); } _this2.trigger('data', event); return; } match = /^#ext-x-key:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'key' }; if (match[1]) { event.attributes = parseattributes(match[1]); // parse the iv string into a uint32array if (event.attributes.iv) { if (event.attributes.iv.substring(0, 2).tolowercase() === '0x') { event.attributes.iv = event.attributes.iv.substring(2); } event.attributes.iv = event.attributes.iv.match(/.{8}/g); event.attributes.iv[0] = parseint(event.attributes.iv[0], 16); event.attributes.iv[1] = parseint(event.attributes.iv[1], 16); event.attributes.iv[2] = parseint(event.attributes.iv[2], 16); event.attributes.iv[3] = parseint(event.attributes.iv[3], 16); event.attributes.iv = new uint32array(event.attributes.iv); } } _this2.trigger('data', event); return; } match = /^#ext-x-start:?(.*)$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'start' }; if (match[1]) { event.attributes = parseattributes(match[1]); event.attributes['time-offset'] = parsefloat(event.attributes['time-offset']); event.attributes.precise = /yes/.test(event.attributes.precise); } _this2.trigger('data', event); return; } match = /^#ext-x-cue-out-cont:?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'cue-out-cont' }; if (match[1]) { event.data = match[1]; } else { event.data = ''; } _this2.trigger('data', event); return; } match = /^#ext-x-cue-out:?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'cue-out' }; if (match[1]) { event.data = match[1]; } else { event.data = ''; } _this2.trigger('data', event); return; } match = /^#ext-x-cue-in:?(.*)?$/.exec(newline); if (match) { event = { type: 'tag', tagtype: 'cue-in' }; if (match[1]) { event.data = match[1]; } else { event.data = ''; } _this2.trigger('data', event); return; } match = /^#ext-x-skip:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'skip' }; event.attributes = parseattributes(match[1]); if (event.attributes.hasownproperty('skipped-segments')) { event.attributes['skipped-segments'] = parseint(event.attributes['skipped-segments'], 10); } if (event.attributes.hasownproperty('recently-removed-dateranges')) { event.attributes['recently-removed-dateranges'] = event.attributes['recently-removed-dateranges'].split(tab); } _this2.trigger('data', event); return; } match = /^#ext-x-part:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'part' }; event.attributes = parseattributes(match[1]); ['duration'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parsefloat(event.attributes[key]); } }); ['independent', 'gap'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = /yes/.test(event.attributes[key]); } }); if (event.attributes.hasownproperty('byterange')) { event.attributes.byterange = parsebyterange(event.attributes.byterange); } _this2.trigger('data', event); return; } match = /^#ext-x-server-control:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'server-control' }; event.attributes = parseattributes(match[1]); ['can-skip-until', 'part-hold-back', 'hold-back'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parsefloat(event.attributes[key]); } }); ['can-skip-dateranges', 'can-block-reload'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = /yes/.test(event.attributes[key]); } }); _this2.trigger('data', event); return; } match = /^#ext-x-part-inf:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'part-inf' }; event.attributes = parseattributes(match[1]); ['part-target'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parsefloat(event.attributes[key]); } }); _this2.trigger('data', event); return; } match = /^#ext-x-preload-hint:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'preload-hint' }; event.attributes = parseattributes(match[1]); ['byterange-start', 'byterange-length'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parseint(event.attributes[key], 10); var subkey = key === 'byterange-length' ? 'length' : 'offset'; event.attributes.byterange = event.attributes.byterange || {}; event.attributes.byterange[subkey] = event.attributes[key]; // only keep the parsed byterange object. delete event.attributes[key]; } }); _this2.trigger('data', event); return; } match = /^#ext-x-rendition-report:(.*)$/.exec(newline); if (match && match[1]) { event = { type: 'tag', tagtype: 'rendition-report' }; event.attributes = parseattributes(match[1]); ['last-msn', 'last-part'].foreach(function (key) { if (event.attributes.hasownproperty(key)) { event.attributes[key] = parseint(event.attributes[key], 10); } }); _this2.trigger('data', event); return; } // unknown tag type _this2.trigger('data', { type: 'tag', data: newline.slice(4) }); }); } /** * add a parser for custom headers * * @param {object} options a map of options for the added parser * @param {regexp} options.expression a regular expression to match the custom header * @param {string} options.customtype the custom type to register to the output * @param {function} [options.dataparser] function to parse the line into an object * @param {boolean} [options.segment] should tag data be attached to the segment object */ ; _proto.addparser = function addparser(_ref) { var _this3 = this; var expression = _ref.expression, customtype = _ref.customtype, dataparser = _ref.dataparser, segment = _ref.segment; if (typeof dataparser !== 'function') { dataparser = function dataparser(line) { return line; }; } this.customparsers.push(function (line) { var match = expression.exec(line); if (match) { _this3.trigger('data', { type: 'custom', data: dataparser(line), customtype: customtype, segment: segment }); return true; } }); } /** * add a custom header mapper * * @param {object} options * @param {regexp} options.expression a regular expression to match the custom header * @param {function} options.map function to translate tag into a different tag */ ; _proto.addtagmapper = function addtagmapper(_ref2) { var expression = _ref2.expression, map = _ref2.map; var mapfn = function mapfn(line) { if (expression.test(line)) { return map(line); } return line; }; this.tagmappers.push(mapfn); }; return parsestream; }(_videojs_vhs_utils_es_stream_js__webpack_imported_module_1__[/* default */ "a"]); var camelcase = function camelcase(str) { return str.tolowercase().replace(/-(\w)/g, function (a) { return a[1].touppercase(); }); }; var camelcasekeys = function camelcasekeys(attributes) { var result = {}; object.keys(attributes).foreach(function (key) { result[camelcase(key)] = attributes[key]; }); return result; }; // set server-control hold back based upon targetduration and parttargetduration // we need this helper because defaults are based upon targetduration and // parttargetduration being set, but they may not be if server-control appears before // target durations are set. var setholdback = function setholdback(manifest) { var servercontrol = manifest.servercontrol, targetduration = manifest.targetduration, parttargetduration = manifest.parttargetduration; if (!servercontrol) { return; } var tag = '#ext-x-server-control'; var hb = 'holdback'; var phb = 'partholdback'; var mintargetduration = targetduration && targetduration * 3; var minpartduration = parttargetduration && parttargetduration * 2; if (targetduration && !servercontrol.hasownproperty(hb)) { servercontrol[hb] = mintargetduration; this.trigger('info', { message: tag + " defaulting hold-back to targetduration * 3 (" + mintargetduration + ")." }); } if (mintargetduration && servercontrol[hb] < mintargetduration) { this.trigger('warn', { message: tag + " clamping hold-back (" + servercontrol[hb] + ") to targetduration * 3 (" + mintargetduration + ")" }); servercontrol[hb] = mintargetduration; } // default no part hold back to part target duration * 3 if (parttargetduration && !servercontrol.hasownproperty(phb)) { servercontrol[phb] = parttargetduration * 3; this.trigger('info', { message: tag + " defaulting part-hold-back to parttargetduration * 3 (" + servercontrol[phb] + ")." }); } // if part hold back is too small default it to part target duration * 2 if (parttargetduration && servercontrol[phb] < minpartduration) { this.trigger('warn', { message: tag + " clamping part-hold-back (" + servercontrol[phb] + ") to parttargetduration * 2 (" + minpartduration + ")." }); servercontrol[phb] = minpartduration; } }; /** * a parser for m3u8 files. the current interpretation of the input is * exposed as a property `manifest` on parser objects. it's just two lines to * create and parse a manifest once you have the contents available as a string: * * ```js * var parser = new m3u8.parser(); * parser.push(xhr.responsetext); * ``` * * new input can later be applied to update the manifest object by calling * `push` again. * * the parser attempts to create a usable manifest object even if the * underlying input is somewhat nonsensical. it emits `info` and `warning` * events during the parse if it encounters input that seems invalid or * requires some property of the manifest object to be defaulted. * * @class parser * @extends stream */ var parser = /*#__pure__*/function (_stream) { _babel_runtime_helpers_inheritsloose__webpack_imported_module_0___default()(parser, _stream); function parser() { var _this; _this = _stream.call(this) || this; _this.linestream = new linestream(); _this.parsestream = new parsestream(); _this.linestream.pipe(_this.parsestream); /* eslint-disable consistent-this */ var self = _babel_runtime_helpers_assertthisinitialized__webpack_imported_module_3___default()(_this); /* eslint-enable consistent-this */ var uris = []; var currenturi = {}; // if specified, the active ext-x-map definition var currentmap; // if specified, the active decryption key var _key; var hasparts = false; var noop = function noop() {}; var defaultmediagroups = { 'audio': {}, 'video': {}, 'closed-captions': {}, 'subtitles': {} }; // this is the widevine uuid from dash if iop. the same exact string is // used in mpds with widevine encrypted streams. var widevineuuid = 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed'; // group segments into numbered timelines delineated by discontinuities var currenttimeline = 0; // the manifest is empty until the parse stream begins delivering data _this.manifest = { allowcache: true, discontinuitystarts: [], segments: [] }; // keep track of the last seen segment's byte range end, as segments are not required // to provide the offset, in which case it defaults to the next byte after the // previous segment var lastbyterangeend = 0; // keep track of the last seen part's byte range end. var lastpartbyterangeend = 0; _this.on('end', function () { // only add preloadsegment if we don't yet have a uri for it. // and we actually have parts/preloadhints if (currenturi.uri || !currenturi.parts && !currenturi.preloadhints) { return; } if (!currenturi.map && currentmap) { currenturi.map = currentmap; } if (!currenturi.key && _key) { currenturi.key = _key; } if (!currenturi.timeline && typeof currenttimeline === 'number') { currenturi.timeline = currenttimeline; } _this.manifest.preloadsegment = currenturi; }); // update the manifest with the m3u8 entry from the parse stream _this.parsestream.on('data', function (entry) { var mediagroup; var rendition; ({ tag: function tag() { // switch based on the tag type (({ version: function version() { if (entry.version) { this.manifest.version = entry.version; } }, 'allow-cache': function allowcache() { this.manifest.allowcache = entry.allowed; if (!('allowed' in entry)) { this.trigger('info', { message: 'defaulting allowcache to yes' }); this.manifest.allowcache = true; } }, byterange: function byterange() { var byterange = {}; if ('length' in entry) { currenturi.byterange = byterange; byterange.length = entry.length; if (!('offset' in entry)) { /* * from the latest spec (as of this writing): * https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-4.3.2.2 * * same text since ext-x-byterange's introduction in draft 7: * https://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.1) * * "if o [offset] is not present, the sub-range begins at the next byte * following the sub-range of the previous media segment." */ entry.offset = lastbyterangeend; } } if ('offset' in entry) { currenturi.byterange = byterange; byterange.offset = entry.offset; } lastbyterangeend = byterange.offset + byterange.length; }, endlist: function endlist() { this.manifest.endlist = true; }, inf: function inf() { if (!('mediasequence' in this.manifest)) { this.manifest.mediasequence = 0; this.trigger('info', { message: 'defaulting media sequence to zero' }); } if (!('discontinuitysequence' in this.manifest)) { this.manifest.discontinuitysequence = 0; this.trigger('info', { message: 'defaulting discontinuity sequence to zero' }); } if (entry.duration > 0) { currenturi.duration = entry.duration; } if (entry.duration === 0) { currenturi.duration = 0.01; this.trigger('info', { message: 'updating zero segment duration to a small value' }); } this.manifest.segments = uris; }, key: function key() { if (!entry.attributes) { this.trigger('warn', { message: 'ignoring key declaration without attribute list' }); return; } // clear the active encryption key if (entry.attributes.method === 'none') { _key = null; return; } if (!entry.attributes.uri) { this.trigger('warn', { message: 'ignoring key declaration without uri' }); return; } if (entry.attributes.keyformat === 'com.apple.streamingkeydelivery') { this.manifest.contentprotection = this.manifest.contentprotection || {}; // todo: add full support for this. this.manifest.contentprotection['com.apple.fps.1_0'] = { attributes: entry.attributes }; return; } if (entry.attributes.keyformat === 'com.microsoft.playready') { this.manifest.contentprotection = this.manifest.contentprotection || {}; // todo: add full support for this. this.manifest.contentprotection['com.microsoft.playready'] = { uri: entry.attributes.uri }; return; } // check if the content is encrypted for widevine // widevine/hls spec: https://storage.googleapis.com/wvdocs/widevine_drm_hls.pdf if (entry.attributes.keyformat === widevineuuid) { var valid_methods = ['sample-aes', 'sample-aes-ctr', 'sample-aes-cenc']; if (valid_methods.indexof(entry.attributes.method) === -1) { this.trigger('warn', { message: 'invalid key method provided for widevine' }); return; } if (entry.attributes.method === 'sample-aes-cenc') { this.trigger('warn', { message: 'sample-aes-cenc is deprecated, please use sample-aes-ctr instead' }); } if (entry.attributes.uri.substring(0, 23) !== 'data:text/plain;base64,') { this.trigger('warn', { message: 'invalid key uri provided for widevine' }); return; } if (!(entry.attributes.keyid && entry.attributes.keyid.substring(0, 2) === '0x')) { this.trigger('warn', { message: 'invalid key id provided for widevine' }); return; } // if widevine key attributes are valid, store them as `contentprotection` // on the manifest to emulate widevine tag structure in a dash mpd this.manifest.contentprotection = this.manifest.contentprotection || {}; this.manifest.contentprotection['com.widevine.alpha'] = { attributes: { schemeiduri: entry.attributes.keyformat, // remove '0x' from the key id string keyid: entry.attributes.keyid.substring(2) }, // decode the base64-encoded pssh box pssh: object(_videojs_vhs_utils_es_decode_b64_to_uint8_array_js__webpack_imported_module_4__[/* default */ "a"])(entry.attributes.uri.split(',')[1]) }; return; } if (!entry.attributes.method) { this.trigger('warn', { message: 'defaulting key method to aes-128' }); } // setup an encryption key for upcoming segments _key = { method: entry.attributes.method || 'aes-128', uri: entry.attributes.uri }; if (typeof entry.attributes.iv !== 'undefined') { _key.iv = entry.attributes.iv; } }, 'media-sequence': function mediasequence() { if (!isfinite(entry.number)) { this.trigger('warn', { message: 'ignoring invalid media sequence: ' + entry.number }); return; } this.manifest.mediasequence = entry.number; }, 'discontinuity-sequence': function discontinuitysequence() { if (!isfinite(entry.number)) { this.trigger('warn', { message: 'ignoring invalid discontinuity sequence: ' + entry.number }); return; } this.manifest.discontinuitysequence = entry.number; currenttimeline = entry.number; }, 'playlist-type': function playlisttype() { if (!/vod|event/.test(entry.playlisttype)) { this.trigger('warn', { message: 'ignoring unknown playlist type: ' + entry.playlist }); return; } this.manifest.playlisttype = entry.playlisttype; }, map: function map() { currentmap = {}; if (entry.uri) { currentmap.uri = entry.uri; } if (entry.byterange) { currentmap.byterange = entry.byterange; } if (_key) { currentmap.key = _key; } }, 'stream-inf': function streaminf() { this.manifest.playlists = uris; this.manifest.mediagroups = this.manifest.mediagroups || defaultmediagroups; if (!entry.attributes) { this.trigger('warn', { message: 'ignoring empty stream-inf attributes' }); return; } if (!currenturi.attributes) { currenturi.attributes = {}; } _babel_runtime_helpers_extends__webpack_imported_module_2___default()(currenturi.attributes, entry.attributes); }, media: function media() { this.manifest.mediagroups = this.manifest.mediagroups || defaultmediagroups; if (!(entry.attributes && entry.attributes.type && entry.attributes['group-id'] && entry.attributes.name)) { this.trigger('warn', { message: 'ignoring incomplete or missing media group' }); return; } // find the media group, creating defaults as necessary var mediagrouptype = this.manifest.mediagroups[entry.attributes.type]; mediagrouptype[entry.attributes['group-id']] = mediagrouptype[entry.attributes['group-id']] || {}; mediagroup = mediagrouptype[entry.attributes['group-id']]; // collect the rendition metadata rendition = { default: /yes/i.test(entry.attributes.default) }; if (rendition.default) { rendition.autoselect = true; } else { rendition.autoselect = /yes/i.test(entry.attributes.autoselect); } if (entry.attributes.language) { rendition.language = entry.attributes.language; } if (entry.attributes.uri) { rendition.uri = entry.attributes.uri; } if (entry.attributes['instream-id']) { rendition.instreamid = entry.attributes['instream-id']; } if (entry.attributes.characteristics) { rendition.characteristics = entry.attributes.characteristics; } if (entry.attributes.forced) { rendition.forced = /yes/i.test(entry.attributes.forced); } // insert the new rendition mediagroup[entry.attributes.name] = rendition; }, discontinuity: function discontinuity() { currenttimeline += 1; currenturi.discontinuity = true; this.manifest.discontinuitystarts.push(uris.length); }, 'program-date-time': function programdatetime() { if (typeof this.manifest.datetimestring === 'undefined') { // program-date-time is a media-segment tag, but for backwards // compatibility, we add the first occurence of the program-date-time tag // to the manifest object // todo: consider removing this in future major version this.manifest.datetimestring = entry.datetimestring; this.manifest.datetimeobject = entry.datetimeobject; } currenturi.datetimestring = entry.datetimestring; currenturi.datetimeobject = entry.datetimeobject; }, targetduration: function targetduration() { if (!isfinite(entry.duration) || entry.duration < 0) { this.trigger('warn', { message: 'ignoring invalid target duration: ' + entry.duration }); return; } this.manifest.targetduration = entry.duration; setholdback.call(this, this.manifest); }, start: function start() { if (!entry.attributes || isnan(entry.attributes['time-offset'])) { this.trigger('warn', { message: 'ignoring start declaration without appropriate attribute list' }); return; } this.manifest.start = { timeoffset: entry.attributes['time-offset'], precise: entry.attributes.precise }; }, 'cue-out': function cueout() { currenturi.cueout = entry.data; }, 'cue-out-cont': function cueoutcont() { currenturi.cueoutcont = entry.data; }, 'cue-in': function cuein() { currenturi.cuein = entry.data; }, 'skip': function skip() { this.manifest.skip = camelcasekeys(entry.attributes); this.warnonmissingattributes_('#ext-x-skip', entry.attributes, ['skipped-segments']); }, 'part': function part() { var _this2 = this; hasparts = true; // parts are always specifed before a segment var segmentindex = this.manifest.segments.length; var part = camelcasekeys(entry.attributes); currenturi.parts = currenturi.parts || []; currenturi.parts.push(part); if (part.byterange) { if (!part.byterange.hasownproperty('offset')) { part.byterange.offset = lastpartbyterangeend; } lastpartbyterangeend = part.byterange.offset + part.byterange.length; } var partindex = currenturi.parts.length - 1; this.warnonmissingattributes_("#ext-x-part #" + partindex + " for segment #" + segmentindex, entry.attributes, ['uri', 'duration']); if (this.manifest.renditionreports) { this.manifest.renditionreports.foreach(function (r, i) { if (!r.hasownproperty('lastpart')) { _this2.trigger('warn', { message: "#ext-x-rendition-report #" + i + " lacks required attribute(s): last-part" }); } }); } }, 'server-control': function servercontrol() { var attrs = this.manifest.servercontrol = camelcasekeys(entry.attributes); if (!attrs.hasownproperty('canblockreload')) { attrs.canblockreload = false; this.trigger('info', { message: '#ext-x-server-control defaulting can-block-reload to false' }); } setholdback.call(this, this.manifest); if (attrs.canskipdateranges && !attrs.hasownproperty('canskipuntil')) { this.trigger('warn', { message: '#ext-x-server-control lacks required attribute can-skip-until which is required when can-skip-dateranges is set' }); } }, 'preload-hint': function preloadhint() { // parts are always specifed before a segment var segmentindex = this.manifest.segments.length; var hint = camelcasekeys(entry.attributes); var ispart = hint.type && hint.type === 'part'; currenturi.preloadhints = currenturi.preloadhints || []; currenturi.preloadhints.push(hint); if (hint.byterange) { if (!hint.byterange.hasownproperty('offset')) { // use last part byterange end or zero if not a part. hint.byterange.offset = ispart ? lastpartbyterangeend : 0; if (ispart) { lastpartbyterangeend = hint.byterange.offset + hint.byterange.length; } } } var index = currenturi.preloadhints.length - 1; this.warnonmissingattributes_("#ext-x-preload-hint #" + index + " for segment #" + segmentindex, entry.attributes, ['type', 'uri']); if (!hint.type) { return; } // search through all preload hints except for the current one for // a duplicate type. for (var i = 0; i < currenturi.preloadhints.length - 1; i++) { var otherhint = currenturi.preloadhints[i]; if (!otherhint.type) { continue; } if (otherhint.type === hint.type) { this.trigger('warn', { message: "#ext-x-preload-hint #" + index + " for segment #" + segmentindex + " has the same type " + hint.type + " as preload hint #" + i }); } } }, 'rendition-report': function renditionreport() { var report = camelcasekeys(entry.attributes); this.manifest.renditionreports = this.manifest.renditionreports || []; this.manifest.renditionreports.push(report); var index = this.manifest.renditionreports.length - 1; var required = ['last-msn', 'uri']; if (hasparts) { required.push('last-part'); } this.warnonmissingattributes_("#ext-x-rendition-report #" + index, entry.attributes, required); }, 'part-inf': function partinf() { this.manifest.partinf = camelcasekeys(entry.attributes); this.warnonmissingattributes_('#ext-x-part-inf', entry.attributes, ['part-target']); if (this.manifest.partinf.parttarget) { this.manifest.parttargetduration = this.manifest.partinf.parttarget; } setholdback.call(this, this.manifest); } })[entry.tagtype] || noop).call(self); }, uri: function uri() { currenturi.uri = entry.uri; uris.push(currenturi); // if no explicit duration was declared, use the target duration if (this.manifest.targetduration && !('duration' in currenturi)) { this.trigger('warn', { message: 'defaulting segment duration to the target duration' }); currenturi.duration = this.manifest.targetduration; } // annotate with encryption information, if necessary if (_key) { currenturi.key = _key; } currenturi.timeline = currenttimeline; // annotate with initialization segment information, if necessary if (currentmap) { currenturi.map = currentmap; } // reset the last byterange end as it needs to be 0 between parts lastpartbyterangeend = 0; // prepare for the next uri currenturi = {}; }, comment: function comment() {// comments are not important for playback }, custom: function custom() { // if this is segment-level data attach the output to the segment if (entry.segment) { currenturi.custom = currenturi.custom || {}; currenturi.custom[entry.customtype] = entry.data; // if this is manifest-level data attach to the top level manifest object } else { this.manifest.custom = this.manifest.custom || {}; this.manifest.custom[entry.customtype] = entry.data; } } })[entry.type].call(self); }); return _this; } var _proto = parser.prototype; _proto.warnonmissingattributes_ = function warnonmissingattributes_(identifier, attributes, required) { var missing = []; required.foreach(function (key) { if (!attributes.hasownproperty(key)) { missing.push(key); } }); if (missing.length) { this.trigger('warn', { message: identifier + " lacks required attribute(s): " + missing.join(', ') }); } } /** * parse the input string and update the manifest object. * * @param {string} chunk a potentially incomplete portion of the manifest */ ; _proto.push = function push(chunk) { this.linestream.push(chunk); } /** * flush any remaining input. this can be handy if the last line of an m3u8 * manifest did not contain a trailing newline but the file has been * completely received. */ ; _proto.end = function end() { // flush any buffered input this.linestream.push('\n'); this.trigger('end'); } /** * add an additional parser for non-standard tags * * @param {object} options a map of options for the added parser * @param {regexp} options.expression a regular expression to match the custom header * @param {string} options.type the type to register to the output * @param {function} [options.dataparser] function to parse the line into an object * @param {boolean} [options.segment] should tag data be attached to the segment object */ ; _proto.addparser = function addparser(options) { this.parsestream.addparser(options); } /** * add a custom header mapper * * @param {object} options * @param {regexp} options.expression a regular expression to match the custom header * @param {function} options.map function to translate tag into a different tag */ ; _proto.addtagmapper = function addtagmapper(options) { this.parsestream.addtagmapper(options); }; return parser; }(_videojs_vhs_utils_es_stream_js__webpack_imported_module_1__[/* default */ "a"]); /***/ }), /***/ 195: /***/ (function(module, exports, __webpack_require__) { var getuint64 = __webpack_require__(322).getuint64; var parsesidx = function(data) { var view = new dataview(data.buffer, data.byteoffset, data.bytelength), result = { version: data[0], flags: new uint8array(data.subarray(1, 4)), references: [], referenceid: view.getuint32(4), timescale: view.getuint32(8) }, i = 12; if (result.version === 0) { result.earliestpresentationtime = view.getuint32(i); result.firstoffset = view.getuint32(i + 4); i += 8; } else { // read 64 bits result.earliestpresentationtime = getuint64(data.subarray(i)); result.firstoffset = getuint64(data.subarray(i + 8)); i += 16; } i += 2; // reserved var referencecount = view.getuint16(i); i += 2; // start of references for (; referencecount > 0; i += 12, referencecount--) { result.references.push({ referencetype: (data[i] & 0x80) >>> 7, referencedsize: view.getuint32(i) & 0x7fffffff, subsegmentduration: view.getuint32(i + 4), startswithsap: !!(data[i + 8] & 0x80), saptype: (data[i + 8] & 0x70) >>> 4, sapdeltatime: view.getuint32(i + 8) & 0x0fffffff }); } return result; }; module.exports = parsesidx; /***/ }), /***/ 315: /***/ (function(module, exports, __webpack_require__) { "use strict"; /* webpack var injection */(function(global) {/*! * the buffer module from node.js, for the browser. * * @author feross aboukhadijeh * @license mit */ /* eslint-disable no-proto */ var base64 = __webpack_require__(316) var ieee754 = __webpack_require__(317) var isarray = __webpack_require__(318) exports.buffer = buffer exports.slowbuffer = slowbuffer exports.inspect_max_bytes = 50 /** * if `buffer.typed_array_support`: * === true use uint8array implementation (fastest) * === false use object implementation (most compatible, even ie6) * * browsers that support typed arrays are ie 10+, firefox 4+, chrome 7+, safari 5.1+, * opera 11.6+, ios 4.2+. * * due to various browser bugs, sometimes the object implementation will be used even * when the browser supports typed arrays. * * note: * * - firefox 4-29 lacks support for adding new properties to `uint8array` instances, * see: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. * * - chrome 9-10 is missing the `typedarray.prototype.subarray` function. * * - ie10 has a broken `typedarray.prototype.subarray` function which returns arrays of * incorrect length in some situations. * we detect these buggy browsers and set `buffer.typed_array_support` to `false` so they * get the object implementation, which is slower but behaves correctly. */ buffer.typed_array_support = global.typed_array_support !== undefined ? global.typed_array_support : typedarraysupport() /* * export kmaxlength after typed array support is determined. */ exports.kmaxlength = kmaxlength() function typedarraysupport () { try { var arr = new uint8array(1) arr.__proto__ = {__proto__: uint8array.prototype, foo: function () { return 42 }} return arr.foo() === 42 && // typed array instances can be augmented typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` arr.subarray(1, 1).bytelength === 0 // ie10 has broken `subarray` } catch (e) { return false } } function kmaxlength () { return buffer.typed_array_support ? 0x7fffffff : 0x3fffffff } function createbuffer (that, length) { if (kmaxlength() < length) { throw new rangeerror('invalid typed array length') } if (buffer.typed_array_support) { // return an augmented `uint8array` instance, for best performance that = new uint8array(length) that.__proto__ = buffer.prototype } else { // fallback: return an object instance of the buffer class if (that === null) { that = new buffer(length) } that.length = length } return that } /** * the buffer constructor returns instances of `uint8array` that have their * prototype changed to `buffer.prototype`. furthermore, `buffer` is a subclass of * `uint8array`, so the returned instances will have all the node `buffer` methods * and the `uint8array` methods. square bracket notation works as expected -- it * returns a single octet. * * the `uint8array` prototype remains unmodified. */ function buffer (arg, encodingoroffset, length) { if (!buffer.typed_array_support && !(this instanceof buffer)) { return new buffer(arg, encodingoroffset, length) } // common case. if (typeof arg === 'number') { if (typeof encodingoroffset === 'string') { throw new error( 'if encoding is specified then the first argument must be a string' ) } return allocunsafe(this, arg) } return from(this, arg, encodingoroffset, length) } buffer.poolsize = 8192 // not used by this implementation // todo: legacy, not needed anymore. remove in next major version. buffer._augment = function (arr) { arr.__proto__ = buffer.prototype return arr } function from (that, value, encodingoroffset, length) { if (typeof value === 'number') { throw new typeerror('"value" argument must not be a number') } if (typeof arraybuffer !== 'undefined' && value instanceof arraybuffer) { return fromarraybuffer(that, value, encodingoroffset, length) } if (typeof value === 'string') { return fromstring(that, value, encodingoroffset) } return fromobject(that, value) } /** * functionally equivalent to buffer(arg, encoding) but throws a typeerror * if value is a number. * buffer.from(str[, encoding]) * buffer.from(array) * buffer.from(buffer) * buffer.from(arraybuffer[, byteoffset[, length]]) **/ buffer.from = function (value, encodingoroffset, length) { return from(null, value, encodingoroffset, length) } if (buffer.typed_array_support) { buffer.prototype.__proto__ = uint8array.prototype buffer.__proto__ = uint8array if (typeof symbol !== 'undefined' && symbol.species && buffer[symbol.species] === buffer) { // fix subarray() in es2016. see: https://github.com/feross/buffer/pull/97 object.defineproperty(buffer, symbol.species, { value: null, configurable: true }) } } function assertsize (size) { if (typeof size !== 'number') { throw new typeerror('"size" argument must be a number') } else if (size < 0) { throw new rangeerror('"size" argument must not be negative') } } function alloc (that, size, fill, encoding) { assertsize(size) if (size <= 0) { return createbuffer(that, size) } if (fill !== undefined) { // only pay attention to encoding if it's a string. this // prevents accidentally sending in a number that would // be interpretted as a start offset. return typeof encoding === 'string' ? createbuffer(that, size).fill(fill, encoding) : createbuffer(that, size).fill(fill) } return createbuffer(that, size) } /** * creates a new filled buffer instance. * alloc(size[, fill[, encoding]]) **/ buffer.alloc = function (size, fill, encoding) { return alloc(null, size, fill, encoding) } function allocunsafe (that, size) { assertsize(size) that = createbuffer(that, size < 0 ? 0 : checked(size) | 0) if (!buffer.typed_array_support) { for (var i = 0; i < size; ++i) { that[i] = 0 } } return that } /** * equivalent to buffer(num), by default creates a non-zero-filled buffer instance. * */ buffer.allocunsafe = function (size) { return allocunsafe(null, size) } /** * equivalent to slowbuffer(num), by default creates a non-zero-filled buffer instance. */ buffer.allocunsafeslow = function (size) { return allocunsafe(null, size) } function fromstring (that, string, encoding) { if (typeof encoding !== 'string' || encoding === '') { encoding = 'utf8' } if (!buffer.isencoding(encoding)) { throw new typeerror('"encoding" must be a valid string encoding') } var length = bytelength(string, encoding) | 0 that = createbuffer(that, length) var actual = that.write(string, encoding) if (actual !== length) { // writing a hex string, for example, that contains invalid characters will // cause everything after the first invalid character to be ignored. (e.g. // 'abxxcd' will be treated as 'ab') that = that.slice(0, actual) } return that } function fromarraylike (that, array) { var length = array.length < 0 ? 0 : checked(array.length) | 0 that = createbuffer(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } function fromarraybuffer (that, array, byteoffset, length) { array.bytelength // this throws if `array` is not a valid arraybuffer if (byteoffset < 0 || array.bytelength < byteoffset) { throw new rangeerror('\'offset\' is out of bounds') } if (array.bytelength < byteoffset + (length || 0)) { throw new rangeerror('\'length\' is out of bounds') } if (byteoffset === undefined && length === undefined) { array = new uint8array(array) } else if (length === undefined) { array = new uint8array(array, byteoffset) } else { array = new uint8array(array, byteoffset, length) } if (buffer.typed_array_support) { // return an augmented `uint8array` instance, for best performance that = array that.__proto__ = buffer.prototype } else { // fallback: return an object instance of the buffer class that = fromarraylike(that, array) } return that } function fromobject (that, obj) { if (buffer.isbuffer(obj)) { var len = checked(obj.length) | 0 that = createbuffer(that, len) if (that.length === 0) { return that } obj.copy(that, 0, 0, len) return that } if (obj) { if ((typeof arraybuffer !== 'undefined' && obj.buffer instanceof arraybuffer) || 'length' in obj) { if (typeof obj.length !== 'number' || isnan(obj.length)) { return createbuffer(that, 0) } return fromarraylike(that, obj) } if (obj.type === 'buffer' && isarray(obj.data)) { return fromarraylike(that, obj.data) } } throw new typeerror('first argument must be a string, buffer, arraybuffer, array, or array-like object.') } function checked (length) { // note: cannot use `length < kmaxlength()` here because that fails when // length is nan (which is otherwise coerced to zero.) if (length >= kmaxlength()) { throw new rangeerror('attempt to allocate buffer larger than maximum ' + 'size: 0x' + kmaxlength().tostring(16) + ' bytes') } return length | 0 } function slowbuffer (length) { if (+length != length) { // eslint-disable-line eqeqeq length = 0 } return buffer.alloc(+length) } buffer.isbuffer = function isbuffer (b) { return !!(b != null && b._isbuffer) } buffer.compare = function compare (a, b) { if (!buffer.isbuffer(a) || !buffer.isbuffer(b)) { throw new typeerror('arguments must be buffers') } if (a === b) return 0 var x = a.length var y = b.length for (var i = 0, len = math.min(x, y); i < len; ++i) { if (a[i] !== b[i]) { x = a[i] y = b[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } buffer.isencoding = function isencoding (encoding) { switch (string(encoding).tolowercase()) { case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'latin1': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return true default: return false } } buffer.concat = function concat (list, length) { if (!isarray(list)) { throw new typeerror('"list" argument must be an array of buffers') } if (list.length === 0) { return buffer.alloc(0) } var i if (length === undefined) { length = 0 for (i = 0; i < list.length; ++i) { length += list[i].length } } var buffer = buffer.allocunsafe(length) var pos = 0 for (i = 0; i < list.length; ++i) { var buf = list[i] if (!buffer.isbuffer(buf)) { throw new typeerror('"list" argument must be an array of buffers') } buf.copy(buffer, pos) pos += buf.length } return buffer } function bytelength (string, encoding) { if (buffer.isbuffer(string)) { return string.length } if (typeof arraybuffer !== 'undefined' && typeof arraybuffer.isview === 'function' && (arraybuffer.isview(string) || string instanceof arraybuffer)) { return string.bytelength } if (typeof string !== 'string') { string = '' + string } var len = string.length if (len === 0) return 0 // use a for loop to avoid recursion var loweredcase = false for (;;) { switch (encoding) { case 'ascii': case 'latin1': case 'binary': return len case 'utf8': case 'utf-8': case undefined: return utf8tobytes(string).length case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return len * 2 case 'hex': return len >>> 1 case 'base64': return base64tobytes(string).length default: if (loweredcase) return utf8tobytes(string).length // assume utf8 encoding = ('' + encoding).tolowercase() loweredcase = true } } } buffer.bytelength = bytelength function slowtostring (encoding, start, end) { var loweredcase = false // no need to verify that "this.length <= max_uint32" since it's a read-only // property of a typed array. // this behaves neither like string nor uint8array in that we set start/end // to their upper/lower bounds if the value passed is out of range. // undefined is handled specially as per ecma-262 6th edition, // section 13.3.3.7 runtime semantics: keyedbindinginitialization. if (start === undefined || start < 0) { start = 0 } // return early if start > this.length. done here to prevent potential uint32 // coercion fail below. if (start > this.length) { return '' } if (end === undefined || end > this.length) { end = this.length } if (end <= 0) { return '' } // force coersion to uint32. this will also coerce falsey/nan values to 0. end >>>= 0 start >>>= 0 if (end <= start) { return '' } if (!encoding) encoding = 'utf8' while (true) { switch (encoding) { case 'hex': return hexslice(this, start, end) case 'utf8': case 'utf-8': return utf8slice(this, start, end) case 'ascii': return asciislice(this, start, end) case 'latin1': case 'binary': return latin1slice(this, start, end) case 'base64': return base64slice(this, start, end) case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return utf16leslice(this, start, end) default: if (loweredcase) throw new typeerror('unknown encoding: ' + encoding) encoding = (encoding + '').tolowercase() loweredcase = true } } } // the property is used by `buffer.isbuffer` and `is-buffer` (in safari 5-7) to detect // buffer instances. buffer.prototype._isbuffer = true function swap (b, n, m) { var i = b[n] b[n] = b[m] b[m] = i } buffer.prototype.swap16 = function swap16 () { var len = this.length if (len % 2 !== 0) { throw new rangeerror('buffer size must be a multiple of 16-bits') } for (var i = 0; i < len; i += 2) { swap(this, i, i + 1) } return this } buffer.prototype.swap32 = function swap32 () { var len = this.length if (len % 4 !== 0) { throw new rangeerror('buffer size must be a multiple of 32-bits') } for (var i = 0; i < len; i += 4) { swap(this, i, i + 3) swap(this, i + 1, i + 2) } return this } buffer.prototype.swap64 = function swap64 () { var len = this.length if (len % 8 !== 0) { throw new rangeerror('buffer size must be a multiple of 64-bits') } for (var i = 0; i < len; i += 8) { swap(this, i, i + 7) swap(this, i + 1, i + 6) swap(this, i + 2, i + 5) swap(this, i + 3, i + 4) } return this } buffer.prototype.tostring = function tostring () { var length = this.length | 0 if (length === 0) return '' if (arguments.length === 0) return utf8slice(this, 0, length) return slowtostring.apply(this, arguments) } buffer.prototype.equals = function equals (b) { if (!buffer.isbuffer(b)) throw new typeerror('argument must be a buffer') if (this === b) return true return buffer.compare(this, b) === 0 } buffer.prototype.inspect = function inspect () { var str = '' var max = exports.inspect_max_bytes if (this.length > 0) { str = this.tostring('hex', 0, max).match(/.{2}/g).join(' ') if (this.length > max) str += ' ... ' } return '' } buffer.prototype.compare = function compare (target, start, end, thisstart, thisend) { if (!buffer.isbuffer(target)) { throw new typeerror('argument must be a buffer') } if (start === undefined) { start = 0 } if (end === undefined) { end = target ? target.length : 0 } if (thisstart === undefined) { thisstart = 0 } if (thisend === undefined) { thisend = this.length } if (start < 0 || end > target.length || thisstart < 0 || thisend > this.length) { throw new rangeerror('out of range index') } if (thisstart >= thisend && start >= end) { return 0 } if (thisstart >= thisend) { return -1 } if (start >= end) { return 1 } start >>>= 0 end >>>= 0 thisstart >>>= 0 thisend >>>= 0 if (this === target) return 0 var x = thisend - thisstart var y = end - start var len = math.min(x, y) var thiscopy = this.slice(thisstart, thisend) var targetcopy = target.slice(start, end) for (var i = 0; i < len; ++i) { if (thiscopy[i] !== targetcopy[i]) { x = thiscopy[i] y = targetcopy[i] break } } if (x < y) return -1 if (y < x) return 1 return 0 } // finds either the first index of `val` in `buffer` at offset >= `byteoffset`, // or the last index of `val` in `buffer` at offset <= `byteoffset`. // // arguments: // - buffer - a buffer to search // - val - a string, buffer, or number // - byteoffset - an index into `buffer`; will be clamped to an int32 // - encoding - an optional encoding, relevant is val is a string // - dir - true for indexof, false for lastindexof function bidirectionalindexof (buffer, val, byteoffset, encoding, dir) { // empty buffer means no match if (buffer.length === 0) return -1 // normalize byteoffset if (typeof byteoffset === 'string') { encoding = byteoffset byteoffset = 0 } else if (byteoffset > 0x7fffffff) { byteoffset = 0x7fffffff } else if (byteoffset < -0x80000000) { byteoffset = -0x80000000 } byteoffset = +byteoffset // coerce to number. if (isnan(byteoffset)) { // byteoffset: it it's undefined, null, nan, "foo", etc, search whole buffer byteoffset = dir ? 0 : (buffer.length - 1) } // normalize byteoffset: negative offsets start from the end of the buffer if (byteoffset < 0) byteoffset = buffer.length + byteoffset if (byteoffset >= buffer.length) { if (dir) return -1 else byteoffset = buffer.length - 1 } else if (byteoffset < 0) { if (dir) byteoffset = 0 else return -1 } // normalize val if (typeof val === 'string') { val = buffer.from(val, encoding) } // finally, search either indexof (if dir is true) or lastindexof if (buffer.isbuffer(val)) { // special case: looking for empty string/buffer always fails if (val.length === 0) { return -1 } return arrayindexof(buffer, val, byteoffset, encoding, dir) } else if (typeof val === 'number') { val = val & 0xff // search for a byte value [0-255] if (buffer.typed_array_support && typeof uint8array.prototype.indexof === 'function') { if (dir) { return uint8array.prototype.indexof.call(buffer, val, byteoffset) } else { return uint8array.prototype.lastindexof.call(buffer, val, byteoffset) } } return arrayindexof(buffer, [ val ], byteoffset, encoding, dir) } throw new typeerror('val must be string, number or buffer') } function arrayindexof (arr, val, byteoffset, encoding, dir) { var indexsize = 1 var arrlength = arr.length var vallength = val.length if (encoding !== undefined) { encoding = string(encoding).tolowercase() if (encoding === 'ucs2' || encoding === 'ucs-2' || encoding === 'utf16le' || encoding === 'utf-16le') { if (arr.length < 2 || val.length < 2) { return -1 } indexsize = 2 arrlength /= 2 vallength /= 2 byteoffset /= 2 } } function read (buf, i) { if (indexsize === 1) { return buf[i] } else { return buf.readuint16be(i * indexsize) } } var i if (dir) { var foundindex = -1 for (i = byteoffset; i < arrlength; i++) { if (read(arr, i) === read(val, foundindex === -1 ? 0 : i - foundindex)) { if (foundindex === -1) foundindex = i if (i - foundindex + 1 === vallength) return foundindex * indexsize } else { if (foundindex !== -1) i -= i - foundindex foundindex = -1 } } } else { if (byteoffset + vallength > arrlength) byteoffset = arrlength - vallength for (i = byteoffset; i >= 0; i--) { var found = true for (var j = 0; j < vallength; j++) { if (read(arr, i + j) !== read(val, j)) { found = false break } } if (found) return i } } return -1 } buffer.prototype.includes = function includes (val, byteoffset, encoding) { return this.indexof(val, byteoffset, encoding) !== -1 } buffer.prototype.indexof = function indexof (val, byteoffset, encoding) { return bidirectionalindexof(this, val, byteoffset, encoding, true) } buffer.prototype.lastindexof = function lastindexof (val, byteoffset, encoding) { return bidirectionalindexof(this, val, byteoffset, encoding, false) } function hexwrite (buf, string, offset, length) { offset = number(offset) || 0 var remaining = buf.length - offset if (!length) { length = remaining } else { length = number(length) if (length > remaining) { length = remaining } } // must be an even number of digits var strlen = string.length if (strlen % 2 !== 0) throw new typeerror('invalid hex string') if (length > strlen / 2) { length = strlen / 2 } for (var i = 0; i < length; ++i) { var parsed = parseint(string.substr(i * 2, 2), 16) if (isnan(parsed)) return i buf[offset + i] = parsed } return i } function utf8write (buf, string, offset, length) { return blitbuffer(utf8tobytes(string, buf.length - offset), buf, offset, length) } function asciiwrite (buf, string, offset, length) { return blitbuffer(asciitobytes(string), buf, offset, length) } function latin1write (buf, string, offset, length) { return asciiwrite(buf, string, offset, length) } function base64write (buf, string, offset, length) { return blitbuffer(base64tobytes(string), buf, offset, length) } function ucs2write (buf, string, offset, length) { return blitbuffer(utf16letobytes(string, buf.length - offset), buf, offset, length) } buffer.prototype.write = function write (string, offset, length, encoding) { // buffer#write(string) if (offset === undefined) { encoding = 'utf8' length = this.length offset = 0 // buffer#write(string, encoding) } else if (length === undefined && typeof offset === 'string') { encoding = offset length = this.length offset = 0 // buffer#write(string, offset[, length][, encoding]) } else if (isfinite(offset)) { offset = offset | 0 if (isfinite(length)) { length = length | 0 if (encoding === undefined) encoding = 'utf8' } else { encoding = length length = undefined } // legacy write(string, encoding, offset, length) - remove in v0.13 } else { throw new error( 'buffer.write(string, encoding, offset[, length]) is no longer supported' ) } var remaining = this.length - offset if (length === undefined || length > remaining) length = remaining if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { throw new rangeerror('attempt to write outside buffer bounds') } if (!encoding) encoding = 'utf8' var loweredcase = false for (;;) { switch (encoding) { case 'hex': return hexwrite(this, string, offset, length) case 'utf8': case 'utf-8': return utf8write(this, string, offset, length) case 'ascii': return asciiwrite(this, string, offset, length) case 'latin1': case 'binary': return latin1write(this, string, offset, length) case 'base64': // warning: maxlength not taken into account in base64write return base64write(this, string, offset, length) case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': return ucs2write(this, string, offset, length) default: if (loweredcase) throw new typeerror('unknown encoding: ' + encoding) encoding = ('' + encoding).tolowercase() loweredcase = true } } } buffer.prototype.tojson = function tojson () { return { type: 'buffer', data: array.prototype.slice.call(this._arr || this, 0) } } function base64slice (buf, start, end) { if (start === 0 && end === buf.length) { return base64.frombytearray(buf) } else { return base64.frombytearray(buf.slice(start, end)) } } function utf8slice (buf, start, end) { end = math.min(buf.length, end) var res = [] var i = start while (i < end) { var firstbyte = buf[i] var codepoint = null var bytespersequence = (firstbyte > 0xef) ? 4 : (firstbyte > 0xdf) ? 3 : (firstbyte > 0xbf) ? 2 : 1 if (i + bytespersequence <= end) { var secondbyte, thirdbyte, fourthbyte, tempcodepoint switch (bytespersequence) { case 1: if (firstbyte < 0x80) { codepoint = firstbyte } break case 2: secondbyte = buf[i + 1] if ((secondbyte & 0xc0) === 0x80) { tempcodepoint = (firstbyte & 0x1f) << 0x6 | (secondbyte & 0x3f) if (tempcodepoint > 0x7f) { codepoint = tempcodepoint } } break case 3: secondbyte = buf[i + 1] thirdbyte = buf[i + 2] if ((secondbyte & 0xc0) === 0x80 && (thirdbyte & 0xc0) === 0x80) { tempcodepoint = (firstbyte & 0xf) << 0xc | (secondbyte & 0x3f) << 0x6 | (thirdbyte & 0x3f) if (tempcodepoint > 0x7ff && (tempcodepoint < 0xd800 || tempcodepoint > 0xdfff)) { codepoint = tempcodepoint } } break case 4: secondbyte = buf[i + 1] thirdbyte = buf[i + 2] fourthbyte = buf[i + 3] if ((secondbyte & 0xc0) === 0x80 && (thirdbyte & 0xc0) === 0x80 && (fourthbyte & 0xc0) === 0x80) { tempcodepoint = (firstbyte & 0xf) << 0x12 | (secondbyte & 0x3f) << 0xc | (thirdbyte & 0x3f) << 0x6 | (fourthbyte & 0x3f) if (tempcodepoint > 0xffff && tempcodepoint < 0x110000) { codepoint = tempcodepoint } } } } if (codepoint === null) { // we did not generate a valid codepoint so insert a // replacement char (u+fffd) and advance only 1 byte codepoint = 0xfffd bytespersequence = 1 } else if (codepoint > 0xffff) { // encode to utf16 (surrogate pair dance) codepoint -= 0x10000 res.push(codepoint >>> 10 & 0x3ff | 0xd800) codepoint = 0xdc00 | codepoint & 0x3ff } res.push(codepoint) i += bytespersequence } return decodecodepointsarray(res) } // based on http://stackoverflow.com/a/22747272/680742, the browser with // the lowest limit is chrome, with 0x10000 args. // we go 1 magnitude less, for safety var max_arguments_length = 0x1000 function decodecodepointsarray (codepoints) { var len = codepoints.length if (len <= max_arguments_length) { return string.fromcharcode.apply(string, codepoints) // avoid extra slice() } // decode in chunks to avoid "call stack size exceeded". var res = '' var i = 0 while (i < len) { res += string.fromcharcode.apply( string, codepoints.slice(i, i += max_arguments_length) ) } return res } function asciislice (buf, start, end) { var ret = '' end = math.min(buf.length, end) for (var i = start; i < end; ++i) { ret += string.fromcharcode(buf[i] & 0x7f) } return ret } function latin1slice (buf, start, end) { var ret = '' end = math.min(buf.length, end) for (var i = start; i < end; ++i) { ret += string.fromcharcode(buf[i]) } return ret } function hexslice (buf, start, end) { var len = buf.length if (!start || start < 0) start = 0 if (!end || end < 0 || end > len) end = len var out = '' for (var i = start; i < end; ++i) { out += tohex(buf[i]) } return out } function utf16leslice (buf, start, end) { var bytes = buf.slice(start, end) var res = '' for (var i = 0; i < bytes.length; i += 2) { res += string.fromcharcode(bytes[i] + bytes[i + 1] * 256) } return res } buffer.prototype.slice = function slice (start, end) { var len = this.length start = ~~start end = end === undefined ? len : ~~end if (start < 0) { start += len if (start < 0) start = 0 } else if (start > len) { start = len } if (end < 0) { end += len if (end < 0) end = 0 } else if (end > len) { end = len } if (end < start) end = start var newbuf if (buffer.typed_array_support) { newbuf = this.subarray(start, end) newbuf.__proto__ = buffer.prototype } else { var slicelen = end - start newbuf = new buffer(slicelen, undefined) for (var i = 0; i < slicelen; ++i) { newbuf[i] = this[i + start] } } return newbuf } /* * need to make sure that buffer isn't trying to write out of bounds. */ function checkoffset (offset, ext, length) { if ((offset % 1) !== 0 || offset < 0) throw new rangeerror('offset is not uint') if (offset + ext > length) throw new rangeerror('trying to access beyond buffer length') } buffer.prototype.readuintle = function readuintle (offset, bytelength, noassert) { offset = offset | 0 bytelength = bytelength | 0 if (!noassert) checkoffset(offset, bytelength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < bytelength && (mul *= 0x100)) { val += this[offset + i] * mul } return val } buffer.prototype.readuintbe = function readuintbe (offset, bytelength, noassert) { offset = offset | 0 bytelength = bytelength | 0 if (!noassert) { checkoffset(offset, bytelength, this.length) } var val = this[offset + --bytelength] var mul = 1 while (bytelength > 0 && (mul *= 0x100)) { val += this[offset + --bytelength] * mul } return val } buffer.prototype.readuint8 = function readuint8 (offset, noassert) { if (!noassert) checkoffset(offset, 1, this.length) return this[offset] } buffer.prototype.readuint16le = function readuint16le (offset, noassert) { if (!noassert) checkoffset(offset, 2, this.length) return this[offset] | (this[offset + 1] << 8) } buffer.prototype.readuint16be = function readuint16be (offset, noassert) { if (!noassert) checkoffset(offset, 2, this.length) return (this[offset] << 8) | this[offset + 1] } buffer.prototype.readuint32le = function readuint32le (offset, noassert) { if (!noassert) checkoffset(offset, 4, this.length) return ((this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16)) + (this[offset + 3] * 0x1000000) } buffer.prototype.readuint32be = function readuint32be (offset, noassert) { if (!noassert) checkoffset(offset, 4, this.length) return (this[offset] * 0x1000000) + ((this[offset + 1] << 16) | (this[offset + 2] << 8) | this[offset + 3]) } buffer.prototype.readintle = function readintle (offset, bytelength, noassert) { offset = offset | 0 bytelength = bytelength | 0 if (!noassert) checkoffset(offset, bytelength, this.length) var val = this[offset] var mul = 1 var i = 0 while (++i < bytelength && (mul *= 0x100)) { val += this[offset + i] * mul } mul *= 0x80 if (val >= mul) val -= math.pow(2, 8 * bytelength) return val } buffer.prototype.readintbe = function readintbe (offset, bytelength, noassert) { offset = offset | 0 bytelength = bytelength | 0 if (!noassert) checkoffset(offset, bytelength, this.length) var i = bytelength var mul = 1 var val = this[offset + --i] while (i > 0 && (mul *= 0x100)) { val += this[offset + --i] * mul } mul *= 0x80 if (val >= mul) val -= math.pow(2, 8 * bytelength) return val } buffer.prototype.readint8 = function readint8 (offset, noassert) { if (!noassert) checkoffset(offset, 1, this.length) if (!(this[offset] & 0x80)) return (this[offset]) return ((0xff - this[offset] + 1) * -1) } buffer.prototype.readint16le = function readint16le (offset, noassert) { if (!noassert) checkoffset(offset, 2, this.length) var val = this[offset] | (this[offset + 1] << 8) return (val & 0x8000) ? val | 0xffff0000 : val } buffer.prototype.readint16be = function readint16be (offset, noassert) { if (!noassert) checkoffset(offset, 2, this.length) var val = this[offset + 1] | (this[offset] << 8) return (val & 0x8000) ? val | 0xffff0000 : val } buffer.prototype.readint32le = function readint32le (offset, noassert) { if (!noassert) checkoffset(offset, 4, this.length) return (this[offset]) | (this[offset + 1] << 8) | (this[offset + 2] << 16) | (this[offset + 3] << 24) } buffer.prototype.readint32be = function readint32be (offset, noassert) { if (!noassert) checkoffset(offset, 4, this.length) return (this[offset] << 24) | (this[offset + 1] << 16) | (this[offset + 2] << 8) | (this[offset + 3]) } buffer.prototype.readfloatle = function readfloatle (offset, noassert) { if (!noassert) checkoffset(offset, 4, this.length) return ieee754.read(this, offset, true, 23, 4) } buffer.prototype.readfloatbe = function readfloatbe (offset, noassert) { if (!noassert) checkoffset(offset, 4, this.length) return ieee754.read(this, offset, false, 23, 4) } buffer.prototype.readdoublele = function readdoublele (offset, noassert) { if (!noassert) checkoffset(offset, 8, this.length) return ieee754.read(this, offset, true, 52, 8) } buffer.prototype.readdoublebe = function readdoublebe (offset, noassert) { if (!noassert) checkoffset(offset, 8, this.length) return ieee754.read(this, offset, false, 52, 8) } function checkint (buf, value, offset, ext, max, min) { if (!buffer.isbuffer(buf)) throw new typeerror('"buffer" argument must be a buffer instance') if (value > max || value < min) throw new rangeerror('"value" argument is out of bounds') if (offset + ext > buf.length) throw new rangeerror('index out of range') } buffer.prototype.writeuintle = function writeuintle (value, offset, bytelength, noassert) { value = +value offset = offset | 0 bytelength = bytelength | 0 if (!noassert) { var maxbytes = math.pow(2, 8 * bytelength) - 1 checkint(this, value, offset, bytelength, maxbytes, 0) } var mul = 1 var i = 0 this[offset] = value & 0xff while (++i < bytelength && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xff } return offset + bytelength } buffer.prototype.writeuintbe = function writeuintbe (value, offset, bytelength, noassert) { value = +value offset = offset | 0 bytelength = bytelength | 0 if (!noassert) { var maxbytes = math.pow(2, 8 * bytelength) - 1 checkint(this, value, offset, bytelength, maxbytes, 0) } var i = bytelength - 1 var mul = 1 this[offset + i] = value & 0xff while (--i >= 0 && (mul *= 0x100)) { this[offset + i] = (value / mul) & 0xff } return offset + bytelength } buffer.prototype.writeuint8 = function writeuint8 (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 1, 0xff, 0) if (!buffer.typed_array_support) value = math.floor(value) this[offset] = (value & 0xff) return offset + 1 } function objectwriteuint16 (buf, value, offset, littleendian) { if (value < 0) value = 0xffff + value + 1 for (var i = 0, j = math.min(buf.length - offset, 2); i < j; ++i) { buf[offset + i] = (value & (0xff << (8 * (littleendian ? i : 1 - i)))) >>> (littleendian ? i : 1 - i) * 8 } } buffer.prototype.writeuint16le = function writeuint16le (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 2, 0xffff, 0) if (buffer.typed_array_support) { this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) } else { objectwriteuint16(this, value, offset, true) } return offset + 2 } buffer.prototype.writeuint16be = function writeuint16be (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 2, 0xffff, 0) if (buffer.typed_array_support) { this[offset] = (value >>> 8) this[offset + 1] = (value & 0xff) } else { objectwriteuint16(this, value, offset, false) } return offset + 2 } function objectwriteuint32 (buf, value, offset, littleendian) { if (value < 0) value = 0xffffffff + value + 1 for (var i = 0, j = math.min(buf.length - offset, 4); i < j; ++i) { buf[offset + i] = (value >>> (littleendian ? i : 3 - i) * 8) & 0xff } } buffer.prototype.writeuint32le = function writeuint32le (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 4, 0xffffffff, 0) if (buffer.typed_array_support) { this[offset + 3] = (value >>> 24) this[offset + 2] = (value >>> 16) this[offset + 1] = (value >>> 8) this[offset] = (value & 0xff) } else { objectwriteuint32(this, value, offset, true) } return offset + 4 } buffer.prototype.writeuint32be = function writeuint32be (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 4, 0xffffffff, 0) if (buffer.typed_array_support) { this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = (value & 0xff) } else { objectwriteuint32(this, value, offset, false) } return offset + 4 } buffer.prototype.writeintle = function writeintle (value, offset, bytelength, noassert) { value = +value offset = offset | 0 if (!noassert) { var limit = math.pow(2, 8 * bytelength - 1) checkint(this, value, offset, bytelength, limit - 1, -limit) } var i = 0 var mul = 1 var sub = 0 this[offset] = value & 0xff while (++i < bytelength && (mul *= 0x100)) { if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { sub = 1 } this[offset + i] = ((value / mul) >> 0) - sub & 0xff } return offset + bytelength } buffer.prototype.writeintbe = function writeintbe (value, offset, bytelength, noassert) { value = +value offset = offset | 0 if (!noassert) { var limit = math.pow(2, 8 * bytelength - 1) checkint(this, value, offset, bytelength, limit - 1, -limit) } var i = bytelength - 1 var mul = 1 var sub = 0 this[offset + i] = value & 0xff while (--i >= 0 && (mul *= 0x100)) { if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { sub = 1 } this[offset + i] = ((value / mul) >> 0) - sub & 0xff } return offset + bytelength } buffer.prototype.writeint8 = function writeint8 (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 1, 0x7f, -0x80) if (!buffer.typed_array_support) value = math.floor(value) if (value < 0) value = 0xff + value + 1 this[offset] = (value & 0xff) return offset + 1 } buffer.prototype.writeint16le = function writeint16le (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 2, 0x7fff, -0x8000) if (buffer.typed_array_support) { this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) } else { objectwriteuint16(this, value, offset, true) } return offset + 2 } buffer.prototype.writeint16be = function writeint16be (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 2, 0x7fff, -0x8000) if (buffer.typed_array_support) { this[offset] = (value >>> 8) this[offset + 1] = (value & 0xff) } else { objectwriteuint16(this, value, offset, false) } return offset + 2 } buffer.prototype.writeint32le = function writeint32le (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 4, 0x7fffffff, -0x80000000) if (buffer.typed_array_support) { this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) this[offset + 2] = (value >>> 16) this[offset + 3] = (value >>> 24) } else { objectwriteuint32(this, value, offset, true) } return offset + 4 } buffer.prototype.writeint32be = function writeint32be (value, offset, noassert) { value = +value offset = offset | 0 if (!noassert) checkint(this, value, offset, 4, 0x7fffffff, -0x80000000) if (value < 0) value = 0xffffffff + value + 1 if (buffer.typed_array_support) { this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) this[offset + 3] = (value & 0xff) } else { objectwriteuint32(this, value, offset, false) } return offset + 4 } function checkieee754 (buf, value, offset, ext, max, min) { if (offset + ext > buf.length) throw new rangeerror('index out of range') if (offset < 0) throw new rangeerror('index out of range') } function writefloat (buf, value, offset, littleendian, noassert) { if (!noassert) { checkieee754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) } ieee754.write(buf, value, offset, littleendian, 23, 4) return offset + 4 } buffer.prototype.writefloatle = function writefloatle (value, offset, noassert) { return writefloat(this, value, offset, true, noassert) } buffer.prototype.writefloatbe = function writefloatbe (value, offset, noassert) { return writefloat(this, value, offset, false, noassert) } function writedouble (buf, value, offset, littleendian, noassert) { if (!noassert) { checkieee754(buf, value, offset, 8, 1.7976931348623157e+308, -1.7976931348623157e+308) } ieee754.write(buf, value, offset, littleendian, 52, 8) return offset + 8 } buffer.prototype.writedoublele = function writedoublele (value, offset, noassert) { return writedouble(this, value, offset, true, noassert) } buffer.prototype.writedoublebe = function writedoublebe (value, offset, noassert) { return writedouble(this, value, offset, false, noassert) } // copy(targetbuffer, targetstart=0, sourcestart=0, sourceend=buffer.length) buffer.prototype.copy = function copy (target, targetstart, start, end) { if (!start) start = 0 if (!end && end !== 0) end = this.length if (targetstart >= target.length) targetstart = target.length if (!targetstart) targetstart = 0 if (end > 0 && end < start) end = start // copy 0 bytes; we're done if (end === start) return 0 if (target.length === 0 || this.length === 0) return 0 // fatal error conditions if (targetstart < 0) { throw new rangeerror('targetstart out of bounds') } if (start < 0 || start >= this.length) throw new rangeerror('sourcestart out of bounds') if (end < 0) throw new rangeerror('sourceend out of bounds') // are we oob? if (end > this.length) end = this.length if (target.length - targetstart < end - start) { end = target.length - targetstart + start } var len = end - start var i if (this === target && start < targetstart && targetstart < end) { // descending copy from end for (i = len - 1; i >= 0; --i) { target[i + targetstart] = this[i + start] } } else if (len < 1000 || !buffer.typed_array_support) { // ascending copy from start for (i = 0; i < len; ++i) { target[i + targetstart] = this[i + start] } } else { uint8array.prototype.set.call( target, this.subarray(start, start + len), targetstart ) } return len } // usage: // buffer.fill(number[, offset[, end]]) // buffer.fill(buffer[, offset[, end]]) // buffer.fill(string[, offset[, end]][, encoding]) buffer.prototype.fill = function fill (val, start, end, encoding) { // handle string cases: if (typeof val === 'string') { if (typeof start === 'string') { encoding = start start = 0 end = this.length } else if (typeof end === 'string') { encoding = end end = this.length } if (val.length === 1) { var code = val.charcodeat(0) if (code < 256) { val = code } } if (encoding !== undefined && typeof encoding !== 'string') { throw new typeerror('encoding must be a string') } if (typeof encoding === 'string' && !buffer.isencoding(encoding)) { throw new typeerror('unknown encoding: ' + encoding) } } else if (typeof val === 'number') { val = val & 255 } // invalid ranges are not set to a default, so can range check early. if (start < 0 || this.length < start || this.length < end) { throw new rangeerror('out of range index') } if (end <= start) { return this } start = start >>> 0 end = end === undefined ? this.length : end >>> 0 if (!val) val = 0 var i if (typeof val === 'number') { for (i = start; i < end; ++i) { this[i] = val } } else { var bytes = buffer.isbuffer(val) ? val : utf8tobytes(new buffer(val, encoding).tostring()) var len = bytes.length for (i = 0; i < end - start; ++i) { this[i + start] = bytes[i % len] } } return this } // helper functions // ================ var invalid_base64_re = /[^+\/0-9a-za-z-_]/g function base64clean (str) { // node strips out invalid characters like \n and \t from the string, base64-js does not str = stringtrim(str).replace(invalid_base64_re, '') // node converts strings with length < 2 to '' if (str.length < 2) return '' // node allows for non-padded base64 strings (missing trailing ===), base64-js does not while (str.length % 4 !== 0) { str = str + '=' } return str } function stringtrim (str) { if (str.trim) return str.trim() return str.replace(/^\s+|\s+$/g, '') } function tohex (n) { if (n < 16) return '0' + n.tostring(16) return n.tostring(16) } function utf8tobytes (string, units) { units = units || infinity var codepoint var length = string.length var leadsurrogate = null var bytes = [] for (var i = 0; i < length; ++i) { codepoint = string.charcodeat(i) // is surrogate component if (codepoint > 0xd7ff && codepoint < 0xe000) { // last char was a lead if (!leadsurrogate) { // no lead yet if (codepoint > 0xdbff) { // unexpected trail if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd) continue } else if (i + 1 === length) { // unpaired lead if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd) continue } // valid lead leadsurrogate = codepoint continue } // 2 leads in a row if (codepoint < 0xdc00) { if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd) leadsurrogate = codepoint continue } // valid surrogate pair codepoint = (leadsurrogate - 0xd800 << 10 | codepoint - 0xdc00) + 0x10000 } else if (leadsurrogate) { // valid bmp char, but last char was a lead if ((units -= 3) > -1) bytes.push(0xef, 0xbf, 0xbd) } leadsurrogate = null // encode utf8 if (codepoint < 0x80) { if ((units -= 1) < 0) break bytes.push(codepoint) } else if (codepoint < 0x800) { if ((units -= 2) < 0) break bytes.push( codepoint >> 0x6 | 0xc0, codepoint & 0x3f | 0x80 ) } else if (codepoint < 0x10000) { if ((units -= 3) < 0) break bytes.push( codepoint >> 0xc | 0xe0, codepoint >> 0x6 & 0x3f | 0x80, codepoint & 0x3f | 0x80 ) } else if (codepoint < 0x110000) { if ((units -= 4) < 0) break bytes.push( codepoint >> 0x12 | 0xf0, codepoint >> 0xc & 0x3f | 0x80, codepoint >> 0x6 & 0x3f | 0x80, codepoint & 0x3f | 0x80 ) } else { throw new error('invalid code point') } } return bytes } function asciitobytes (str) { var bytearray = [] for (var i = 0; i < str.length; ++i) { // node's code seems to be doing this and not & 0x7f.. bytearray.push(str.charcodeat(i) & 0xff) } return bytearray } function utf16letobytes (str, units) { var c, hi, lo var bytearray = [] for (var i = 0; i < str.length; ++i) { if ((units -= 2) < 0) break c = str.charcodeat(i) hi = c >> 8 lo = c % 256 bytearray.push(lo) bytearray.push(hi) } return bytearray } function base64tobytes (str) { return base64.tobytearray(base64clean(str)) } function blitbuffer (src, dst, offset, length) { for (var i = 0; i < length; ++i) { if ((i + offset >= dst.length) || (i >= src.length)) break dst[i + offset] = src[i] } return i } function isnan (val) { return val !== val // eslint-disable-line no-self-compare } /* webpack var injection */}.call(this, __webpack_require__(15))) /***/ }), /***/ 322: /***/ (function(module, exports) { var max_uint32 = math.pow(2, 32); var getuint64 = function(uint8) { var dv = new dataview(uint8.buffer, uint8.byteoffset, uint8.bytelength); var value; if (dv.getbiguint64) { value = dv.getbiguint64(0); if (value < number.max_safe_integer) { return number(value); } return value; } return (dv.getuint32(0) * max_uint32) + dv.getuint32(4); }; module.exports = { getuint64: getuint64, max_uint32: max_uint32 }; /***/ }), /***/ 325: /***/ (function(module, exports, __webpack_require__) { "use strict"; var getsidechannel = __webpack_require__(326); var utils = __webpack_require__(178); var formats = __webpack_require__(110); var has = object.prototype.hasownproperty; var arrayprefixgenerators = { brackets: function brackets(prefix) { return prefix + '[]'; }, comma: 'comma', indices: function indices(prefix, key) { return prefix + '[' + key + ']'; }, repeat: function repeat(prefix) { return prefix; } }; var isarray = array.isarray; var split = string.prototype.split; var push = array.prototype.push; var pushtoarray = function (arr, valueorarray) { push.apply(arr, isarray(valueorarray) ? valueorarray : [valueorarray]); }; var toiso = date.prototype.toisostring; var defaultformat = formats['default']; var defaults = { addqueryprefix: false, allowdots: false, charset: 'utf-8', charsetsentinel: false, delimiter: '&', encode: true, encoder: utils.encode, encodevaluesonly: false, format: defaultformat, formatter: formats.formatters[defaultformat], // deprecated indices: false, serializedate: function serializedate(date) { return toiso.call(date); }, skipnulls: false, strictnullhandling: false }; var isnonnullishprimitive = function isnonnullishprimitive(v) { return typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' || typeof v === 'symbol' || typeof v === 'bigint'; }; var sentinel = {}; var stringify = function stringify( object, prefix, generatearrayprefix, commaroundtrip, strictnullhandling, skipnulls, encoder, filter, sort, allowdots, serializedate, format, formatter, encodevaluesonly, charset, sidechannel ) { var obj = object; var tmpsc = sidechannel; var step = 0; var findflag = false; while ((tmpsc = tmpsc.get(sentinel)) !== void undefined && !findflag) { // where object last appeared in the ref tree var pos = tmpsc.get(object); step += 1; if (typeof pos !== 'undefined') { if (pos === step) { throw new rangeerror('cyclic object value'); } else { findflag = true; // break while } } if (typeof tmpsc.get(sentinel) === 'undefined') { step = 0; } } if (typeof filter === 'function') { obj = filter(prefix, obj); } else if (obj instanceof date) { obj = serializedate(obj); } else if (generatearrayprefix === 'comma' && isarray(obj)) { obj = utils.maybemap(obj, function (value) { if (value instanceof date) { return serializedate(value); } return value; }); } if (obj === null) { if (strictnullhandling) { return encoder && !encodevaluesonly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix; } obj = ''; } if (isnonnullishprimitive(obj) || utils.isbuffer(obj)) { if (encoder) { var keyvalue = encodevaluesonly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format); if (generatearrayprefix === 'comma' && encodevaluesonly) { var valuesarray = split.call(string(obj), ','); var valuesjoined = ''; for (var i = 0; i < valuesarray.length; ++i) { valuesjoined += (i === 0 ? '' : ',') + formatter(encoder(valuesarray[i], defaults.encoder, charset, 'value', format)); } return [formatter(keyvalue) + (commaroundtrip && isarray(obj) && valuesarray.length === 1 ? '[]' : '') + '=' + valuesjoined]; } return [formatter(keyvalue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))]; } return [formatter(prefix) + '=' + formatter(string(obj))]; } var values = []; if (typeof obj === 'undefined') { return values; } var objkeys; if (generatearrayprefix === 'comma' && isarray(obj)) { // we need to join elements in objkeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }]; } else if (isarray(filter)) { objkeys = filter; } else { var keys = object.keys(obj); objkeys = sort ? keys.sort(sort) : keys; } var adjustedprefix = commaroundtrip && isarray(obj) && obj.length === 1 ? prefix + '[]' : prefix; for (var j = 0; j < objkeys.length; ++j) { var key = objkeys[j]; var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key]; if (skipnulls && value === null) { continue; } var keyprefix = isarray(obj) ? typeof generatearrayprefix === 'function' ? generatearrayprefix(adjustedprefix, key) : adjustedprefix : adjustedprefix + (allowdots ? '.' + key : '[' + key + ']'); sidechannel.set(object, step); var valuesidechannel = getsidechannel(); valuesidechannel.set(sentinel, sidechannel); pushtoarray(values, stringify( value, keyprefix, generatearrayprefix, commaroundtrip, strictnullhandling, skipnulls, encoder, filter, sort, allowdots, serializedate, format, formatter, encodevaluesonly, charset, valuesidechannel )); } return values; }; var normalizestringifyoptions = function normalizestringifyoptions(opts) { if (!opts) { return defaults; } if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') { throw new typeerror('encoder has to be a function.'); } var charset = opts.charset || defaults.charset; if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { throw new typeerror('the charset option must be either utf-8, iso-8859-1, or undefined'); } var format = formats['default']; if (typeof opts.format !== 'undefined') { if (!has.call(formats.formatters, opts.format)) { throw new typeerror('unknown format option provided.'); } format = opts.format; } var formatter = formats.formatters[format]; var filter = defaults.filter; if (typeof opts.filter === 'function' || isarray(opts.filter)) { filter = opts.filter; } return { addqueryprefix: typeof opts.addqueryprefix === 'boolean' ? opts.addqueryprefix : defaults.addqueryprefix, allowdots: typeof opts.allowdots === 'undefined' ? defaults.allowdots : !!opts.allowdots, charset: charset, charsetsentinel: typeof opts.charsetsentinel === 'boolean' ? opts.charsetsentinel : defaults.charsetsentinel, delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, encodevaluesonly: typeof opts.encodevaluesonly === 'boolean' ? opts.encodevaluesonly : defaults.encodevaluesonly, filter: filter, format: format, formatter: formatter, serializedate: typeof opts.serializedate === 'function' ? opts.serializedate : defaults.serializedate, skipnulls: typeof opts.skipnulls === 'boolean' ? opts.skipnulls : defaults.skipnulls, sort: typeof opts.sort === 'function' ? opts.sort : null, strictnullhandling: typeof opts.strictnullhandling === 'boolean' ? opts.strictnullhandling : defaults.strictnullhandling }; }; module.exports = function (object, opts) { var obj = object; var options = normalizestringifyoptions(opts); var objkeys; var filter; if (typeof options.filter === 'function') { filter = options.filter; obj = filter('', obj); } else if (isarray(options.filter)) { filter = options.filter; objkeys = filter; } var keys = []; if (typeof obj !== 'object' || obj === null) { return ''; } var arrayformat; if (opts && opts.arrayformat in arrayprefixgenerators) { arrayformat = opts.arrayformat; } else if (opts && 'indices' in opts) { arrayformat = opts.indices ? 'indices' : 'repeat'; } else { arrayformat = 'indices'; } var generatearrayprefix = arrayprefixgenerators[arrayformat]; if (opts && 'commaroundtrip' in opts && typeof opts.commaroundtrip !== 'boolean') { throw new typeerror('`commaroundtrip` must be a boolean, or absent'); } var commaroundtrip = generatearrayprefix === 'comma' && opts && opts.commaroundtrip; if (!objkeys) { objkeys = object.keys(obj); } if (options.sort) { objkeys.sort(options.sort); } var sidechannel = getsidechannel(); for (var i = 0; i < objkeys.length; ++i) { var key = objkeys[i]; if (options.skipnulls && obj[key] === null) { continue; } pushtoarray(keys, stringify( obj[key], key, generatearrayprefix, commaroundtrip, options.strictnullhandling, options.skipnulls, options.encode ? options.encoder : null, options.filter, options.sort, options.allowdots, options.serializedate, options.format, options.formatter, options.encodevaluesonly, options.charset, sidechannel )); } var joined = keys.join(options.delimiter); var prefix = options.addqueryprefix === true ? '?' : ''; if (options.charsetsentinel) { if (options.charset === 'iso-8859-1') { // encodeuricomponent('✓'), the "numeric entity" representation of a checkmark prefix += 'utf8=%26%2310003%3b&'; } else { // encodeuricomponent('✓') prefix += 'utf8=%e2%9c%93&'; } } return joined.length > 0 ? prefix + joined : ''; }; /***/ }), /***/ 333: /***/ (function(module, exports, __webpack_require__) { var hasmap = typeof map === 'function' && map.prototype; var mapsizedescriptor = object.getownpropertydescriptor && hasmap ? object.getownpropertydescriptor(map.prototype, 'size') : null; var mapsize = hasmap && mapsizedescriptor && typeof mapsizedescriptor.get === 'function' ? mapsizedescriptor.get : null; var mapforeach = hasmap && map.prototype.foreach; var hasset = typeof set === 'function' && set.prototype; var setsizedescriptor = object.getownpropertydescriptor && hasset ? object.getownpropertydescriptor(set.prototype, 'size') : null; var setsize = hasset && setsizedescriptor && typeof setsizedescriptor.get === 'function' ? setsizedescriptor.get : null; var setforeach = hasset && set.prototype.foreach; var hasweakmap = typeof weakmap === 'function' && weakmap.prototype; var weakmaphas = hasweakmap ? weakmap.prototype.has : null; var hasweakset = typeof weakset === 'function' && weakset.prototype; var weaksethas = hasweakset ? weakset.prototype.has : null; var hasweakref = typeof weakref === 'function' && weakref.prototype; var weakrefderef = hasweakref ? weakref.prototype.deref : null; var booleanvalueof = boolean.prototype.valueof; var objecttostring = object.prototype.tostring; var functiontostring = function.prototype.tostring; var $match = string.prototype.match; var $slice = string.prototype.slice; var $replace = string.prototype.replace; var $touppercase = string.prototype.touppercase; var $tolowercase = string.prototype.tolowercase; var $test = regexp.prototype.test; var $concat = array.prototype.concat; var $join = array.prototype.join; var $arrslice = array.prototype.slice; var $floor = math.floor; var bigintvalueof = typeof bigint === 'function' ? bigint.prototype.valueof : null; var gops = object.getownpropertysymbols; var symtostring = typeof symbol === 'function' && typeof symbol.iterator === 'symbol' ? symbol.prototype.tostring : null; var hasshammedsymbols = typeof symbol === 'function' && typeof symbol.iterator === 'object'; // ie, `has-tostringtag/shams var tostringtag = typeof symbol === 'function' && symbol.tostringtag && (typeof symbol.tostringtag === hasshammedsymbols ? 'object' : 'symbol') ? symbol.tostringtag : null; var isenumerable = object.prototype.propertyisenumerable; var gpo = (typeof reflect === 'function' ? reflect.getprototypeof : object.getprototypeof) || ( [].__proto__ === array.prototype // eslint-disable-line no-proto ? function (o) { return o.__proto__; // eslint-disable-line no-proto } : null ); function addnumericseparator(num, str) { if ( num === infinity || num === -infinity || num !== num || (num && num > -1000 && num < 1000) || $test.call(/e/, str) ) { return str; } var sepregex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g; if (typeof num === 'number') { var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num) if (int !== num) { var intstr = string(int); var dec = $slice.call(str, intstr.length + 1); return $replace.call(intstr, sepregex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, ''); } } return $replace.call(str, sepregex, '$&_'); } var utilinspect = __webpack_require__(334); var inspectcustom = utilinspect.custom; var inspectsymbol = issymbol(inspectcustom) ? inspectcustom : null; module.exports = function inspect_(obj, options, depth, seen) { var opts = options || {}; if (has(opts, 'quotestyle') && (opts.quotestyle !== 'single' && opts.quotestyle !== 'double')) { throw new typeerror('option "quotestyle" must be "single" or "double"'); } if ( has(opts, 'maxstringlength') && (typeof opts.maxstringlength === 'number' ? opts.maxstringlength < 0 && opts.maxstringlength !== infinity : opts.maxstringlength !== null ) ) { throw new typeerror('option "maxstringlength", if provided, must be a positive integer, infinity, or `null`'); } var custominspect = has(opts, 'custominspect') ? opts.custominspect : true; if (typeof custominspect !== 'boolean' && custominspect !== 'symbol') { throw new typeerror('option "custominspect", if provided, must be `true`, `false`, or `\'symbol\'`'); } if ( has(opts, 'indent') && opts.indent !== null && opts.indent !== '\t' && !(parseint(opts.indent, 10) === opts.indent && opts.indent > 0) ) { throw new typeerror('option "indent" must be "\\t", an integer > 0, or `null`'); } if (has(opts, 'numericseparator') && typeof opts.numericseparator !== 'boolean') { throw new typeerror('option "numericseparator", if provided, must be `true` or `false`'); } var numericseparator = opts.numericseparator; if (typeof obj === 'undefined') { return 'undefined'; } if (obj === null) { return 'null'; } if (typeof obj === 'boolean') { return obj ? 'true' : 'false'; } if (typeof obj === 'string') { return inspectstring(obj, opts); } if (typeof obj === 'number') { if (obj === 0) { return infinity / obj > 0 ? '0' : '-0'; } var str = string(obj); return numericseparator ? addnumericseparator(obj, str) : str; } if (typeof obj === 'bigint') { var bigintstr = string(obj) + 'n'; return numericseparator ? addnumericseparator(obj, bigintstr) : bigintstr; } var maxdepth = typeof opts.depth === 'undefined' ? 5 : opts.depth; if (typeof depth === 'undefined') { depth = 0; } if (depth >= maxdepth && maxdepth > 0 && typeof obj === 'object') { return isarray(obj) ? '[array]' : '[object]'; } var indent = getindent(opts, depth); if (typeof seen === 'undefined') { seen = []; } else if (indexof(seen, obj) >= 0) { return '[circular]'; } function inspect(value, from, noindent) { if (from) { seen = $arrslice.call(seen); seen.push(from); } if (noindent) { var newopts = { depth: opts.depth }; if (has(opts, 'quotestyle')) { newopts.quotestyle = opts.quotestyle; } return inspect_(value, newopts, depth + 1, seen); } return inspect_(value, opts, depth + 1, seen); } if (typeof obj === 'function' && !isregexp(obj)) { // in older engines, regexes are callable var name = nameof(obj); var keys = arrobjkeys(obj, inspect); return '[function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : ''); } if (issymbol(obj)) { var symstring = hasshammedsymbols ? $replace.call(string(obj), /^(symbol\(.*\))_[^)]*$/, '$1') : symtostring.call(obj); return typeof obj === 'object' && !hasshammedsymbols ? markboxed(symstring) : symstring; } if (iselement(obj)) { var s = '<' + $tolowercase.call(string(obj.nodename)); var attrs = obj.attributes || []; for (var i = 0; i < attrs.length; i++) { s += ' ' + attrs[i].name + '=' + wrapquotes(quote(attrs[i].value), 'double', opts); } s += '>'; if (obj.childnodes && obj.childnodes.length) { s += '...'; } s += ''; return s; } if (isarray(obj)) { if (obj.length === 0) { return '[]'; } var xs = arrobjkeys(obj, inspect); if (indent && !singlelinevalues(xs)) { return '[' + indentedjoin(xs, indent) + ']'; } return '[ ' + $join.call(xs, ', ') + ' ]'; } if (iserror(obj)) { var parts = arrobjkeys(obj, inspect); if (!('cause' in error.prototype) && 'cause' in obj && !isenumerable.call(obj, 'cause')) { return '{ [' + string(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }'; } if (parts.length === 0) { return '[' + string(obj) + ']'; } return '{ [' + string(obj) + '] ' + $join.call(parts, ', ') + ' }'; } if (typeof obj === 'object' && custominspect) { if (inspectsymbol && typeof obj[inspectsymbol] === 'function' && utilinspect) { return utilinspect(obj, { depth: maxdepth - depth }); } else if (custominspect !== 'symbol' && typeof obj.inspect === 'function') { return obj.inspect(); } } if (ismap(obj)) { var mapparts = []; mapforeach.call(obj, function (value, key) { mapparts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj)); }); return collectionof('map', mapsize.call(obj), mapparts, indent); } if (isset(obj)) { var setparts = []; setforeach.call(obj, function (value) { setparts.push(inspect(value, obj)); }); return collectionof('set', setsize.call(obj), setparts, indent); } if (isweakmap(obj)) { return weakcollectionof('weakmap'); } if (isweakset(obj)) { return weakcollectionof('weakset'); } if (isweakref(obj)) { return weakcollectionof('weakref'); } if (isnumber(obj)) { return markboxed(inspect(number(obj))); } if (isbigint(obj)) { return markboxed(inspect(bigintvalueof.call(obj))); } if (isboolean(obj)) { return markboxed(booleanvalueof.call(obj)); } if (isstring(obj)) { return markboxed(inspect(string(obj))); } if (!isdate(obj) && !isregexp(obj)) { var ys = arrobjkeys(obj, inspect); var isplainobject = gpo ? gpo(obj) === object.prototype : obj instanceof object || obj.constructor === object; var prototag = obj instanceof object ? '' : 'null prototype'; var stringtag = !isplainobject && tostringtag && object(obj) === obj && tostringtag in obj ? $slice.call(tostr(obj), 8, -1) : prototag ? 'object' : ''; var constructortag = isplainobject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : ''; var tag = constructortag + (stringtag || prototag ? '[' + $join.call($concat.call([], stringtag || [], prototag || []), ': ') + '] ' : ''); if (ys.length === 0) { return tag + '{}'; } if (indent) { return tag + '{' + indentedjoin(ys, indent) + '}'; } return tag + '{ ' + $join.call(ys, ', ') + ' }'; } return string(obj); }; function wrapquotes(s, defaultstyle, opts) { var quotechar = (opts.quotestyle || defaultstyle) === 'double' ? '"' : "'"; return quotechar + s + quotechar; } function quote(s) { return $replace.call(string(s), /"/g, '"'); } function isarray(obj) { return tostr(obj) === '[object array]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isdate(obj) { return tostr(obj) === '[object date]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isregexp(obj) { return tostr(obj) === '[object regexp]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function iserror(obj) { return tostr(obj) === '[object error]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isstring(obj) { return tostr(obj) === '[object string]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isnumber(obj) { return tostr(obj) === '[object number]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } function isboolean(obj) { return tostr(obj) === '[object boolean]' && (!tostringtag || !(typeof obj === 'object' && tostringtag in obj)); } // symbol and bigint do have symbol.tostringtag by spec, so that can't be used to eliminate false positives function issymbol(obj) { if (hasshammedsymbols) { return obj && typeof obj === 'object' && obj instanceof symbol; } if (typeof obj === 'symbol') { return true; } if (!obj || typeof obj !== 'object' || !symtostring) { return false; } try { symtostring.call(obj); return true; } catch (e) {} return false; } function isbigint(obj) { if (!obj || typeof obj !== 'object' || !bigintvalueof) { return false; } try { bigintvalueof.call(obj); return true; } catch (e) {} return false; } var hasown = object.prototype.hasownproperty || function (key) { return key in this; }; function has(obj, key) { return hasown.call(obj, key); } function tostr(obj) { return objecttostring.call(obj); } function nameof(f) { if (f.name) { return f.name; } var m = $match.call(functiontostring.call(f), /^function\s*([\w$]+)/); if (m) { return m[1]; } return null; } function indexof(xs, x) { if (xs.indexof) { return xs.indexof(x); } for (var i = 0, l = xs.length; i < l; i++) { if (xs[i] === x) { return i; } } return -1; } function ismap(x) { if (!mapsize || !x || typeof x !== 'object') { return false; } try { mapsize.call(x); try { setsize.call(x); } catch (s) { return true; } return x instanceof map; // core-js workaround, pre-v2.5.0 } catch (e) {} return false; } function isweakmap(x) { if (!weakmaphas || !x || typeof x !== 'object') { return false; } try { weakmaphas.call(x, weakmaphas); try { weaksethas.call(x, weaksethas); } catch (s) { return true; } return x instanceof weakmap; // core-js workaround, pre-v2.5.0 } catch (e) {} return false; } function isweakref(x) { if (!weakrefderef || !x || typeof x !== 'object') { return false; } try { weakrefderef.call(x); return true; } catch (e) {} return false; } function isset(x) { if (!setsize || !x || typeof x !== 'object') { return false; } try { setsize.call(x); try { mapsize.call(x); } catch (m) { return true; } return x instanceof set; // core-js workaround, pre-v2.5.0 } catch (e) {} return false; } function isweakset(x) { if (!weaksethas || !x || typeof x !== 'object') { return false; } try { weaksethas.call(x, weaksethas); try { weakmaphas.call(x, weakmaphas); } catch (s) { return true; } return x instanceof weakset; // core-js workaround, pre-v2.5.0 } catch (e) {} return false; } function iselement(x) { if (!x || typeof x !== 'object') { return false; } if (typeof htmlelement !== 'undefined' && x instanceof htmlelement) { return true; } return typeof x.nodename === 'string' && typeof x.getattribute === 'function'; } function inspectstring(str, opts) { if (str.length > opts.maxstringlength) { var remaining = str.length - opts.maxstringlength; var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : ''); return inspectstring($slice.call(str, 0, opts.maxstringlength), opts) + trailer; } // eslint-disable-next-line no-control-regex var s = $replace.call($replace.call(str, /(['\\])/g, '\\$1'), /[\x00-\x1f]/g, lowbyte); return wrapquotes(s, 'single', opts); } function lowbyte(c) { var n = c.charcodeat(0); var x = { 8: 'b', 9: 't', 10: 'n', 12: 'f', 13: 'r' }[n]; if (x) { return '\\' + x; } return '\\x' + (n < 0x10 ? '0' : '') + $touppercase.call(n.tostring(16)); } function markboxed(str) { return 'object(' + str + ')'; } function weakcollectionof(type) { return type + ' { ? }'; } function collectionof(type, size, entries, indent) { var joinedentries = indent ? indentedjoin(entries, indent) : $join.call(entries, ', '); return type + ' (' + size + ') {' + joinedentries + '}'; } function singlelinevalues(xs) { for (var i = 0; i < xs.length; i++) { if (indexof(xs[i], '\n') >= 0) { return false; } } return true; } function getindent(opts, depth) { var baseindent; if (opts.indent === '\t') { baseindent = '\t'; } else if (typeof opts.indent === 'number' && opts.indent > 0) { baseindent = $join.call(array(opts.indent + 1), ' '); } else { return null; } return { base: baseindent, prev: $join.call(array(depth + 1), baseindent) }; } function indentedjoin(xs, indent) { if (xs.length === 0) { return ''; } var linejoiner = '\n' + indent.prev + indent.base; return linejoiner + $join.call(xs, ',' + linejoiner) + '\n' + indent.prev; } function arrobjkeys(obj, inspect) { var isarr = isarray(obj); var xs = []; if (isarr) { xs.length = obj.length; for (var i = 0; i < obj.length; i++) { xs[i] = has(obj, i) ? inspect(obj[i], obj) : ''; } } var syms = typeof gops === 'function' ? gops(obj) : []; var symmap; if (hasshammedsymbols) { symmap = {}; for (var k = 0; k < syms.length; k++) { symmap['$' + syms[k]] = syms[k]; } } for (var key in obj) { // eslint-disable-line no-restricted-syntax if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue if (isarr && string(number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue if (hasshammedsymbols && symmap['$' + key] instanceof symbol) { // this is to prevent shammed symbols, which are stored as strings, from being included in the string key section continue; // eslint-disable-line no-restricted-syntax, no-continue } else if ($test.call(/[^\w$]/, key)) { xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj)); } else { xs.push(key + ': ' + inspect(obj[key], obj)); } } if (typeof gops === 'function') { for (var j = 0; j < syms.length; j++) { if (isenumerable.call(obj, syms[j])) { xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj)); } } } return xs; } /***/ }), /***/ 335: /***/ (function(module, exports, __webpack_require__) { "use strict"; var utils = __webpack_require__(178); var has = object.prototype.hasownproperty; var isarray = array.isarray; var defaults = { allowdots: false, allowprototypes: false, allowsparse: false, arraylimit: 20, charset: 'utf-8', charsetsentinel: false, comma: false, decoder: utils.decode, delimiter: '&', depth: 5, ignorequeryprefix: false, interpretnumericentities: false, parameterlimit: 1000, parsearrays: true, plainobjects: false, strictnullhandling: false }; var interpretnumericentities = function (str) { return str.replace(/&#(\d+);/g, function ($0, numberstr) { return string.fromcharcode(parseint(numberstr, 10)); }); }; var parsearrayvalue = function (val, options) { if (val && typeof val === 'string' && options.comma && val.indexof(',') > -1) { return val.split(','); } return val; }; // this is what browsers will submit when the ✓ character occurs in an // application/x-www-form-urlencoded body and the encoding of the page containing // the form is iso-8859-1, or when the submitted form has an accept-charset // attribute of iso-8859-1. presumably also with other charsets that do not contain // the ✓ character, such as us-ascii. var isosentinel = 'utf8=%26%2310003%3b'; // encodeuricomponent('✓') // these are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded. var charsetsentinel = 'utf8=%e2%9c%93'; // encodeuricomponent('✓') var parsevalues = function parsequerystringvalues(str, options) { var obj = {}; var cleanstr = options.ignorequeryprefix ? str.replace(/^\?/, '') : str; var limit = options.parameterlimit === infinity ? undefined : options.parameterlimit; var parts = cleanstr.split(options.delimiter, limit); var skipindex = -1; // keep track of where the utf8 sentinel was found var i; var charset = options.charset; if (options.charsetsentinel) { for (i = 0; i < parts.length; ++i) { if (parts[i].indexof('utf8=') === 0) { if (parts[i] === charsetsentinel) { charset = 'utf-8'; } else if (parts[i] === isosentinel) { charset = 'iso-8859-1'; } skipindex = i; i = parts.length; // the eslint settings do not allow break; } } } for (i = 0; i < parts.length; ++i) { if (i === skipindex) { continue; } var part = parts[i]; var bracketequalspos = part.indexof(']='); var pos = bracketequalspos === -1 ? part.indexof('=') : bracketequalspos + 1; var key, val; if (pos === -1) { key = options.decoder(part, defaults.decoder, charset, 'key'); val = options.strictnullhandling ? null : ''; } else { key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key'); val = utils.maybemap( parsearrayvalue(part.slice(pos + 1), options), function (encodedval) { return options.decoder(encodedval, defaults.decoder, charset, 'value'); } ); } if (val && options.interpretnumericentities && charset === 'iso-8859-1') { val = interpretnumericentities(val); } if (part.indexof('[]=') > -1) { val = isarray(val) ? [val] : val; } if (has.call(obj, key)) { obj[key] = utils.combine(obj[key], val); } else { obj[key] = val; } } return obj; }; var parseobject = function (chain, val, options, valuesparsed) { var leaf = valuesparsed ? val : parsearrayvalue(val, options); for (var i = chain.length - 1; i >= 0; --i) { var obj; var root = chain[i]; if (root === '[]' && options.parsearrays) { obj = [].concat(leaf); } else { obj = options.plainobjects ? object.create(null) : {}; var cleanroot = root.charat(0) === '[' && root.charat(root.length - 1) === ']' ? root.slice(1, -1) : root; var index = parseint(cleanroot, 10); if (!options.parsearrays && cleanroot === '') { obj = { 0: leaf }; } else if ( !isnan(index) && root !== cleanroot && string(index) === cleanroot && index >= 0 && (options.parsearrays && index <= options.arraylimit) ) { obj = []; obj[index] = leaf; } else if (cleanroot !== '__proto__') { obj[cleanroot] = leaf; } } leaf = obj; } return leaf; }; var parsekeys = function parsequerystringkeys(givenkey, val, options, valuesparsed) { if (!givenkey) { return; } // transform dot notation to bracket notation var key = options.allowdots ? givenkey.replace(/\.([^.[]+)/g, '[$1]') : givenkey; // the regex chunks var brackets = /(\[[^[\]]*])/; var child = /(\[[^[\]]*])/g; // get the parent var segment = options.depth > 0 && brackets.exec(key); var parent = segment ? key.slice(0, segment.index) : key; // stash the parent if it exists var keys = []; if (parent) { // if we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties if (!options.plainobjects && has.call(object.prototype, parent)) { if (!options.allowprototypes) { return; } } keys.push(parent); } // loop through children appending to the array until we hit depth var i = 0; while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) { i += 1; if (!options.plainobjects && has.call(object.prototype, segment[1].slice(1, -1))) { if (!options.allowprototypes) { return; } } keys.push(segment[1]); } // if there's a remainder, just add whatever is left if (segment) { keys.push('[' + key.slice(segment.index) + ']'); } return parseobject(keys, val, options, valuesparsed); }; var normalizeparseoptions = function normalizeparseoptions(opts) { if (!opts) { return defaults; } if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') { throw new typeerror('decoder has to be a function.'); } if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { throw new typeerror('the charset option must be either utf-8, iso-8859-1, or undefined'); } var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset; return { allowdots: typeof opts.allowdots === 'undefined' ? defaults.allowdots : !!opts.allowdots, allowprototypes: typeof opts.allowprototypes === 'boolean' ? opts.allowprototypes : defaults.allowprototypes, allowsparse: typeof opts.allowsparse === 'boolean' ? opts.allowsparse : defaults.allowsparse, arraylimit: typeof opts.arraylimit === 'number' ? opts.arraylimit : defaults.arraylimit, charset: charset, charsetsentinel: typeof opts.charsetsentinel === 'boolean' ? opts.charsetsentinel : defaults.charsetsentinel, comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma, decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder, delimiter: typeof opts.delimiter === 'string' || utils.isregexp(opts.delimiter) ? opts.delimiter : defaults.delimiter, // eslint-disable-next-line no-implicit-coercion, no-extra-parens depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth, ignorequeryprefix: opts.ignorequeryprefix === true, interpretnumericentities: typeof opts.interpretnumericentities === 'boolean' ? opts.interpretnumericentities : defaults.interpretnumericentities, parameterlimit: typeof opts.parameterlimit === 'number' ? opts.parameterlimit : defaults.parameterlimit, parsearrays: opts.parsearrays !== false, plainobjects: typeof opts.plainobjects === 'boolean' ? opts.plainobjects : defaults.plainobjects, strictnullhandling: typeof opts.strictnullhandling === 'boolean' ? opts.strictnullhandling : defaults.strictnullhandling }; }; module.exports = function (str, opts) { var options = normalizeparseoptions(opts); if (str === '' || str === null || typeof str === 'undefined') { return options.plainobjects ? object.create(null) : {}; } var tempobj = typeof str === 'string' ? parsevalues(str, options) : str; var obj = options.plainobjects ? object.create(null) : {}; // iterate over the keys and setup the new object var keys = object.keys(tempobj); for (var i = 0; i < keys.length; ++i) { var key = keys[i]; var newobj = parsekeys(key, tempobj[key], options, typeof str === 'string'); obj = utils.merge(obj, newobj, options); } if (options.allowsparse === true) { return obj; } return utils.compact(obj); }; /***/ }), /***/ 37: /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export version */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return addsidxsegmentstoplaylist$1; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return generatesidxkey; }); /* unused harmony export inheritattributes */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return parse; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return parseutctiming; }); /* unused harmony export stringtompdxml */ /* unused harmony export tom3u8 */ /* unused harmony export toplaylists */ /* harmony import */ var _videojs_vhs_utils_es_resolve_url__webpack_imported_module_0__ = __webpack_require__(53); /* harmony import */ var global_window__webpack_imported_module_1__ = __webpack_require__(0); /* harmony import */ var global_window__webpack_imported_module_1___default = /*#__pure__*/__webpack_require__.n(global_window__webpack_imported_module_1__); /* harmony import */ var _videojs_vhs_utils_es_media_groups__webpack_imported_module_2__ = __webpack_require__(193); /* harmony import */ var _videojs_vhs_utils_es_decode_b64_to_uint8_array__webpack_imported_module_3__ = __webpack_require__(89); /* harmony import */ var _xmldom_xmldom__webpack_imported_module_4__ = __webpack_require__(194); /* harmony import */ var _xmldom_xmldom__webpack_imported_module_4___default = /*#__pure__*/__webpack_require__.n(_xmldom_xmldom__webpack_imported_module_4__); /*! @name mpd-parser @version 0.21.1 @license apache-2.0 */ var version = "0.21.1"; var isobject = function isobject(obj) { return !!obj && typeof obj === 'object'; }; var merge = function merge() { for (var _len = arguments.length, objects = new array(_len), _key = 0; _key < _len; _key++) { objects[_key] = arguments[_key]; } return objects.reduce(function (result, source) { if (typeof source !== 'object') { return result; } object.keys(source).foreach(function (key) { if (array.isarray(result[key]) && array.isarray(source[key])) { result[key] = result[key].concat(source[key]); } else if (isobject(result[key]) && isobject(source[key])) { result[key] = merge(result[key], source[key]); } else { result[key] = source[key]; } }); return result; }, {}); }; var values = function values(o) { return object.keys(o).map(function (k) { return o[k]; }); }; var range = function range(start, end) { var result = []; for (var i = start; i < end; i++) { result.push(i); } return result; }; var flatten = function flatten(lists) { return lists.reduce(function (x, y) { return x.concat(y); }, []); }; var from = function from(list) { if (!list.length) { return []; } var result = []; for (var i = 0; i < list.length; i++) { result.push(list[i]); } return result; }; var findindexes = function findindexes(l, key) { return l.reduce(function (a, e, i) { if (e[key]) { a.push(i); } return a; }, []); }; /** * returns the first index that satisfies the matching function, or -1 if not found. * * only necessary because of ie11 support. * * @param {array} list - the list to search through * @param {function} matchingfunction - the matching function * * @return {number} the matching index or -1 if not found */ var findindex = function findindex(list, matchingfunction) { for (var i = 0; i < list.length; i++) { if (matchingfunction(list[i])) { return i; } } return -1; }; /** * returns a union of the included lists provided each element can be identified by a key. * * @param {array} list - list of lists to get the union of * @param {function} keyfunction - the function to use as a key for each element * * @return {array} the union of the arrays */ var union = function union(lists, keyfunction) { return values(lists.reduce(function (acc, list) { list.foreach(function (el) { acc[keyfunction(el)] = el; }); return acc; }, {})); }; var errors = { invalid_number_of_period: 'invalid_number_of_period', dash_empty_manifest: 'dash_empty_manifest', dash_invalid_xml: 'dash_invalid_xml', no_base_url: 'no_base_url', missing_segment_information: 'missing_segment_information', segment_time_unspecified: 'segment_time_unspecified', unsupported_utc_timing_scheme: 'unsupported_utc_timing_scheme' }; /** * @typedef {object} singleuri * @property {string} uri - relative location of segment * @property {string} resolveduri - resolved location of segment * @property {object} byterange - object containing information on how to make byte range * requests following byte-range-spec per rfc2616. * @property {string} byterange.length - length of range request * @property {string} byterange.offset - byte offset of range request * * @see https://www.w3.org/protocols/rfc2616/rfc2616-sec14.html#sec14.35.1 */ /** * converts a urltype node (5.3.9.2.3 table 13) to a segment object * that conforms to how m3u8-parser is structured * * @see https://github.com/videojs/m3u8-parser * * @param {string} baseurl - baseurl provided by nodes * @param {string} source - source url for segment * @param {string} range - optional range used for range calls, * follows rfc 2616, clause 14.35.1 * @return {singleuri} full segment information transformed into a format similar * to m3u8-parser */ var urltypetosegment = function urltypetosegment(_ref) { var _ref$baseurl = _ref.baseurl, baseurl = _ref$baseurl === void 0 ? '' : _ref$baseurl, _ref$source = _ref.source, source = _ref$source === void 0 ? '' : _ref$source, _ref$range = _ref.range, range = _ref$range === void 0 ? '' : _ref$range, _ref$indexrange = _ref.indexrange, indexrange = _ref$indexrange === void 0 ? '' : _ref$indexrange; var segment = { uri: source, resolveduri: object(_videojs_vhs_utils_es_resolve_url__webpack_imported_module_0__[/* default */ "a"])(baseurl || '', source) }; if (range || indexrange) { var rangestr = range ? range : indexrange; var ranges = rangestr.split('-'); // default to parsing this as a bigint if possible var startrange = global_window__webpack_imported_module_1___default.a.bigint ? global_window__webpack_imported_module_1___default.a.bigint(ranges[0]) : parseint(ranges[0], 10); var endrange = global_window__webpack_imported_module_1___default.a.bigint ? global_window__webpack_imported_module_1___default.a.bigint(ranges[1]) : parseint(ranges[1], 10); // convert back to a number if less than max_safe_integer if (startrange < number.max_safe_integer && typeof startrange === 'bigint') { startrange = number(startrange); } if (endrange < number.max_safe_integer && typeof endrange === 'bigint') { endrange = number(endrange); } var length; if (typeof endrange === 'bigint' || typeof startrange === 'bigint') { length = global_window__webpack_imported_module_1___default.a.bigint(endrange) - global_window__webpack_imported_module_1___default.a.bigint(startrange) + global_window__webpack_imported_module_1___default.a.bigint(1); } else { length = endrange - startrange + 1; } if (typeof length === 'bigint' && length < number.max_safe_integer) { length = number(length); } // byterange should be inclusive according to // rfc 2616, clause 14.35.1 segment.byterange = { length: length, offset: startrange }; } return segment; }; var byterangetostring = function byterangetostring(byterange) { // `endrange` is one less than `offset + length` because the http range // header uses inclusive ranges var endrange; if (typeof byterange.offset === 'bigint' || typeof byterange.length === 'bigint') { endrange = global_window__webpack_imported_module_1___default.a.bigint(byterange.offset) + global_window__webpack_imported_module_1___default.a.bigint(byterange.length) - global_window__webpack_imported_module_1___default.a.bigint(1); } else { endrange = byterange.offset + byterange.length - 1; } return byterange.offset + "-" + endrange; }; /** * parse the end number attribue that can be a string * number, or undefined. * * @param {string|number|undefined} endnumber * the end number attribute. * * @return {number|null} * the result of parsing the end number. */ var parseendnumber = function parseendnumber(endnumber) { if (endnumber && typeof endnumber !== 'number') { endnumber = parseint(endnumber, 10); } if (isnan(endnumber)) { return null; } return endnumber; }; /** * functions for calculating the range of available segments in static and dynamic * manifests. */ var segmentrange = { /** * returns the entire range of available segments for a static mpd * * @param {object} attributes * inheritied mpd attributes * @return {{ start: number, end: number }} * the start and end numbers for available segments */ static: function _static(attributes) { var duration = attributes.duration, _attributes$timescale = attributes.timescale, timescale = _attributes$timescale === void 0 ? 1 : _attributes$timescale, sourceduration = attributes.sourceduration, periodduration = attributes.periodduration; var endnumber = parseendnumber(attributes.endnumber); var segmentduration = duration / timescale; if (typeof endnumber === 'number') { return { start: 0, end: endnumber }; } if (typeof periodduration === 'number') { return { start: 0, end: periodduration / segmentduration }; } return { start: 0, end: sourceduration / segmentduration }; }, /** * returns the current live window range of available segments for a dynamic mpd * * @param {object} attributes * inheritied mpd attributes * @return {{ start: number, end: number }} * the start and end numbers for available segments */ dynamic: function dynamic(attributes) { var now = attributes.now, clientoffset = attributes.clientoffset, availabilitystarttime = attributes.availabilitystarttime, _attributes$timescale2 = attributes.timescale, timescale = _attributes$timescale2 === void 0 ? 1 : _attributes$timescale2, duration = attributes.duration, _attributes$periodsta = attributes.periodstart, periodstart = _attributes$periodsta === void 0 ? 0 : _attributes$periodsta, _attributes$minimumup = attributes.minimumupdateperiod, minimumupdateperiod = _attributes$minimumup === void 0 ? 0 : _attributes$minimumup, _attributes$timeshift = attributes.timeshiftbufferdepth, timeshiftbufferdepth = _attributes$timeshift === void 0 ? infinity : _attributes$timeshift; var endnumber = parseendnumber(attributes.endnumber); // clientoffset is passed in at the top level of mpd-parser and is an offset calculated // after retrieving utc server time. var now = (now + clientoffset) / 1000; // wc stands for wall clock. // convert the period start time to epoch. var periodstartwc = availabilitystarttime + periodstart; // period end in epoch is manifest's retrieval time + time until next update. var periodendwc = now + minimumupdateperiod; var periodduration = periodendwc - periodstartwc; var segmentcount = math.ceil(periodduration * timescale / duration); var availablestart = math.floor((now - periodstartwc - timeshiftbufferdepth) * timescale / duration); var availableend = math.floor((now - periodstartwc) * timescale / duration); return { start: math.max(0, availablestart), end: typeof endnumber === 'number' ? endnumber : math.min(segmentcount, availableend) }; } }; /** * maps a range of numbers to objects with information needed to build the corresponding * segment list * * @name tosegmentscallback * @function * @param {number} number * number of the segment * @param {number} index * index of the number in the range list * @return {{ number: number, duration: number, timeline: number, time: number }} * object with segment timing and duration info */ /** * returns a callback for array.prototype.map for mapping a range of numbers to * information needed to build the segment list. * * @param {object} attributes * inherited mpd attributes * @return {tosegmentscallback} * callback map function */ var tosegments = function tosegments(attributes) { return function (number) { var duration = attributes.duration, _attributes$timescale3 = attributes.timescale, timescale = _attributes$timescale3 === void 0 ? 1 : _attributes$timescale3, periodstart = attributes.periodstart, _attributes$startnumb = attributes.startnumber, startnumber = _attributes$startnumb === void 0 ? 1 : _attributes$startnumb; return { number: startnumber + number, duration: duration / timescale, timeline: periodstart, time: number * duration }; }; }; /** * returns a list of objects containing segment timing and duration info used for * building the list of segments. this uses the @duration attribute specified * in the mpd manifest to derive the range of segments. * * @param {object} attributes * inherited mpd attributes * @return {{number: number, duration: number, time: number, timeline: number}[]} * list of objects with segment timing and duration info */ var parsebyduration = function parsebyduration(attributes) { var type = attributes.type, duration = attributes.duration, _attributes$timescale4 = attributes.timescale, timescale = _attributes$timescale4 === void 0 ? 1 : _attributes$timescale4, periodduration = attributes.periodduration, sourceduration = attributes.sourceduration; var _segmentrange$type = segmentrange[type](attributes), start = _segmentrange$type.start, end = _segmentrange$type.end; var segments = range(start, end).map(tosegments(attributes)); if (type === 'static') { var index = segments.length - 1; // section is either a period or the full source var sectionduration = typeof periodduration === 'number' ? periodduration : sourceduration; // final segment may be less than full segment duration segments[index].duration = sectionduration - duration / timescale * index; } return segments; }; /** * translates segmentbase into a set of segments. * (dash spec section 5.3.9.3.2) contains a set of nodes. each * node should be translated into segment. * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @return {object.} list of segments */ var segmentsfrombase = function segmentsfrombase(attributes) { var baseurl = attributes.baseurl, _attributes$initializ = attributes.initialization, initialization = _attributes$initializ === void 0 ? {} : _attributes$initializ, sourceduration = attributes.sourceduration, _attributes$indexrang = attributes.indexrange, indexrange = _attributes$indexrang === void 0 ? '' : _attributes$indexrang, periodstart = attributes.periodstart, presentationtime = attributes.presentationtime, _attributes$number = attributes.number, number = _attributes$number === void 0 ? 0 : _attributes$number, duration = attributes.duration; // base url is required for segmentbase to work, per spec (section 5.3.9.2.1) if (!baseurl) { throw new error(errors.no_base_url); } var initsegment = urltypetosegment({ baseurl: baseurl, source: initialization.sourceurl, range: initialization.range }); var segment = urltypetosegment({ baseurl: baseurl, source: baseurl, indexrange: indexrange }); segment.map = initsegment; // if there is a duration, use it, otherwise use the given duration of the source // (since segmentbase is only for one total segment) if (duration) { var segmenttimeinfo = parsebyduration(attributes); if (segmenttimeinfo.length) { segment.duration = segmenttimeinfo[0].duration; segment.timeline = segmenttimeinfo[0].timeline; } } else if (sourceduration) { segment.duration = sourceduration; segment.timeline = periodstart; } // if presentation time is provided, these segments are being generated by sidx // references, and should use the time provided. for the general case of segmentbase, // there should only be one segment in the period, so its presentation time is the same // as its period start. segment.presentationtime = presentationtime || periodstart; segment.number = number; return [segment]; }; /** * given a playlist, a sidx box, and a baseurl, update the segment list of the playlist * according to the sidx information given. * * playlist.sidx has metadadata about the sidx where-as the sidx param * is the parsed sidx box itself. * * @param {object} playlist the playlist to update the sidx information for * @param {object} sidx the parsed sidx box * @return {object} the playlist object with the updated sidx information */ var addsidxsegmentstoplaylist$1 = function addsidxsegmentstoplaylist(playlist, sidx, baseurl) { // retain init segment information var initsegment = playlist.sidx.map ? playlist.sidx.map : null; // retain source duration from initial main manifest parsing var sourceduration = playlist.sidx.duration; // retain source timeline var timeline = playlist.timeline || 0; var sidxbyterange = playlist.sidx.byterange; var sidxend = sidxbyterange.offset + sidxbyterange.length; // retain timescale of the parsed sidx var timescale = sidx.timescale; // referencetype 1 refers to other sidx boxes var mediareferences = sidx.references.filter(function (r) { return r.referencetype !== 1; }); var segments = []; var type = playlist.endlist ? 'static' : 'dynamic'; var periodstart = playlist.sidx.timeline; var presentationtime = periodstart; var number = playlist.mediasequence || 0; // firstoffset is the offset from the end of the sidx box var startindex; // eslint-disable-next-line if (typeof sidx.firstoffset === 'bigint') { startindex = global_window__webpack_imported_module_1___default.a.bigint(sidxend) + sidx.firstoffset; } else { startindex = sidxend + sidx.firstoffset; } for (var i = 0; i < mediareferences.length; i++) { var reference = sidx.references[i]; // size of the referenced (sub)segment var size = reference.referencedsize; // duration of the referenced (sub)segment, in the timescale // this will be converted to seconds when generating segments var duration = reference.subsegmentduration; // should be an inclusive range var endindex = void 0; // eslint-disable-next-line if (typeof startindex === 'bigint') { endindex = startindex + global_window__webpack_imported_module_1___default.a.bigint(size) - global_window__webpack_imported_module_1___default.a.bigint(1); } else { endindex = startindex + size - 1; } var indexrange = startindex + "-" + endindex; var attributes = { baseurl: baseurl, timescale: timescale, timeline: timeline, periodstart: periodstart, presentationtime: presentationtime, number: number, duration: duration, sourceduration: sourceduration, indexrange: indexrange, type: type }; var segment = segmentsfrombase(attributes)[0]; if (initsegment) { segment.map = initsegment; } segments.push(segment); if (typeof startindex === 'bigint') { startindex += global_window__webpack_imported_module_1___default.a.bigint(size); } else { startindex += size; } presentationtime += duration / timescale; number++; } playlist.segments = segments; return playlist; }; var supported_media_types = ['audio', 'subtitles']; // allow one 60fps frame as leniency (arbitrarily chosen) var time_fudge = 1 / 60; /** * given a list of timelinestarts, combines, dedupes, and sorts them. * * @param {timelinestart[]} timelinestarts - list of timeline starts * * @return {timelinestart[]} the combined and deduped timeline starts */ var getuniquetimelinestarts = function getuniquetimelinestarts(timelinestarts) { return union(timelinestarts, function (_ref) { var timeline = _ref.timeline; return timeline; }).sort(function (a, b) { return a.timeline > b.timeline ? 1 : -1; }); }; /** * finds the playlist with the matching name attribute. * * @param {array} playlists - playlists to search through * @param {string} name - the name attribute to search for * * @return {object|null} the matching playlist object, or null */ var findplaylistwithname = function findplaylistwithname(playlists, name) { for (var i = 0; i < playlists.length; i++) { if (playlists[i].attributes.name === name) { return playlists[i]; } } return null; }; /** * gets a flattened array of media group playlists. * * @param {object} manifest - the main manifest object * * @return {array} the media group playlists */ var getmediagroupplaylists = function getmediagroupplaylists(manifest) { var mediagroupplaylists = []; object(_videojs_vhs_utils_es_media_groups__webpack_imported_module_2__[/* foreachmediagroup */ "a"])(manifest, supported_media_types, function (properties, type, group, label) { mediagroupplaylists = mediagroupplaylists.concat(properties.playlists || []); }); return mediagroupplaylists; }; /** * updates the playlist's media sequence numbers. * * @param {object} config - options object * @param {object} config.playlist - the playlist to update * @param {number} config.mediasequence - the mediasequence number to start with */ var updatemediasequenceforplaylist = function updatemediasequenceforplaylist(_ref2) { var playlist = _ref2.playlist, mediasequence = _ref2.mediasequence; playlist.mediasequence = mediasequence; playlist.segments.foreach(function (segment, index) { segment.number = playlist.mediasequence + index; }); }; /** * updates the media and discontinuity sequence numbers of newplaylists given oldplaylists * and a complete list of timeline starts. * * if no matching playlist is found, only the discontinuity sequence number of the playlist * will be updated. * * since early available timelines are not supported, at least one segment must be present. * * @param {object} config - options object * @param {object[]} oldplaylists - the old playlists to use as a reference * @param {object[]} newplaylists - the new playlists to update * @param {object} timelinestarts - all timelinestarts seen in the stream to this point */ var updatesequencenumbers = function updatesequencenumbers(_ref3) { var oldplaylists = _ref3.oldplaylists, newplaylists = _ref3.newplaylists, timelinestarts = _ref3.timelinestarts; newplaylists.foreach(function (playlist) { playlist.discontinuitysequence = findindex(timelinestarts, function (_ref4) { var timeline = _ref4.timeline; return timeline === playlist.timeline; }); // playlists names come from dash representation ids, which are mandatory // (see iso_23009-1-2012 5.3.5.2). // // if the same representation existed in a prior period, it will retain the same name. var oldplaylist = findplaylistwithname(oldplaylists, playlist.attributes.name); if (!oldplaylist) { // since this is a new playlist, the media sequence values can start from 0 without // consequence. return; } // todo better support for live sidx // // as of this writing, mpd-parser does not support multiperiod sidx (in live or vod). // this is evident by a playlist only having a single sidx reference. in a multiperiod // playlist there would need to be multiple sidx references. in addition, live sidx is // not supported when the sidx properties change on refreshes. // // in the future, if support needs to be added, the merging logic here can be called // after sidx references are resolved. for now, exit early to prevent exceptions being // thrown due to undefined references. if (playlist.sidx) { return; } // since we don't yet support early available timelines, we don't need to support // playlists with no segments. var firstnewsegment = playlist.segments[0]; var oldmatchingsegmentindex = findindex(oldplaylist.segments, function (oldsegment) { return math.abs(oldsegment.presentationtime - firstnewsegment.presentationtime) < time_fudge; }); // no matching segment from the old playlist means the entire playlist was refreshed. // in this case the media sequence should account for this update, and the new segments // should be marked as discontinuous from the prior content, since the last prior // timeline was removed. if (oldmatchingsegmentindex === -1) { updatemediasequenceforplaylist({ playlist: playlist, mediasequence: oldplaylist.mediasequence + oldplaylist.segments.length }); playlist.segments[0].discontinuity = true; playlist.discontinuitystarts.unshift(0); // no matching segment does not necessarily mean there's missing content. // // if the new playlist's timeline is the same as the last seen segment's timeline, // then a discontinuity can be added to identify that there's potentially missing // content. if there's no missing content, the discontinuity should still be rather // harmless. it's possible that if segment durations are accurate enough, that the // existence of a gap can be determined using the presentation times and durations, // but if the segment timing info is off, it may introduce more problems than simply // adding the discontinuity. // // if the new playlist's timeline is different from the last seen segment's timeline, // then a discontinuity can be added to identify that this is the first seen segment // of a new timeline. however, the logic at the start of this function that // determined the disconinuity sequence by timeline index is now off by one (the // discontinuity of the newest timeline hasn't yet fallen off the manifest...since // we added it), so the disconinuity sequence must be decremented. // // a period may also have a duration of zero, so the case of no segments is handled // here even though we don't yet support early available periods. if (!oldplaylist.segments.length && playlist.timeline > oldplaylist.timeline || oldplaylist.segments.length && playlist.timeline > oldplaylist.segments[oldplaylist.segments.length - 1].timeline) { playlist.discontinuitysequence--; } return; } // if the first segment matched with a prior segment on a discontinuity (it's matching // on the first segment of a period), then the discontinuitysequence shouldn't be the // timeline's matching one, but instead should be the one prior, and the first segment // of the new manifest should be marked with a discontinuity. // // the reason for this special case is that discontinuity sequence shows how many // discontinuities have fallen off of the playlist, and discontinuities are marked on // the first segment of a new "timeline." because of this, while dash will retain that // period while the "timeline" exists, hls keeps track of it via the discontinuity // sequence, and that first segment is an indicator, but can be removed before that // timeline is gone. var oldmatchingsegment = oldplaylist.segments[oldmatchingsegmentindex]; if (oldmatchingsegment.discontinuity && !firstnewsegment.discontinuity) { firstnewsegment.discontinuity = true; playlist.discontinuitystarts.unshift(0); playlist.discontinuitysequence--; } updatemediasequenceforplaylist({ playlist: playlist, mediasequence: oldplaylist.segments[oldmatchingsegmentindex].number }); }); }; /** * given an old parsed manifest object and a new parsed manifest object, updates the * sequence and timing values within the new manifest to ensure that it lines up with the * old. * * @param {array} oldmanifest - the old main manifest object * @param {array} newmanifest - the new main manifest object * * @return {object} the updated new manifest object */ var positionmanifestontimeline = function positionmanifestontimeline(_ref5) { var oldmanifest = _ref5.oldmanifest, newmanifest = _ref5.newmanifest; // starting from v4.1.2 of the iop, section 4.4.3.3 states: // // "mpd@availabilitystarttime and period@start shall not be changed over mpd updates." // // this was added from https://github.com/dash-industry-forum/dash-if-iop/issues/160 // // because of this change, and the difficulty of supporting periods with changing start // times, periods with changing start times are not supported. this makes the logic much // simpler, since periods with the same start time can be considerred the same period // across refreshes. // // to give an example as to the difficulty of handling periods where the start time may // change, if a single period manifest is refreshed with another manifest with a single // period, and both the start and end times are increased, then the only way to determine // if it's a new period or an old one that has changed is to look through the segments of // each playlist and determine the presentation time bounds to find a match. in addition, // if the period start changed to exceed the old period end, then there would be no // match, and it would not be possible to determine whether the refreshed period is a new // one or the old one. var oldplaylists = oldmanifest.playlists.concat(getmediagroupplaylists(oldmanifest)); var newplaylists = newmanifest.playlists.concat(getmediagroupplaylists(newmanifest)); // save all seen timelinestarts to the new manifest. although this potentially means that // there's a "memory leak" in that it will never stop growing, in reality, only a couple // of properties are saved for each seen period. even long running live streams won't // generate too many periods, unless the stream is watched for decades. in the future, // this can be optimized by mapping to discontinuity sequence numbers for each timeline, // but it may not become an issue, and the additional info can be useful for debugging. newmanifest.timelinestarts = getuniquetimelinestarts([oldmanifest.timelinestarts, newmanifest.timelinestarts]); updatesequencenumbers({ oldplaylists: oldplaylists, newplaylists: newplaylists, timelinestarts: newmanifest.timelinestarts }); return newmanifest; }; var generatesidxkey = function generatesidxkey(sidx) { return sidx && sidx.uri + '-' + byterangetostring(sidx.byterange); }; var mergediscontiguousplaylists = function mergediscontiguousplaylists(playlists) { var mergedplaylists = values(playlists.reduce(function (acc, playlist) { // assuming playlist ids are the same across periods // todo: handle multiperiod where representation sets are not the same // across periods var name = playlist.attributes.id + (playlist.attributes.lang || ''); if (!acc[name]) { // first period acc[name] = playlist; acc[name].attributes.timelinestarts = []; } else { // subsequent periods if (playlist.segments) { var _acc$name$segments; // first segment of subsequent periods signal a discontinuity if (playlist.segments[0]) { playlist.segments[0].discontinuity = true; } (_acc$name$segments = acc[name].segments).push.apply(_acc$name$segments, playlist.segments); } // bubble up contentprotection, this assumes all drm content // has the same contentprotection if (playlist.attributes.contentprotection) { acc[name].attributes.contentprotection = playlist.attributes.contentprotection; } } acc[name].attributes.timelinestarts.push({ // although they represent the same number, it's important to have both to make it // compatible with hls potentially having a similar attribute. start: playlist.attributes.periodstart, timeline: playlist.attributes.periodstart }); return acc; }, {})); return mergedplaylists.map(function (playlist) { playlist.discontinuitystarts = findindexes(playlist.segments || [], 'discontinuity'); return playlist; }); }; var addsidxsegmentstoplaylist = function addsidxsegmentstoplaylist(playlist, sidxmapping) { var sidxkey = generatesidxkey(playlist.sidx); var sidxmatch = sidxkey && sidxmapping[sidxkey] && sidxmapping[sidxkey].sidx; if (sidxmatch) { addsidxsegmentstoplaylist$1(playlist, sidxmatch, playlist.sidx.resolveduri); } return playlist; }; var addsidxsegmentstoplaylists = function addsidxsegmentstoplaylists(playlists, sidxmapping) { if (sidxmapping === void 0) { sidxmapping = {}; } if (!object.keys(sidxmapping).length) { return playlists; } for (var i in playlists) { playlists[i] = addsidxsegmentstoplaylist(playlists[i], sidxmapping); } return playlists; }; var formataudioplaylist = function formataudioplaylist(_ref, isaudioonly) { var _attributes; var attributes = _ref.attributes, segments = _ref.segments, sidx = _ref.sidx, mediasequence = _ref.mediasequence, discontinuitysequence = _ref.discontinuitysequence, discontinuitystarts = _ref.discontinuitystarts; var playlist = { attributes: (_attributes = { name: attributes.id, bandwidth: attributes.bandwidth, codecs: attributes.codecs }, _attributes['program-id'] = 1, _attributes), uri: '', endlist: attributes.type === 'static', timeline: attributes.periodstart, resolveduri: '', targetduration: attributes.duration, discontinuitysequence: discontinuitysequence, discontinuitystarts: discontinuitystarts, timelinestarts: attributes.timelinestarts, mediasequence: mediasequence, segments: segments }; if (attributes.contentprotection) { playlist.contentprotection = attributes.contentprotection; } if (sidx) { playlist.sidx = sidx; } if (isaudioonly) { playlist.attributes.audio = 'audio'; playlist.attributes.subtitles = 'subs'; } return playlist; }; var formatvttplaylist = function formatvttplaylist(_ref2) { var _m3u8attributes; var attributes = _ref2.attributes, segments = _ref2.segments, mediasequence = _ref2.mediasequence, discontinuitystarts = _ref2.discontinuitystarts, discontinuitysequence = _ref2.discontinuitysequence; if (typeof segments === 'undefined') { // vtt tracks may use single file in baseurl segments = [{ uri: attributes.baseurl, timeline: attributes.periodstart, resolveduri: attributes.baseurl || '', duration: attributes.sourceduration, number: 0 }]; // targetduration should be the same duration as the only segment attributes.duration = attributes.sourceduration; } var m3u8attributes = (_m3u8attributes = { name: attributes.id, bandwidth: attributes.bandwidth }, _m3u8attributes['program-id'] = 1, _m3u8attributes); if (attributes.codecs) { m3u8attributes.codecs = attributes.codecs; } return { attributes: m3u8attributes, uri: '', endlist: attributes.type === 'static', timeline: attributes.periodstart, resolveduri: attributes.baseurl || '', targetduration: attributes.duration, timelinestarts: attributes.timelinestarts, discontinuitystarts: discontinuitystarts, discontinuitysequence: discontinuitysequence, mediasequence: mediasequence, segments: segments }; }; var organizeaudioplaylists = function organizeaudioplaylists(playlists, sidxmapping, isaudioonly) { if (sidxmapping === void 0) { sidxmapping = {}; } if (isaudioonly === void 0) { isaudioonly = false; } var mainplaylist; var formattedplaylists = playlists.reduce(function (a, playlist) { var role = playlist.attributes.role && playlist.attributes.role.value || ''; var language = playlist.attributes.lang || ''; var label = playlist.attributes.label || 'main'; if (language && !playlist.attributes.label) { var rolelabel = role ? " (" + role + ")" : ''; label = "" + playlist.attributes.lang + rolelabel; } if (!a[label]) { a[label] = { language: language, autoselect: true, default: role === 'main', playlists: [], uri: '' }; } var formatted = addsidxsegmentstoplaylist(formataudioplaylist(playlist, isaudioonly), sidxmapping); a[label].playlists.push(formatted); if (typeof mainplaylist === 'undefined' && role === 'main') { mainplaylist = playlist; mainplaylist.default = true; } return a; }, {}); // if no playlists have role "main", mark the first as main if (!mainplaylist) { var firstlabel = object.keys(formattedplaylists)[0]; formattedplaylists[firstlabel].default = true; } return formattedplaylists; }; var organizevttplaylists = function organizevttplaylists(playlists, sidxmapping) { if (sidxmapping === void 0) { sidxmapping = {}; } return playlists.reduce(function (a, playlist) { var label = playlist.attributes.lang || 'text'; if (!a[label]) { a[label] = { language: label, default: false, autoselect: false, playlists: [], uri: '' }; } a[label].playlists.push(addsidxsegmentstoplaylist(formatvttplaylist(playlist), sidxmapping)); return a; }, {}); }; var organizecaptionservices = function organizecaptionservices(captionservices) { return captionservices.reduce(function (svcobj, svc) { if (!svc) { return svcobj; } svc.foreach(function (service) { var channel = service.channel, language = service.language; svcobj[language] = { autoselect: false, default: false, instreamid: channel, language: language }; if (service.hasownproperty('aspectratio')) { svcobj[language].aspectratio = service.aspectratio; } if (service.hasownproperty('easyreader')) { svcobj[language].easyreader = service.easyreader; } if (service.hasownproperty('3d')) { svcobj[language]['3d'] = service['3d']; } }); return svcobj; }, {}); }; var formatvideoplaylist = function formatvideoplaylist(_ref3) { var _attributes2; var attributes = _ref3.attributes, segments = _ref3.segments, sidx = _ref3.sidx, discontinuitystarts = _ref3.discontinuitystarts; var playlist = { attributes: (_attributes2 = { name: attributes.id, audio: 'audio', subtitles: 'subs', resolution: { width: attributes.width, height: attributes.height }, codecs: attributes.codecs, bandwidth: attributes.bandwidth }, _attributes2['program-id'] = 1, _attributes2), uri: '', endlist: attributes.type === 'static', timeline: attributes.periodstart, resolveduri: '', targetduration: attributes.duration, discontinuitystarts: discontinuitystarts, timelinestarts: attributes.timelinestarts, segments: segments }; if (attributes.contentprotection) { playlist.contentprotection = attributes.contentprotection; } if (sidx) { playlist.sidx = sidx; } return playlist; }; var videoonly = function videoonly(_ref4) { var attributes = _ref4.attributes; return attributes.mimetype === 'video/mp4' || attributes.mimetype === 'video/webm' || attributes.contenttype === 'video'; }; var audioonly = function audioonly(_ref5) { var attributes = _ref5.attributes; return attributes.mimetype === 'audio/mp4' || attributes.mimetype === 'audio/webm' || attributes.contenttype === 'audio'; }; var vttonly = function vttonly(_ref6) { var attributes = _ref6.attributes; return attributes.mimetype === 'text/vtt' || attributes.contenttype === 'text'; }; /** * contains start and timeline properties denoting a timeline start. for dash, these will * be the same number. * * @typedef {object} timelinestart * @property {number} start - the start time of the timeline * @property {number} timeline - the timeline number */ /** * adds appropriate media and discontinuity sequence values to the segments and playlists. * * throughout mpd-parser, the `number` attribute is used in relation to `startnumber`, a * dash specific attribute used in constructing segment uri's from templates. however, from * an hls perspective, the `number` attribute on a segment would be its `mediasequence` * value, which should start at the original media sequence value (or 0) and increment by 1 * for each segment thereafter. since dash's `startnumber` values are independent per * period, it doesn't make sense to use it for `number`. instead, assume everything starts * from a 0 mediasequence value and increment from there. * * note that vhs currently doesn't use the `number` property, but it can be helpful for * debugging and making sense of the manifest. * * for live playlists, to account for values increasing in manifests when periods are * removed on refreshes, merging logic should be used to update the numbers to their * appropriate values (to ensure they're sequential and increasing). * * @param {object[]} playlists - the playlists to update * @param {timelinestart[]} timelinestarts - the timeline starts for the manifest */ var addmediasequencevalues = function addmediasequencevalues(playlists, timelinestarts) { // increment all segments sequentially playlists.foreach(function (playlist) { playlist.mediasequence = 0; playlist.discontinuitysequence = findindex(timelinestarts, function (_ref7) { var timeline = _ref7.timeline; return timeline === playlist.timeline; }); if (!playlist.segments) { return; } playlist.segments.foreach(function (segment, index) { segment.number = index; }); }); }; /** * given a media group object, flattens all playlists within the media group into a single * array. * * @param {object} mediagroupobject - the media group object * * @return {object[]} * the media group playlists */ var flattenmediagroupplaylists = function flattenmediagroupplaylists(mediagroupobject) { if (!mediagroupobject) { return []; } return object.keys(mediagroupobject).reduce(function (acc, label) { var labelcontents = mediagroupobject[label]; return acc.concat(labelcontents.playlists); }, []); }; var tom3u8 = function tom3u8(_ref8) { var _mediagroups; var dashplaylists = _ref8.dashplaylists, locations = _ref8.locations, _ref8$sidxmapping = _ref8.sidxmapping, sidxmapping = _ref8$sidxmapping === void 0 ? {} : _ref8$sidxmapping, previousmanifest = _ref8.previousmanifest; if (!dashplaylists.length) { return {}; } // grab all main manifest attributes var _dashplaylists$0$attr = dashplaylists[0].attributes, duration = _dashplaylists$0$attr.sourceduration, type = _dashplaylists$0$attr.type, suggestedpresentationdelay = _dashplaylists$0$attr.suggestedpresentationdelay, minimumupdateperiod = _dashplaylists$0$attr.minimumupdateperiod; var videoplaylists = mergediscontiguousplaylists(dashplaylists.filter(videoonly)).map(formatvideoplaylist); var audioplaylists = mergediscontiguousplaylists(dashplaylists.filter(audioonly)); var vttplaylists = mergediscontiguousplaylists(dashplaylists.filter(vttonly)); var captions = dashplaylists.map(function (playlist) { return playlist.attributes.captionservices; }).filter(boolean); var manifest = { allowcache: true, discontinuitystarts: [], segments: [], endlist: true, mediagroups: (_mediagroups = { audio: {}, video: {} }, _mediagroups['closed-captions'] = {}, _mediagroups.subtitles = {}, _mediagroups), uri: '', duration: duration, playlists: addsidxsegmentstoplaylists(videoplaylists, sidxmapping) }; if (minimumupdateperiod >= 0) { manifest.minimumupdateperiod = minimumupdateperiod * 1000; } if (locations) { manifest.locations = locations; } if (type === 'dynamic') { manifest.suggestedpresentationdelay = suggestedpresentationdelay; } var isaudioonly = manifest.playlists.length === 0; var organizedaudiogroup = audioplaylists.length ? organizeaudioplaylists(audioplaylists, sidxmapping, isaudioonly) : null; var organizedvttgroup = vttplaylists.length ? organizevttplaylists(vttplaylists, sidxmapping) : null; var formattedplaylists = videoplaylists.concat(flattenmediagroupplaylists(organizedaudiogroup), flattenmediagroupplaylists(organizedvttgroup)); var playlisttimelinestarts = formattedplaylists.map(function (_ref9) { var timelinestarts = _ref9.timelinestarts; return timelinestarts; }); manifest.timelinestarts = getuniquetimelinestarts(playlisttimelinestarts); addmediasequencevalues(formattedplaylists, manifest.timelinestarts); if (organizedaudiogroup) { manifest.mediagroups.audio.audio = organizedaudiogroup; } if (organizedvttgroup) { manifest.mediagroups.subtitles.subs = organizedvttgroup; } if (captions.length) { manifest.mediagroups['closed-captions'].cc = organizecaptionservices(captions); } if (previousmanifest) { return positionmanifestontimeline({ oldmanifest: previousmanifest, newmanifest: manifest }); } return manifest; }; /** * calculates the r (repetition) value for a live stream (for the final segment * in a manifest where the r value is negative 1) * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {number} time * current time (typically the total time up until the final segment) * @param {number} duration * duration property for the given * * @return {number} * r value to reach the end of the given period */ var getlivervalue = function getlivervalue(attributes, time, duration) { var now = attributes.now, clientoffset = attributes.clientoffset, availabilitystarttime = attributes.availabilitystarttime, _attributes$timescale = attributes.timescale, timescale = _attributes$timescale === void 0 ? 1 : _attributes$timescale, _attributes$periodsta = attributes.periodstart, periodstart = _attributes$periodsta === void 0 ? 0 : _attributes$periodsta, _attributes$minimumup = attributes.minimumupdateperiod, minimumupdateperiod = _attributes$minimumup === void 0 ? 0 : _attributes$minimumup; var now = (now + clientoffset) / 1000; var periodstartwc = availabilitystarttime + periodstart; var periodendwc = now + minimumupdateperiod; var periodduration = periodendwc - periodstartwc; return math.ceil((periodduration * timescale - time) / duration); }; /** * uses information provided by segmenttemplate.segmenttimeline to determine segment * timing and duration * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object[]} segmenttimeline * list of objects representing the attributes of each s element contained within * * @return {{number: number, duration: number, time: number, timeline: number}[]} * list of objects with segment timing and duration info */ var parsebytimeline = function parsebytimeline(attributes, segmenttimeline) { var type = attributes.type, _attributes$minimumup2 = attributes.minimumupdateperiod, minimumupdateperiod = _attributes$minimumup2 === void 0 ? 0 : _attributes$minimumup2, _attributes$media = attributes.media, media = _attributes$media === void 0 ? '' : _attributes$media, sourceduration = attributes.sourceduration, _attributes$timescale2 = attributes.timescale, timescale = _attributes$timescale2 === void 0 ? 1 : _attributes$timescale2, _attributes$startnumb = attributes.startnumber, startnumber = _attributes$startnumb === void 0 ? 1 : _attributes$startnumb, timeline = attributes.periodstart; var segments = []; var time = -1; for (var sindex = 0; sindex < segmenttimeline.length; sindex++) { var s = segmenttimeline[sindex]; var duration = s.d; var repeat = s.r || 0; var segmenttime = s.t || 0; if (time < 0) { // first segment time = segmenttime; } if (segmenttime && segmenttime > time) { // discontinuity // todo: how to handle this type of discontinuity // timeline++ here would treat it like hls discontuity and content would // get appended without gap // e.g. // // // // // would have $time$ values of [0, 1, 2, 5] // should this be appened at time positions [0, 1, 2, 3],(#ext-x-discontinuity) // or [0, 1, 2, gap, gap, 5]? (#ext-x-gap) // does the value of sourceduration consider this when calculating arbitrary // negative @r repeat value? // e.g. same elements as above with this added at the end // // with a sourceduration of 10 // would the 2 gaps be included in the time duration calculations resulting in // 8 segments with $time$ values of [0, 1, 2, 5, 6, 7, 8, 9] or 10 segments // with $time$ values of [0, 1, 2, 5, 6, 7, 8, 9, 10, 11] ? time = segmenttime; } var count = void 0; if (repeat < 0) { var nexts = sindex + 1; if (nexts === segmenttimeline.length) { // last segment if (type === 'dynamic' && minimumupdateperiod > 0 && media.indexof('$number$') > 0) { count = getlivervalue(attributes, time, duration); } else { // todo: this may be incorrect depending on conclusion of todo above count = (sourceduration * timescale - time) / duration; } } else { count = (segmenttimeline[nexts].t - time) / duration; } } else { count = repeat + 1; } var end = startnumber + segments.length + count; var number = startnumber + segments.length; while (number < end) { segments.push({ number: number, duration: duration / timescale, time: time, timeline: timeline }); time += duration; number++; } } return segments; }; var identifierpattern = /\$([a-z]*)(?:(%0)([0-9]+)d)?\$/g; /** * replaces template identifiers with corresponding values. to be used as the callback * for string.prototype.replace * * @name replacecallback * @function * @param {string} match * entire match of identifier * @param {string} identifier * name of matched identifier * @param {string} format * format tag string. its presence indicates that padding is expected * @param {string} width * desired length of the replaced value. values less than this width shall be left * zero padded * @return {string} * replacement for the matched identifier */ /** * returns a function to be used as a callback for string.prototype.replace to replace * template identifiers * * @param {obect} values * object containing values that shall be used to replace known identifiers * @param {number} values.representationid * value of the representation@id attribute * @param {number} values.number * number of the corresponding segment * @param {number} values.bandwidth * value of the representation@bandwidth attribute. * @param {number} values.time * timestamp value of the corresponding segment * @return {replacecallback} * callback to be used with string.prototype.replace to replace identifiers */ var identifierreplacement = function identifierreplacement(values) { return function (match, identifier, format, width) { if (match === '$$') { // escape sequence return '$'; } if (typeof values[identifier] === 'undefined') { return match; } var value = '' + values[identifier]; if (identifier === 'representationid') { // format tag shall not be present with representationid return value; } if (!format) { width = 1; } else { width = parseint(width, 10); } if (value.length >= width) { return value; } return "" + new array(width - value.length + 1).join('0') + value; }; }; /** * constructs a segment url from a template string * * @param {string} url * template string to construct url from * @param {obect} values * object containing values that shall be used to replace known identifiers * @param {number} values.representationid * value of the representation@id attribute * @param {number} values.number * number of the corresponding segment * @param {number} values.bandwidth * value of the representation@bandwidth attribute. * @param {number} values.time * timestamp value of the corresponding segment * @return {string} * segment url with identifiers replaced */ var constructtemplateurl = function constructtemplateurl(url, values) { return url.replace(identifierpattern, identifierreplacement(values)); }; /** * generates a list of objects containing timing and duration information about each * segment needed to generate segment uris and the complete segment object * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object[]|undefined} segmenttimeline * list of objects representing the attributes of each s element contained within * the segmenttimeline element * @return {{number: number, duration: number, time: number, timeline: number}[]} * list of objects with segment timing and duration info */ var parsetemplateinfo = function parsetemplateinfo(attributes, segmenttimeline) { if (!attributes.duration && !segmenttimeline) { // if neither @duration or segmenttimeline are present, then there shall be exactly // one media segment return [{ number: attributes.startnumber || 1, duration: attributes.sourceduration, time: 0, timeline: attributes.periodstart }]; } if (attributes.duration) { return parsebyduration(attributes); } return parsebytimeline(attributes, segmenttimeline); }; /** * generates a list of segments using information provided by the segmenttemplate element * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object[]|undefined} segmenttimeline * list of objects representing the attributes of each s element contained within * the segmenttimeline element * @return {object[]} * list of segment objects */ var segmentsfromtemplate = function segmentsfromtemplate(attributes, segmenttimeline) { var templatevalues = { representationid: attributes.id, bandwidth: attributes.bandwidth || 0 }; var _attributes$initializ = attributes.initialization, initialization = _attributes$initializ === void 0 ? { sourceurl: '', range: '' } : _attributes$initializ; var mapsegment = urltypetosegment({ baseurl: attributes.baseurl, source: constructtemplateurl(initialization.sourceurl, templatevalues), range: initialization.range }); var segments = parsetemplateinfo(attributes, segmenttimeline); return segments.map(function (segment) { templatevalues.number = segment.number; templatevalues.time = segment.time; var uri = constructtemplateurl(attributes.media || '', templatevalues); // see dash spec section 5.3.9.2.2 // - if timescale isn't present on any level, default to 1. var timescale = attributes.timescale || 1; // - if presentationtimeoffset isn't present on any level, default to 0 var presentationtimeoffset = attributes.presentationtimeoffset || 0; var presentationtime = // even if the @t attribute is not specified for the segment, segment.time is // calculated in mpd-parser prior to this, so it's assumed to be available. attributes.periodstart + (segment.time - presentationtimeoffset) / timescale; var map = { uri: uri, timeline: segment.timeline, duration: segment.duration, resolveduri: object(_videojs_vhs_utils_es_resolve_url__webpack_imported_module_0__[/* default */ "a"])(attributes.baseurl || '', uri), map: mapsegment, number: segment.number, presentationtime: presentationtime }; return map; }); }; /** * converts a (of type urltype from the dash spec 5.3.9.2 table 14) * to an object that matches the output of a segment in videojs/mpd-parser * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object} segmenturl * node to translate into a segment object * @return {object} translated segment object */ var segmenturltosegmentobject = function segmenturltosegmentobject(attributes, segmenturl) { var baseurl = attributes.baseurl, _attributes$initializ = attributes.initialization, initialization = _attributes$initializ === void 0 ? {} : _attributes$initializ; var initsegment = urltypetosegment({ baseurl: baseurl, source: initialization.sourceurl, range: initialization.range }); var segment = urltypetosegment({ baseurl: baseurl, source: segmenturl.media, range: segmenturl.mediarange }); segment.map = initsegment; return segment; }; /** * generates a list of segments using information provided by the segmentlist element * segmentlist (dash spec section 5.3.9.3.2) contains a set of nodes. each * node should be translated into segment. * * @param {object} attributes * object containing all inherited attributes from parent elements with attribute * names as keys * @param {object[]|undefined} segmenttimeline * list of objects representing the attributes of each s element contained within * the segmenttimeline element * @return {object.} list of segments */ var segmentsfromlist = function segmentsfromlist(attributes, segmenttimeline) { var duration = attributes.duration, _attributes$segmentur = attributes.segmenturls, segmenturls = _attributes$segmentur === void 0 ? [] : _attributes$segmentur, periodstart = attributes.periodstart; // per spec (5.3.9.2.1) no way to determine segment duration or // if both segmenttimeline and @duration are defined, it is outside of spec. if (!duration && !segmenttimeline || duration && segmenttimeline) { throw new error(errors.segment_time_unspecified); } var segmenturlmap = segmenturls.map(function (segmenturlobject) { return segmenturltosegmentobject(attributes, segmenturlobject); }); var segmenttimeinfo; if (duration) { segmenttimeinfo = parsebyduration(attributes); } if (segmenttimeline) { segmenttimeinfo = parsebytimeline(attributes, segmenttimeline); } var segments = segmenttimeinfo.map(function (segmenttime, index) { if (segmenturlmap[index]) { var segment = segmenturlmap[index]; // see dash spec section 5.3.9.2.2 // - if timescale isn't present on any level, default to 1. var timescale = attributes.timescale || 1; // - if presentationtimeoffset isn't present on any level, default to 0 var presentationtimeoffset = attributes.presentationtimeoffset || 0; segment.timeline = segmenttime.timeline; segment.duration = segmenttime.duration; segment.number = segmenttime.number; segment.presentationtime = periodstart + (segmenttime.time - presentationtimeoffset) / timescale; return segment; } // since we're mapping we should get rid of any blank segments (in case // the given segmenttimeline is handling for more elements than we have // segmenturls for). }).filter(function (segment) { return segment; }); return segments; }; var generatesegments = function generatesegments(_ref) { var attributes = _ref.attributes, segmentinfo = _ref.segmentinfo; var segmentattributes; var segmentsfn; if (segmentinfo.template) { segmentsfn = segmentsfromtemplate; segmentattributes = merge(attributes, segmentinfo.template); } else if (segmentinfo.base) { segmentsfn = segmentsfrombase; segmentattributes = merge(attributes, segmentinfo.base); } else if (segmentinfo.list) { segmentsfn = segmentsfromlist; segmentattributes = merge(attributes, segmentinfo.list); } var segmentsinfo = { attributes: attributes }; if (!segmentsfn) { return segmentsinfo; } var segments = segmentsfn(segmentattributes, segmentinfo.segmenttimeline); // the @duration attribute will be used to determin the playlist's targetduration which // must be in seconds. since we've generated the segment list, we no longer need // @duration to be in @timescale units, so we can convert it here. if (segmentattributes.duration) { var _segmentattributes = segmentattributes, duration = _segmentattributes.duration, _segmentattributes$ti = _segmentattributes.timescale, timescale = _segmentattributes$ti === void 0 ? 1 : _segmentattributes$ti; segmentattributes.duration = duration / timescale; } else if (segments.length) { // if there is no @duration attribute, use the largest segment duration as // as target duration segmentattributes.duration = segments.reduce(function (max, segment) { return math.max(max, math.ceil(segment.duration)); }, 0); } else { segmentattributes.duration = 0; } segmentsinfo.attributes = segmentattributes; segmentsinfo.segments = segments; // this is a sidx box without actual segment information if (segmentinfo.base && segmentattributes.indexrange) { segmentsinfo.sidx = segments[0]; segmentsinfo.segments = []; } return segmentsinfo; }; var toplaylists = function toplaylists(representations) { return representations.map(generatesegments); }; var findchildren = function findchildren(element, name) { return from(element.childnodes).filter(function (_ref) { var tagname = _ref.tagname; return tagname === name; }); }; var getcontent = function getcontent(element) { return element.textcontent.trim(); }; var parseduration = function parseduration(str) { var seconds_in_year = 365 * 24 * 60 * 60; var seconds_in_month = 30 * 24 * 60 * 60; var seconds_in_day = 24 * 60 * 60; var seconds_in_hour = 60 * 60; var seconds_in_min = 60; // p10y10m10dt10h10m10.1s var durationregex = /p(?:(\d*)y)?(?:(\d*)m)?(?:(\d*)d)?(?:t(?:(\d*)h)?(?:(\d*)m)?(?:([\d.]*)s)?)?/; var match = durationregex.exec(str); if (!match) { return 0; } var _match$slice = match.slice(1), year = _match$slice[0], month = _match$slice[1], day = _match$slice[2], hour = _match$slice[3], minute = _match$slice[4], second = _match$slice[5]; return parsefloat(year || 0) * seconds_in_year + parsefloat(month || 0) * seconds_in_month + parsefloat(day || 0) * seconds_in_day + parsefloat(hour || 0) * seconds_in_hour + parsefloat(minute || 0) * seconds_in_min + parsefloat(second || 0); }; var parsedate = function parsedate(str) { // date format without timezone according to iso 8601 // yyy-mm-ddthh:mm:ss.ssssss var dateregex = /^\d+-\d+-\d+t\d+:\d+:\d+(\.\d+)?$/; // if the date string does not specifiy a timezone, we must specifiy utc. this is // expressed by ending with 'z' if (dateregex.test(str)) { str += 'z'; } return date.parse(str); }; var parsers = { /** * specifies the duration of the entire media presentation. format is a duration string * as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ mediapresentationduration: function mediapresentationduration(value) { return parseduration(value); }, /** * specifies the segment availability start time for all segments referred to in this * mpd. for a dynamic manifest, it specifies the anchor for the earliest availability * time. format is a date string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the date as seconds from unix epoch */ availabilitystarttime: function availabilitystarttime(value) { return parsedate(value) / 1000; }, /** * specifies the smallest period between potential changes to the mpd. format is a * duration string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ minimumupdateperiod: function minimumupdateperiod(value) { return parseduration(value); }, /** * specifies the suggested presentation delay. format is a * duration string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ suggestedpresentationdelay: function suggestedpresentationdelay(value) { return parseduration(value); }, /** * specifices the type of mpd. can be either "static" or "dynamic" * * @param {string} value * value of attribute as a string * * @return {string} * the type as a string */ type: function type(value) { return value; }, /** * specifies the duration of the smallest time shifting buffer for any representation * in the mpd. format is a duration string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ timeshiftbufferdepth: function timeshiftbufferdepth(value) { return parseduration(value); }, /** * specifies the periodstart time of the period relative to the availabilitystarttime. * format is a duration string as specified in iso 8601 * * @param {string} value * value of attribute as a string * @return {number} * the duration in seconds */ start: function start(value) { return parseduration(value); }, /** * specifies the width of the visual presentation * * @param {string} value * value of attribute as a string * @return {number} * the parsed width */ width: function width(value) { return parseint(value, 10); }, /** * specifies the height of the visual presentation * * @param {string} value * value of attribute as a string * @return {number} * the parsed height */ height: function height(value) { return parseint(value, 10); }, /** * specifies the bitrate of the representation * * @param {string} value * value of attribute as a string * @return {number} * the parsed bandwidth */ bandwidth: function bandwidth(value) { return parseint(value, 10); }, /** * specifies the number of the first media segment in this representation in the period * * @param {string} value * value of attribute as a string * @return {number} * the parsed number */ startnumber: function startnumber(value) { return parseint(value, 10); }, /** * specifies the timescale in units per seconds * * @param {string} value * value of attribute as a string * @return {number} * the parsed timescale */ timescale: function timescale(value) { return parseint(value, 10); }, /** * specifies the presentationtimeoffset. * * @param {string} value * value of the attribute as a string * * @return {number} * the parsed presentationtimeoffset */ presentationtimeoffset: function presentationtimeoffset(value) { return parseint(value, 10); }, /** * specifies the constant approximate segment duration * note: the element also contains an @duration attribute. this duration * specifies the duration of the period. this attribute is currently not * supported by the rest of the parser, however we still check for it to prevent * errors. * * @param {string} value * value of attribute as a string * @return {number} * the parsed duration */ duration: function duration(value) { var parsedvalue = parseint(value, 10); if (isnan(parsedvalue)) { return parseduration(value); } return parsedvalue; }, /** * specifies the segment duration, in units of the value of the @timescale. * * @param {string} value * value of attribute as a string * @return {number} * the parsed duration */ d: function d(value) { return parseint(value, 10); }, /** * specifies the mpd start time, in @timescale units, the first segment in the series * starts relative to the beginning of the period * * @param {string} value * value of attribute as a string * @return {number} * the parsed time */ t: function t(value) { return parseint(value, 10); }, /** * specifies the repeat count of the number of following contiguous segments with the * same duration expressed by the value of @d * * @param {string} value * value of attribute as a string * @return {number} * the parsed number */ r: function r(value) { return parseint(value, 10); }, /** * default parser for all other attributes. acts as a no-op and just returns the value * as a string * * @param {string} value * value of attribute as a string * @return {string} * unparsed value */ default: function default(value) { return value; } }; /** * gets all the attributes and values of the provided node, parses attributes with known * types, and returns an object with attribute names mapped to values. * * @param {node} el * the node to parse attributes from * @return {object} * object with all attributes of el parsed */ var parseattributes = function parseattributes(el) { if (!(el && el.attributes)) { return {}; } return from(el.attributes).reduce(function (a, e) { var parsefn = parsers[e.name] || parsers.default; a[e.name] = parsefn(e.value); return a; }, {}); }; var keysystemsmap = { 'urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b': 'org.w3.clearkey', 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed': 'com.widevine.alpha', 'urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95': 'com.microsoft.playready', 'urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb': 'com.adobe.primetime' }; /** * builds a list of urls that is the product of the reference urls and baseurl values * * @param {string[]} referenceurls * list of reference urls to resolve to * @param {node[]} baseurlelements * list of baseurl nodes from the mpd * @return {string[]} * list of resolved urls */ var buildbaseurls = function buildbaseurls(referenceurls, baseurlelements) { if (!baseurlelements.length) { return referenceurls; } return flatten(referenceurls.map(function (reference) { return baseurlelements.map(function (baseurlelement) { return object(_videojs_vhs_utils_es_resolve_url__webpack_imported_module_0__[/* default */ "a"])(reference, getcontent(baseurlelement)); }); })); }; /** * contains all segment information for its containing adaptationset * * @typedef {object} segmentinformation * @property {object|undefined} template * contains the attributes for the segmenttemplate node * @property {object[]|undefined} segmenttimeline * contains a list of atrributes for each s node within the segmenttimeline node * @property {object|undefined} list * contains the attributes for the segmentlist node * @property {object|undefined} base * contains the attributes for the segmentbase node */ /** * returns all available segment information contained within the adaptationset node * * @param {node} adaptationset * the adaptationset node to get segment information from * @return {segmentinformation} * the segment information contained within the provided adaptationset */ var getsegmentinformation = function getsegmentinformation(adaptationset) { var segmenttemplate = findchildren(adaptationset, 'segmenttemplate')[0]; var segmentlist = findchildren(adaptationset, 'segmentlist')[0]; var segmenturls = segmentlist && findchildren(segmentlist, 'segmenturl').map(function (s) { return merge({ tag: 'segmenturl' }, parseattributes(s)); }); var segmentbase = findchildren(adaptationset, 'segmentbase')[0]; var segmenttimelineparentnode = segmentlist || segmenttemplate; var segmenttimeline = segmenttimelineparentnode && findchildren(segmenttimelineparentnode, 'segmenttimeline')[0]; var segmentinitializationparentnode = segmentlist || segmentbase || segmenttemplate; var segmentinitialization = segmentinitializationparentnode && findchildren(segmentinitializationparentnode, 'initialization')[0]; // segmenttemplate is handled slightly differently, since it can have both // @initialization and an node. @initialization can be templated, // while the node can have a url and range specified. if the has // both @initialization and an subelement we opt to override with // the node, as this interaction is not defined in the spec. var template = segmenttemplate && parseattributes(segmenttemplate); if (template && segmentinitialization) { template.initialization = segmentinitialization && parseattributes(segmentinitialization); } else if (template && template.initialization) { // if it is @initialization we convert it to an object since this is the format that // later functions will rely on for the initialization segment. this is only valid // for template.initialization = { sourceurl: template.initialization }; } var segmentinfo = { template: template, segmenttimeline: segmenttimeline && findchildren(segmenttimeline, 's').map(function (s) { return parseattributes(s); }), list: segmentlist && merge(parseattributes(segmentlist), { segmenturls: segmenturls, initialization: parseattributes(segmentinitialization) }), base: segmentbase && merge(parseattributes(segmentbase), { initialization: parseattributes(segmentinitialization) }) }; object.keys(segmentinfo).foreach(function (key) { if (!segmentinfo[key]) { delete segmentinfo[key]; } }); return segmentinfo; }; /** * contains segment information and attributes needed to construct a playlist object * from a representation * * @typedef {object} representationinformation * @property {segmentinformation} segmentinfo * segment information for this representation * @property {object} attributes * inherited attributes for this representation */ /** * maps a representation node to an object containing segment information and attributes * * @name inheritbaseurlscallback * @function * @param {node} representation * representation node from the mpd * @return {representationinformation} * representation information needed to construct a playlist object */ /** * returns a callback for array.prototype.map for mapping representation nodes to * segment information and attributes using inherited baseurl nodes. * * @param {object} adaptationsetattributes * contains attributes inherited by the adaptationset * @param {string[]} adaptationsetbaseurls * contains list of resolved base urls inherited by the adaptationset * @param {segmentinformation} adaptationsetsegmentinfo * contains segment information for the adaptationset * @return {inheritbaseurlscallback} * callback map function */ var inheritbaseurls = function inheritbaseurls(adaptationsetattributes, adaptationsetbaseurls, adaptationsetsegmentinfo) { return function (representation) { var repbaseurlelements = findchildren(representation, 'baseurl'); var repbaseurls = buildbaseurls(adaptationsetbaseurls, repbaseurlelements); var attributes = merge(adaptationsetattributes, parseattributes(representation)); var representationsegmentinfo = getsegmentinformation(representation); return repbaseurls.map(function (baseurl) { return { segmentinfo: merge(adaptationsetsegmentinfo, representationsegmentinfo), attributes: merge(attributes, { baseurl: baseurl }) }; }); }; }; /** * tranforms a series of content protection nodes to * an object containing pssh data by key system * * @param {node[]} contentprotectionnodes * content protection nodes * @return {object} * object containing pssh data by key system */ var generatekeysysteminformation = function generatekeysysteminformation(contentprotectionnodes) { return contentprotectionnodes.reduce(function (acc, node) { var attributes = parseattributes(node); // although it could be argued that according to the uuid rfc spec the uuid string (a-f chars) should be generated // as a lowercase string it also mentions it should be treated as case-insensitive on input. since the key system // uuids in the keysystemsmap are hardcoded as lowercase in the codebase there isn't any reason not to do // .tolowercase() on the input uuid string from the manifest (at least i could not think of one). if (attributes.schemeiduri) { attributes.schemeiduri = attributes.schemeiduri.tolowercase(); } var keysystem = keysystemsmap[attributes.schemeiduri]; if (keysystem) { acc[keysystem] = { attributes: attributes }; var psshnode = findchildren(node, 'cenc:pssh')[0]; if (psshnode) { var pssh = getcontent(psshnode); acc[keysystem].pssh = pssh && object(_videojs_vhs_utils_es_decode_b64_to_uint8_array__webpack_imported_module_3__[/* default */ "a"])(pssh); } } return acc; }, {}); }; // defined in ansi_scte 214-1 2016 var parsecaptionservicemetadata = function parsecaptionservicemetadata(service) { // 608 captions if (service.schemeiduri === 'urn:scte:dash:cc:cea-608:2015') { var values = typeof service.value !== 'string' ? [] : service.value.split(';'); return values.map(function (value) { var channel; var language; // default language to value language = value; if (/^cc\d=/.test(value)) { var _value$split = value.split('='); channel = _value$split[0]; language = _value$split[1]; } else if (/^cc\d$/.test(value)) { channel = value; } return { channel: channel, language: language }; }); } else if (service.schemeiduri === 'urn:scte:dash:cc:cea-708:2015') { var _values = typeof service.value !== 'string' ? [] : service.value.split(';'); return _values.map(function (value) { var flags = { // service or channel number 1-63 'channel': undefined, // language is a 3alpha per iso 639.2/b // field is required 'language': undefined, // bit 1/0 or ? // default value is 1, meaning 16:9 aspect ratio, 0 is 4:3, ? is unknown 'aspectratio': 1, // bit 1/0 // easy reader flag indicated the text is tailed to the needs of beginning readers // default 0, or off 'easyreader': 0, // bit 1/0 // if 3d metadata is present (cea-708.1) then 1 // default 0 '3d': 0 }; if (/=/.test(value)) { var _value$split2 = value.split('='), channel = _value$split2[0], _value$split2$ = _value$split2[1], opts = _value$split2$ === void 0 ? '' : _value$split2$; flags.channel = channel; flags.language = value; opts.split(',').foreach(function (opt) { var _opt$split = opt.split(':'), name = _opt$split[0], val = _opt$split[1]; if (name === 'lang') { flags.language = val; // er for easyreadery } else if (name === 'er') { flags.easyreader = number(val); // war for wide aspect ratio } else if (name === 'war') { flags.aspectratio = number(val); } else if (name === '3d') { flags['3d'] = number(val); } }); } else { flags.language = value; } if (flags.channel) { flags.channel = 'service' + flags.channel; } return flags; }); } }; /** * maps an adaptationset node to a list of representation information objects * * @name torepresentationscallback * @function * @param {node} adaptationset * adaptationset node from the mpd * @return {representationinformation[]} * list of objects containing representaion information */ /** * returns a callback for array.prototype.map for mapping adaptationset nodes to a list of * representation information objects * * @param {object} periodattributes * contains attributes inherited by the period * @param {string[]} periodbaseurls * contains list of resolved base urls inherited by the period * @param {string[]} periodsegmentinfo * contains segment information at the period level * @return {torepresentationscallback} * callback map function */ var torepresentations = function torepresentations(periodattributes, periodbaseurls, periodsegmentinfo) { return function (adaptationset) { var adaptationsetattributes = parseattributes(adaptationset); var adaptationsetbaseurls = buildbaseurls(periodbaseurls, findchildren(adaptationset, 'baseurl')); var role = findchildren(adaptationset, 'role')[0]; var roleattributes = { role: parseattributes(role) }; var attrs = merge(periodattributes, adaptationsetattributes, roleattributes); var accessibility = findchildren(adaptationset, 'accessibility')[0]; var captionservices = parsecaptionservicemetadata(parseattributes(accessibility)); if (captionservices) { attrs = merge(attrs, { captionservices: captionservices }); } var label = findchildren(adaptationset, 'label')[0]; if (label && label.childnodes.length) { var labelval = label.childnodes[0].nodevalue.trim(); attrs = merge(attrs, { label: labelval }); } var contentprotection = generatekeysysteminformation(findchildren(adaptationset, 'contentprotection')); if (object.keys(contentprotection).length) { attrs = merge(attrs, { contentprotection: contentprotection }); } var segmentinfo = getsegmentinformation(adaptationset); var representations = findchildren(adaptationset, 'representation'); var adaptationsetsegmentinfo = merge(periodsegmentinfo, segmentinfo); return flatten(representations.map(inheritbaseurls(attrs, adaptationsetbaseurls, adaptationsetsegmentinfo))); }; }; /** * contains all period information for mapping nodes onto adaptation sets. * * @typedef {object} periodinformation * @property {node} period.node * period node from the mpd * @property {object} period.attributes * parsed period attributes from node plus any added */ /** * maps a periodinformation object to a list of representation information objects for all * adaptationset nodes contained within the period. * * @name toadaptationsetscallback * @function * @param {periodinformation} period * period object containing necessary period information * @param {number} periodstart * start time of the period within the mpd * @return {representationinformation[]} * list of objects containing representaion information */ /** * returns a callback for array.prototype.map for mapping period nodes to a list of * representation information objects * * @param {object} mpdattributes * contains attributes inherited by the mpd * @param {string[]} mpdbaseurls * contains list of resolved base urls inherited by the mpd * @return {toadaptationsetscallback} * callback map function */ var toadaptationsets = function toadaptationsets(mpdattributes, mpdbaseurls) { return function (period, index) { var periodbaseurls = buildbaseurls(mpdbaseurls, findchildren(period.node, 'baseurl')); var periodattributes = merge(mpdattributes, { periodstart: period.attributes.start }); if (typeof period.attributes.duration === 'number') { periodattributes.periodduration = period.attributes.duration; } var adaptationsets = findchildren(period.node, 'adaptationset'); var periodsegmentinfo = getsegmentinformation(period.node); return flatten(adaptationsets.map(torepresentations(periodattributes, periodbaseurls, periodsegmentinfo))); }; }; /** * gets period@start property for a given period. * * @param {object} options * options object * @param {object} options.attributes * period attributes * @param {object} [options.priorperiodattributes] * prior period attributes (if prior period is available) * @param {string} options.mpdtype * the mpd@type these periods came from * @return {number|null} * the period start, or null if it's an early available period or error */ var getperiodstart = function getperiodstart(_ref) { var attributes = _ref.attributes, priorperiodattributes = _ref.priorperiodattributes, mpdtype = _ref.mpdtype; // summary of period start time calculation from dash spec section 5.3.2.1 // // a period's start is the first period's start + time elapsed after playing all // prior periods to this one. periods continue one after the other in time (without // gaps) until the end of the presentation. // // the value of period@start should be: // 1. if period@start is present: value of period@start // 2. if previous period exists and it has @duration: previous period@start + // previous period@duration // 3. if this is first period and mpd@type is 'static': 0 // 4. in all other cases, consider the period an "early available period" (note: not // currently supported) // (1) if (typeof attributes.start === 'number') { return attributes.start; } // (2) if (priorperiodattributes && typeof priorperiodattributes.start === 'number' && typeof priorperiodattributes.duration === 'number') { return priorperiodattributes.start + priorperiodattributes.duration; } // (3) if (!priorperiodattributes && mpdtype === 'static') { return 0; } // (4) // there is currently no logic for calculating the period@start value if there is // no period@start or prior period@start and period@duration available. this is not made // explicit by the dash interop guidelines or the dash spec, however, since there's // nothing about any other resolution strategies, it's implied. thus, this case should // be considered an early available period, or error, and null should suffice for both // of those cases. return null; }; /** * traverses the mpd xml tree to generate a list of representation information objects * that have inherited attributes from parent nodes * * @param {node} mpd * the root node of the mpd * @param {object} options * available options for inheritattributes * @param {string} options.manifesturi * the uri source of the mpd * @param {number} options.now * current time per dash iop. default is current time in ms since epoch * @param {number} options.clientoffset * client time difference from now (in milliseconds) * @return {representationinformation[]} * list of objects containing representation information */ var inheritattributes = function inheritattributes(mpd, options) { if (options === void 0) { options = {}; } var _options = options, _options$manifesturi = _options.manifesturi, manifesturi = _options$manifesturi === void 0 ? '' : _options$manifesturi, _options$now = _options.now, now = _options$now === void 0 ? date.now() : _options$now, _options$clientoffset = _options.clientoffset, clientoffset = _options$clientoffset === void 0 ? 0 : _options$clientoffset; var periodnodes = findchildren(mpd, 'period'); if (!periodnodes.length) { throw new error(errors.invalid_number_of_period); } var locations = findchildren(mpd, 'location'); var mpdattributes = parseattributes(mpd); var mpdbaseurls = buildbaseurls([manifesturi], findchildren(mpd, 'baseurl')); // see dash spec section 5.3.1.2, semantics of mpd element. default type to 'static'. mpdattributes.type = mpdattributes.type || 'static'; mpdattributes.sourceduration = mpdattributes.mediapresentationduration || 0; mpdattributes.now = now; mpdattributes.clientoffset = clientoffset; if (locations.length) { mpdattributes.locations = locations.map(getcontent); } var periods = []; // since toadaptationsets acts on individual periods right now, the simplest approach to // adding properties that require looking at prior periods is to parse attributes and add // missing ones before toadaptationsets is called. if more such properties are added, it // may be better to refactor toadaptationsets. periodnodes.foreach(function (node, index) { var attributes = parseattributes(node); // use the last modified prior period, as it may contain added information necessary // for this period. var priorperiod = periods[index - 1]; attributes.start = getperiodstart({ attributes: attributes, priorperiodattributes: priorperiod ? priorperiod.attributes : null, mpdtype: mpdattributes.type }); periods.push({ node: node, attributes: attributes }); }); return { locations: mpdattributes.locations, representationinfo: flatten(periods.map(toadaptationsets(mpdattributes, mpdbaseurls))) }; }; var stringtompdxml = function stringtompdxml(manifeststring) { if (manifeststring === '') { throw new error(errors.dash_empty_manifest); } var parser = new _xmldom_xmldom__webpack_imported_module_4__["domparser"](); var xml; var mpd; try { xml = parser.parsefromstring(manifeststring, 'application/xml'); mpd = xml && xml.documentelement.tagname === 'mpd' ? xml.documentelement : null; } catch (e) {// ie 11 throwsw on invalid xml } if (!mpd || mpd && mpd.getelementsbytagname('parsererror').length > 0) { throw new error(errors.dash_invalid_xml); } return mpd; }; /** * parses the manifest for a utctiming node, returning the nodes attributes if found * * @param {string} mpd * xml string of the mpd manifest * @return {object|null} * attributes of utctiming node specified in the manifest. null if none found */ var parseutctimingscheme = function parseutctimingscheme(mpd) { var utctimingnode = findchildren(mpd, 'utctiming')[0]; if (!utctimingnode) { return null; } var attributes = parseattributes(utctimingnode); switch (attributes.schemeiduri) { case 'urn:mpeg:dash:utc:http-head:2014': case 'urn:mpeg:dash:utc:http-head:2012': attributes.method = 'head'; break; case 'urn:mpeg:dash:utc:http-xsdate:2014': case 'urn:mpeg:dash:utc:http-iso:2014': case 'urn:mpeg:dash:utc:http-xsdate:2012': case 'urn:mpeg:dash:utc:http-iso:2012': attributes.method = 'get'; break; case 'urn:mpeg:dash:utc:direct:2014': case 'urn:mpeg:dash:utc:direct:2012': attributes.method = 'direct'; attributes.value = date.parse(attributes.value); break; case 'urn:mpeg:dash:utc:http-ntp:2014': case 'urn:mpeg:dash:utc:ntp:2014': case 'urn:mpeg:dash:utc:sntp:2014': default: throw new error(errors.unsupported_utc_timing_scheme); } return attributes; }; var version = version; /* * given a dash manifest string and options, parses the dash manifest into an object in the * form outputed by m3u8-parser and accepted by videojs/http-streaming. * * for live dash manifests, if `previousmanifest` is provided in options, then the newly * parsed dash manifest will have its media sequence and discontinuity sequence values * updated to reflect its position relative to the prior manifest. * * @param {string} manifeststring - the dash manifest as a string * @param {options} [options] - any options * * @return {object} the manifest object */ var parse = function parse(manifeststring, options) { if (options === void 0) { options = {}; } var parsedmanifestinfo = inheritattributes(stringtompdxml(manifeststring), options); var playlists = toplaylists(parsedmanifestinfo.representationinfo); return tom3u8({ dashplaylists: playlists, locations: parsedmanifestinfo.locations, sidxmapping: options.sidxmapping, previousmanifest: options.previousmanifest }); }; /** * parses the manifest for a utctiming node, returning the nodes attributes if found * * @param {string} manifeststring * xml string of the mpd manifest * @return {object|null} * attributes of utctiming node specified in the manifest. null if none found */ var parseutctiming = function parseutctiming(manifeststring) { return parseutctimingscheme(stringtompdxml(manifeststring)); }; /***/ }), /***/ 64: /***/ (function(module, exports) { /** * mux.js * * copyright (c) brightcove * licensed apache-2.0 https://github.com/videojs/mux.js/blob/master/license */ var one_second_in_ts = 90000, // 90khz clock secondstovideots, secondstoaudiots, videotstoseconds, audiotstoseconds, audiotstovideots, videotstoaudiots, metadatatstoseconds; secondstovideots = function(seconds) { return seconds * one_second_in_ts; }; secondstoaudiots = function(seconds, samplerate) { return seconds * samplerate; }; videotstoseconds = function(timestamp) { return timestamp / one_second_in_ts; }; audiotstoseconds = function(timestamp, samplerate) { return timestamp / samplerate; }; audiotstovideots = function(timestamp, samplerate) { return secondstovideots(audiotstoseconds(timestamp, samplerate)); }; videotstoaudiots = function(timestamp, samplerate) { return secondstoaudiots(videotstoseconds(timestamp), samplerate); }; /** * adjust id3 tag or caption timing information by the timeline pts values * (if keeporiginaltimestamps is false) and convert to seconds */ metadatatstoseconds = function(timestamp, timelinestartpts, keeporiginaltimestamps) { return videotstoseconds(keeporiginaltimestamps ? timestamp : timestamp - timelinestartpts); }; module.exports = { one_second_in_ts: one_second_in_ts, secondstovideots: secondstovideots, secondstoaudiots: secondstoaudiots, videotstoseconds: videotstoseconds, audiotstoseconds: audiotstoseconds, audiotstovideots: audiotstovideots, videotstoaudiots: videotstoaudiots, metadatatstoseconds: metadatatstoseconds }; /***/ }) }]);