1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-05 19:42:38 +02:00
This commit is contained in:
DanieL 2023-02-13 14:41:08 -03:00
parent 64c36d9f4e
commit 0d0338876d
1197 changed files with 121461 additions and 179724 deletions

View file

@ -1,3 +1,30 @@
<a name="2.16.0"></a>
# [2.16.0](https://github.com/videojs/http-streaming/compare/v2.15.1...v2.16.0) (2023-01-30)
### Bug Fixes
* in-manifest VTT iOS MSE issue ([#1364](https://github.com/videojs/http-streaming/issues/1364)) ([e735188](https://github.com/videojs/http-streaming/commit/e735188))
<a name="2.15.1"></a>
## [2.15.1](https://github.com/videojs/http-streaming/compare/v2.15.0...v2.15.1) (2022-11-21)
### Bug Fixes
* Restart masterPlaylistLoader after media change ([#1339](https://github.com/videojs/http-streaming/issues/1339)) ([66707b4](https://github.com/videojs/http-streaming/commit/66707b4))
* resume loading on segment timeout for `experimentalBufferBasedABR` ([#1333](https://github.com/videojs/http-streaming/issues/1333)) ([5666562](https://github.com/videojs/http-streaming/commit/5666562))
### Chores
* update mpd-parser (main) ([#1336](https://github.com/videojs/http-streaming/issues/1336)) ([404ba76](https://github.com/videojs/http-streaming/commit/404ba76))
* update video.js for the example page ([#1340](https://github.com/videojs/http-streaming/issues/1340)) ([8a8b111](https://github.com/videojs/http-streaming/commit/8a8b111))
<a name="2.15.0"></a>
# [2.15.0](https://github.com/videojs/http-streaming/compare/v2.14.3...v2.15.0) (2022-09-14)
### Features
* add frameRate property to the representation class. ([#1289](https://github.com/videojs/http-streaming/issues/1289)) ([27a970c](https://github.com/videojs/http-streaming/commit/27a970c))
<a name="2.14.3"></a>
## [2.14.3](https://github.com/videojs/http-streaming/compare/v2.14.2...v2.14.3) (2022-08-31)

View file

@ -1,4 +1,4 @@
/*! @name @videojs/http-streaming @version 2.14.3 @license Apache-2.0 */
/*! @name @videojs/http-streaming @version 2.16.0 @license Apache-2.0 */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('video.js'), require('@xmldom/xmldom')) :
typeof define === 'function' && define.amd ? define(['exports', 'video.js', '@xmldom/xmldom'], factory) :
@ -470,7 +470,7 @@
return array;
}
/*! @name m3u8-parser @version 4.7.1 @license Apache-2.0 */
/*! @name m3u8-parser @version 4.8.0 @license Apache-2.0 */
/**
* A stream that buffers string input and generates a `data` event for each
* line.
@ -877,6 +877,10 @@
event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
}
if (event.attributes['FRAME-RATE']) {
event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);
}
if (event.attributes['PROGRAM-ID']) {
event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
}
@ -5471,7 +5475,7 @@
});
};
/*! @name mpd-parser @version 0.21.1 @license Apache-2.0 */
/*! @name mpd-parser @version 0.22.1 @license Apache-2.0 */
var isObject = function isObject(obj) {
return !!obj && typeof obj === 'object';
@ -6562,6 +6566,10 @@
segments: segments
};
if (attributes.frameRate) {
playlist.attributes['FRAME-RATE'] = attributes.frameRate;
}
if (attributes.contentProtection) {
playlist.contentProtection = attributes.contentProtection;
}
@ -7219,6 +7227,20 @@
var getContent = function getContent(element) {
return element.textContent.trim();
};
/**
* Converts the provided string that may contain a division operation to a number.
*
* @param {string} value - the provided string value
*
* @return {number} the parsed string value
*/
var parseDivisionValue = function parseDivisionValue(value) {
return parseFloat(value.split('/').reduce(function (prev, current) {
return prev / current;
}));
};
var parseDuration = function parseDuration(str) {
var SECONDS_IN_YEAR = 365 * 24 * 60 * 60;
@ -7387,6 +7409,18 @@
return parseInt(value, 10);
},
/**
* Specifies the frame rate of the representation
*
* @param {string} value
* value of attribute as a string
* @return {number}
* The parsed frame rate
*/
frameRate: function frameRate(value) {
return parseDivisionValue(value);
},
/**
* Specifies the number of the first Media Segment in this Representation in the Period
*
@ -9928,7 +9962,7 @@
return fn;
};
/* rollup-plugin-worker-factory start for worker!/Users/abarstow/videojs/http-streaming/src/transmuxer-worker.js */
/* rollup-plugin-worker-factory start for worker!/Users/ddashkevich/projects/vhs-release/src/transmuxer-worker.js */
var workerCode$1 = transform(function (self) {
/**
* mux.js
@ -18731,7 +18765,7 @@
};
});
var TransmuxWorker = factory(workerCode$1);
/* rollup-plugin-worker-factory end for worker!/Users/abarstow/videojs/http-streaming/src/transmuxer-worker.js */
/* rollup-plugin-worker-factory end for worker!/Users/ddashkevich/projects/vhs-release/src/transmuxer-worker.js */
var handleData_ = function handleData_(event, transmuxedData, callback) {
var _event$data$segment = event.data.segment,
@ -23823,6 +23857,7 @@
this.bandwidth = 1;
this.roundTrip = NaN;
this.trigger('bandwidthupdate');
this.trigger('timeout');
}
/**
* Handle the callback from the segmentRequest function and set the
@ -25315,6 +25350,111 @@
return SourceUpdater;
}(videojs__default["default"].EventTarget);
var getPrototypeOf = createCommonjsModule(function (module) {
function _getPrototypeOf(o) {
module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
module.exports["default"] = module.exports, module.exports.__esModule = true;
return _getPrototypeOf(o);
}
module.exports = _getPrototypeOf;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var isNativeFunction = createCommonjsModule(function (module) {
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
module.exports = _isNativeFunction;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var isNativeReflectConstruct = createCommonjsModule(function (module) {
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
module.exports = _isNativeReflectConstruct;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var construct = createCommonjsModule(function (module) {
function _construct(Parent, args, Class) {
if (isNativeReflectConstruct()) {
module.exports = _construct = Reflect.construct;
module.exports["default"] = module.exports, module.exports.__esModule = true;
} else {
module.exports = _construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) setPrototypeOf(instance, Class.prototype);
return instance;
};
module.exports["default"] = module.exports, module.exports.__esModule = true;
}
return _construct.apply(null, arguments);
}
module.exports = _construct;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var wrapNativeSuper = createCommonjsModule(function (module) {
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return construct(Class, arguments, getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return setPrototypeOf(Wrapper, Class);
};
module.exports["default"] = module.exports, module.exports.__esModule = true;
return _wrapNativeSuper(Class);
}
module.exports = _wrapNativeSuper;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var uint8ToUtf8 = function uint8ToUtf8(uintArray) {
return decodeURIComponent(escape(String.fromCharCode.apply(null, uintArray)));
};
@ -25322,6 +25462,16 @@
var VTT_LINE_TERMINATORS = new Uint8Array('\n\n'.split('').map(function (char) {
return char.charCodeAt(0);
}));
var NoVttJsError = /*#__PURE__*/function (_Error) {
inheritsLoose(NoVttJsError, _Error);
function NoVttJsError() {
return _Error.call(this, 'Trying to parse received VTT cues, but there is no WebVTT. Make sure vtt.js is loaded.') || this;
}
return NoVttJsError;
}( /*#__PURE__*/wrapNativeSuper(Error));
/**
* An object that manages segment loading and appending.
*
@ -25330,6 +25480,7 @@
* @extends videojs.EventTarget
*/
var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
inheritsLoose(VTTSegmentLoader, _SegmentLoader);
@ -25346,7 +25497,8 @@
_this.mediaSource_ = null;
_this.subtitlesTrack_ = null;
_this.loaderType_ = 'subtitle';
_this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks; // The VTT segment will have its own time mappings. Saving VTT segment timing info in
_this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks;
_this.loadVttJs = settings.loadVttJs; // The VTT segment will have its own time mappings. Saving VTT segment timing info in
// the sync controller leads to improper behavior.
_this.shouldSaveSegmentTimingInfo_ = false;
@ -25621,30 +25773,19 @@
segment.map.bytes = simpleSegment.map.bytes;
}
segmentInfo.bytes = simpleSegment.bytes; // Make sure that vttjs has loaded, otherwise, wait till it finished loading
segmentInfo.bytes = simpleSegment.bytes; // Make sure that vttjs has loaded, otherwise, load it and wait till it finished loading
if (typeof window.WebVTT !== 'function' && this.subtitlesTrack_ && this.subtitlesTrack_.tech_) {
var loadHandler;
if (typeof window.WebVTT !== 'function' && typeof this.loadVttJs === 'function') {
this.state = 'WAITING_ON_VTTJS'; // should be fine to call multiple times
// script will be loaded once but multiple listeners will be added to the queue, which is expected.
var errorHandler = function errorHandler() {
_this3.subtitlesTrack_.tech_.off('vttjsloaded', loadHandler);
_this3.stopForError({
this.loadVttJs().then(function () {
return _this3.segmentRequestFinished_(error, simpleSegment, result);
}, function () {
return _this3.stopForError({
message: 'Error loading vtt.js'
});
return;
};
loadHandler = function loadHandler() {
_this3.subtitlesTrack_.tech_.off('vttjserror', errorHandler);
_this3.segmentRequestFinished_(error, simpleSegment, result);
};
this.state = 'WAITING_ON_VTTJS';
this.subtitlesTrack_.tech_.one('vttjsloaded', loadHandler);
this.subtitlesTrack_.tech_.one('vttjserror', errorHandler);
});
return;
}
@ -25704,6 +25845,8 @@
/**
* Uses the WebVTT parser to parse the segment response
*
* @throws NoVttJsError
*
* @param {Object} segmentInfo
* a segment info object that describes the current segment
* @private
@ -25714,6 +25857,11 @@
var decoder;
var decodeBytesToString = false;
if (typeof window.WebVTT !== 'function') {
// caller is responsible for exception handling.
throw new NoVttJsError();
}
if (typeof window.TextDecoder === 'function') {
decoder = new window.TextDecoder('utf8');
} else {
@ -26550,7 +26698,7 @@
return TimelineChangeController;
}(videojs__default["default"].EventTarget);
/* rollup-plugin-worker-factory start for worker!/Users/abarstow/videojs/http-streaming/src/decrypter-worker.js */
/* rollup-plugin-worker-factory start for worker!/Users/ddashkevich/projects/vhs-release/src/decrypter-worker.js */
var workerCode = transform(function (self) {
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@ -27267,7 +27415,7 @@
};
});
var Decrypter = factory(workerCode);
/* rollup-plugin-worker-factory end for worker!/Users/abarstow/videojs/http-streaming/src/decrypter-worker.js */
/* rollup-plugin-worker-factory end for worker!/Users/ddashkevich/projects/vhs-release/src/decrypter-worker.js */
/**
* Convert the properties of an HLS track into an audioTrackKind.
@ -28396,7 +28544,25 @@
}), options);
_this.subtitleSegmentLoader_ = new VTTSegmentLoader(videojs__default["default"].mergeOptions(segmentLoaderSettings, {
loaderType: 'vtt',
featuresNativeTextTracks: _this.tech_.featuresNativeTextTracks
featuresNativeTextTracks: _this.tech_.featuresNativeTextTracks,
loadVttJs: function loadVttJs() {
return new Promise(function (resolve, reject) {
function onLoad() {
tech.off('vttjserror', onError);
resolve();
}
function onError() {
tech.off('vttjsloaded', onLoad);
reject();
}
tech.one('vttjsloaded', onLoad);
tech.one('vttjserror', onError); // safe to call multiple times, script will be loaded only once:
tech.addWebVttScript_();
});
}
}), options);
_this.setupSegmentLoaderListeners_();
@ -28486,16 +28652,20 @@
/**
* Run selectPlaylist and switch to the new playlist if we should
*
* @param {string} [reason=abr] a reason for why the ABR check is made
* @private
*
*/
;
_proto.checkABR_ = function checkABR_() {
_proto.checkABR_ = function checkABR_(reason) {
if (reason === void 0) {
reason = 'abr';
}
var nextPlaylist = this.selectPlaylist();
if (nextPlaylist && this.shouldSwitchToMedia_(nextPlaylist)) {
this.switchMedia_(nextPlaylist, 'abr');
this.switchMedia_(nextPlaylist, reason);
}
};
@ -28747,7 +28917,9 @@
_this3.requestOptions_.timeout = 0;
} else {
_this3.requestOptions_.timeout = requestTimeout;
} // TODO: Create a new event on the PlaylistLoader that signals
}
_this3.masterPlaylistLoader_.load(); // TODO: Create a new event on the PlaylistLoader that signals
// that the segments have changed in some way and use that to
// update the SegmentLoader instead of doing it twice here and
// on `loadedplaylist`
@ -28951,16 +29123,25 @@
_proto.setupSegmentLoaderListeners_ = function setupSegmentLoaderListeners_() {
var _this4 = this;
this.mainSegmentLoader_.on('bandwidthupdate', function () {
// Whether or not buffer based ABR or another ABR is used, on a bandwidth change it's
// useful to check to see if a rendition switch should be made.
_this4.checkABR_('bandwidthupdate');
_this4.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('timeout', function () {
if (_this4.experimentalBufferBasedABR) {
// If a rendition change is needed, then it would've be done on `bandwidthupdate`.
// Here the only consideration is that for buffer based ABR there's no guarantee
// of an immediate switch (since the bandwidth is averaged with a timeout
// bandwidth value of 1), so force a load on the segment loader to keep it going.
_this4.mainSegmentLoader_.load();
}
}); // `progress` events are not reliable enough of a bandwidth measure to trigger buffer
// based ABR.
if (!this.experimentalBufferBasedABR) {
this.mainSegmentLoader_.on('bandwidthupdate', function () {
var nextPlaylist = _this4.selectPlaylist();
if (_this4.shouldSwitchToMedia_(nextPlaylist)) {
_this4.switchMedia_(nextPlaylist, 'bandwidthupdate');
}
_this4.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('progress', function () {
_this4.trigger('progress');
});
@ -30257,6 +30438,7 @@
this.width = resolution && resolution.width;
this.height = resolution && resolution.height;
this.bandwidth = playlist.attributes.BANDWIDTH;
this.frameRate = playlist.attributes['FRAME-RATE'];
}
this.codecs = codecsForPlaylist(mpc.master(), playlist);
@ -31096,13 +31278,13 @@
initPlugin(this, options);
};
var version$4 = "2.14.3";
var version$4 = "2.16.0";
var version$3 = "6.0.1";
var version$2 = "0.21.1";
var version$2 = "0.22.1";
var version$1 = "4.7.1";
var version$1 = "4.8.0";
var version = "3.1.3";
@ -32364,23 +32546,33 @@
return tech.vhs;
},
canPlayType: function canPlayType(type, options) {
var simpleType = simpleTypeFromSourceType(type);
if (!simpleType) {
return '';
}
var overrideNative = VhsSourceHandler.getOverrideNative(options);
var supportsTypeNatively = Vhs.supportsTypeNatively(simpleType);
var canUseMsePlayback = !supportsTypeNatively || overrideNative;
return canUseMsePlayback ? 'maybe' : '';
},
getOverrideNative: function getOverrideNative(options) {
if (options === void 0) {
options = {};
}
var _videojs$mergeOptions = videojs__default["default"].mergeOptions(videojs__default["default"].options, options),
_videojs$mergeOptions2 = _videojs$mergeOptions.vhs;
_videojs$mergeOptions2 = _videojs$mergeOptions2 === void 0 ? {} : _videojs$mergeOptions2;
var _videojs$mergeOptions3 = _videojs$mergeOptions2.overrideNative,
overrideNative = _videojs$mergeOptions3 === void 0 ? !videojs__default["default"].browser.IS_ANY_SAFARI : _videojs$mergeOptions3,
_videojs$mergeOptions4 = _videojs$mergeOptions.hls;
_videojs$mergeOptions4 = _videojs$mergeOptions4 === void 0 ? {} : _videojs$mergeOptions4;
var _videojs$mergeOptions5 = _videojs$mergeOptions4.overrideNative,
legacyOverrideNative = _videojs$mergeOptions5 === void 0 ? false : _videojs$mergeOptions5;
var supportedType = simpleTypeFromSourceType(type);
var canUseMsePlayback = supportedType && (!Vhs.supportsTypeNatively(supportedType) || legacyOverrideNative || overrideNative);
return canUseMsePlayback ? 'maybe' : '';
var _options = options,
_options$vhs = _options.vhs,
vhs = _options$vhs === void 0 ? {} : _options$vhs,
_options$hls = _options.hls,
hls = _options$hls === void 0 ? {} : _options$hls;
var defaultOverrideNative = !(videojs__default["default"].browser.IS_ANY_SAFARI || videojs__default["default"].browser.IS_IOS);
var _vhs$overrideNative = vhs.overrideNative,
overrideNative = _vhs$overrideNative === void 0 ? defaultOverrideNative : _vhs$overrideNative;
var _hls$overrideNative = hls.overrideNative,
legacyOverrideNative = _hls$overrideNative === void 0 ? false : _hls$overrideNative;
return legacyOverrideNative || overrideNative;
}
};
/**

View file

@ -1,4 +1,4 @@
/*! @name @videojs/http-streaming @version 2.14.3 @license Apache-2.0 */
/*! @name @videojs/http-streaming @version 2.16.0 @license Apache-2.0 */
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
@ -19,6 +19,7 @@ var parseSidx = require('mux.js/lib/tools/parse-sidx');
var id3Helpers = require('@videojs/vhs-utils/cjs/id3-helpers');
var containers = require('@videojs/vhs-utils/cjs/containers');
var clock = require('mux.js/lib/utils/clock');
var _wrapNativeSuper = require('@babel/runtime/helpers/wrapNativeSuper');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@ -30,6 +31,7 @@ var _resolveUrl__default = /*#__PURE__*/_interopDefaultLegacy(_resolveUrl);
var videojs__default = /*#__PURE__*/_interopDefaultLegacy(videojs);
var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
var parseSidx__default = /*#__PURE__*/_interopDefaultLegacy(parseSidx);
var _wrapNativeSuper__default = /*#__PURE__*/_interopDefaultLegacy(_wrapNativeSuper);
/**
* @file resolve-url.js - Handling how URLs are resolved and manipulated
@ -4084,7 +4086,7 @@ var getWorkerString = function getWorkerString(fn) {
return fn.toString().replace(/^function.+?{/, '').slice(0, -1);
};
/* rollup-plugin-worker-factory start for worker!/Users/abarstow/videojs/http-streaming/src/transmuxer-worker.js */
/* rollup-plugin-worker-factory start for worker!/Users/ddashkevich/projects/vhs-release/src/transmuxer-worker.js */
var workerCode$1 = transform(getWorkerString(function () {
/**
* mux.js
@ -12887,7 +12889,7 @@ var workerCode$1 = transform(getWorkerString(function () {
};
}));
var TransmuxWorker = factory(workerCode$1);
/* rollup-plugin-worker-factory end for worker!/Users/abarstow/videojs/http-streaming/src/transmuxer-worker.js */
/* rollup-plugin-worker-factory end for worker!/Users/ddashkevich/projects/vhs-release/src/transmuxer-worker.js */
var handleData_ = function handleData_(event, transmuxedData, callback) {
var _event$data$segment = event.data.segment,
@ -17919,6 +17921,7 @@ var SegmentLoader = /*#__PURE__*/function (_videojs$EventTarget) {
this.bandwidth = 1;
this.roundTrip = NaN;
this.trigger('bandwidthupdate');
this.trigger('timeout');
}
/**
* Handle the callback from the segmentRequest function and set the
@ -19418,6 +19421,16 @@ var uint8ToUtf8 = function uint8ToUtf8(uintArray) {
var VTT_LINE_TERMINATORS = new Uint8Array('\n\n'.split('').map(function (char) {
return char.charCodeAt(0);
}));
var NoVttJsError = /*#__PURE__*/function (_Error) {
_inheritsLoose__default["default"](NoVttJsError, _Error);
function NoVttJsError() {
return _Error.call(this, 'Trying to parse received VTT cues, but there is no WebVTT. Make sure vtt.js is loaded.') || this;
}
return NoVttJsError;
}( /*#__PURE__*/_wrapNativeSuper__default["default"](Error));
/**
* An object that manages segment loading and appending.
*
@ -19426,6 +19439,7 @@ var VTT_LINE_TERMINATORS = new Uint8Array('\n\n'.split('').map(function (char) {
* @extends videojs.EventTarget
*/
var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
_inheritsLoose__default["default"](VTTSegmentLoader, _SegmentLoader);
@ -19442,7 +19456,8 @@ var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
_this.mediaSource_ = null;
_this.subtitlesTrack_ = null;
_this.loaderType_ = 'subtitle';
_this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks; // The VTT segment will have its own time mappings. Saving VTT segment timing info in
_this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks;
_this.loadVttJs = settings.loadVttJs; // The VTT segment will have its own time mappings. Saving VTT segment timing info in
// the sync controller leads to improper behavior.
_this.shouldSaveSegmentTimingInfo_ = false;
@ -19717,30 +19732,19 @@ var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
segment.map.bytes = simpleSegment.map.bytes;
}
segmentInfo.bytes = simpleSegment.bytes; // Make sure that vttjs has loaded, otherwise, wait till it finished loading
segmentInfo.bytes = simpleSegment.bytes; // Make sure that vttjs has loaded, otherwise, load it and wait till it finished loading
if (typeof window__default["default"].WebVTT !== 'function' && this.subtitlesTrack_ && this.subtitlesTrack_.tech_) {
var loadHandler;
if (typeof window__default["default"].WebVTT !== 'function' && typeof this.loadVttJs === 'function') {
this.state = 'WAITING_ON_VTTJS'; // should be fine to call multiple times
// script will be loaded once but multiple listeners will be added to the queue, which is expected.
var errorHandler = function errorHandler() {
_this3.subtitlesTrack_.tech_.off('vttjsloaded', loadHandler);
_this3.stopForError({
this.loadVttJs().then(function () {
return _this3.segmentRequestFinished_(error, simpleSegment, result);
}, function () {
return _this3.stopForError({
message: 'Error loading vtt.js'
});
return;
};
loadHandler = function loadHandler() {
_this3.subtitlesTrack_.tech_.off('vttjserror', errorHandler);
_this3.segmentRequestFinished_(error, simpleSegment, result);
};
this.state = 'WAITING_ON_VTTJS';
this.subtitlesTrack_.tech_.one('vttjsloaded', loadHandler);
this.subtitlesTrack_.tech_.one('vttjserror', errorHandler);
});
return;
}
@ -19800,6 +19804,8 @@ var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
/**
* Uses the WebVTT parser to parse the segment response
*
* @throws NoVttJsError
*
* @param {Object} segmentInfo
* a segment info object that describes the current segment
* @private
@ -19810,6 +19816,11 @@ var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
var decoder;
var decodeBytesToString = false;
if (typeof window__default["default"].WebVTT !== 'function') {
// caller is responsible for exception handling.
throw new NoVttJsError();
}
if (typeof window__default["default"].TextDecoder === 'function') {
decoder = new window__default["default"].TextDecoder('utf8');
} else {
@ -20646,7 +20657,7 @@ var TimelineChangeController = /*#__PURE__*/function (_videojs$EventTarget) {
return TimelineChangeController;
}(videojs__default["default"].EventTarget);
/* rollup-plugin-worker-factory start for worker!/Users/abarstow/videojs/http-streaming/src/decrypter-worker.js */
/* rollup-plugin-worker-factory start for worker!/Users/ddashkevich/projects/vhs-release/src/decrypter-worker.js */
var workerCode = transform(getWorkerString(function () {
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@ -21363,7 +21374,7 @@ var workerCode = transform(getWorkerString(function () {
};
}));
var Decrypter = factory(workerCode);
/* rollup-plugin-worker-factory end for worker!/Users/abarstow/videojs/http-streaming/src/decrypter-worker.js */
/* rollup-plugin-worker-factory end for worker!/Users/ddashkevich/projects/vhs-release/src/decrypter-worker.js */
/**
* Convert the properties of an HLS track into an audioTrackKind.
@ -22492,7 +22503,25 @@ var MasterPlaylistController = /*#__PURE__*/function (_videojs$EventTarget) {
}), options);
_this.subtitleSegmentLoader_ = new VTTSegmentLoader(videojs__default["default"].mergeOptions(segmentLoaderSettings, {
loaderType: 'vtt',
featuresNativeTextTracks: _this.tech_.featuresNativeTextTracks
featuresNativeTextTracks: _this.tech_.featuresNativeTextTracks,
loadVttJs: function loadVttJs() {
return new Promise(function (resolve, reject) {
function onLoad() {
tech.off('vttjserror', onError);
resolve();
}
function onError() {
tech.off('vttjsloaded', onLoad);
reject();
}
tech.one('vttjsloaded', onLoad);
tech.one('vttjserror', onError); // safe to call multiple times, script will be loaded only once:
tech.addWebVttScript_();
});
}
}), options);
_this.setupSegmentLoaderListeners_();
@ -22582,16 +22611,20 @@ var MasterPlaylistController = /*#__PURE__*/function (_videojs$EventTarget) {
/**
* Run selectPlaylist and switch to the new playlist if we should
*
* @param {string} [reason=abr] a reason for why the ABR check is made
* @private
*
*/
;
_proto.checkABR_ = function checkABR_() {
_proto.checkABR_ = function checkABR_(reason) {
if (reason === void 0) {
reason = 'abr';
}
var nextPlaylist = this.selectPlaylist();
if (nextPlaylist && this.shouldSwitchToMedia_(nextPlaylist)) {
this.switchMedia_(nextPlaylist, 'abr');
this.switchMedia_(nextPlaylist, reason);
}
};
@ -22843,7 +22876,9 @@ var MasterPlaylistController = /*#__PURE__*/function (_videojs$EventTarget) {
_this3.requestOptions_.timeout = 0;
} else {
_this3.requestOptions_.timeout = requestTimeout;
} // TODO: Create a new event on the PlaylistLoader that signals
}
_this3.masterPlaylistLoader_.load(); // TODO: Create a new event on the PlaylistLoader that signals
// that the segments have changed in some way and use that to
// update the SegmentLoader instead of doing it twice here and
// on `loadedplaylist`
@ -23047,16 +23082,25 @@ var MasterPlaylistController = /*#__PURE__*/function (_videojs$EventTarget) {
_proto.setupSegmentLoaderListeners_ = function setupSegmentLoaderListeners_() {
var _this4 = this;
this.mainSegmentLoader_.on('bandwidthupdate', function () {
// Whether or not buffer based ABR or another ABR is used, on a bandwidth change it's
// useful to check to see if a rendition switch should be made.
_this4.checkABR_('bandwidthupdate');
_this4.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('timeout', function () {
if (_this4.experimentalBufferBasedABR) {
// If a rendition change is needed, then it would've be done on `bandwidthupdate`.
// Here the only consideration is that for buffer based ABR there's no guarantee
// of an immediate switch (since the bandwidth is averaged with a timeout
// bandwidth value of 1), so force a load on the segment loader to keep it going.
_this4.mainSegmentLoader_.load();
}
}); // `progress` events are not reliable enough of a bandwidth measure to trigger buffer
// based ABR.
if (!this.experimentalBufferBasedABR) {
this.mainSegmentLoader_.on('bandwidthupdate', function () {
var nextPlaylist = _this4.selectPlaylist();
if (_this4.shouldSwitchToMedia_(nextPlaylist)) {
_this4.switchMedia_(nextPlaylist, 'bandwidthupdate');
}
_this4.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('progress', function () {
_this4.trigger('progress');
});
@ -24353,6 +24397,7 @@ var Representation = function Representation(vhsHandler, playlist, id) {
this.width = resolution && resolution.width;
this.height = resolution && resolution.height;
this.bandwidth = playlist.attributes.BANDWIDTH;
this.frameRate = playlist.attributes['FRAME-RATE'];
}
this.codecs = codecsForPlaylist(mpc.master(), playlist);
@ -25192,13 +25237,13 @@ var reloadSourceOnError = function reloadSourceOnError(options) {
initPlugin(this, options);
};
var version$4 = "2.14.3";
var version$4 = "2.16.0";
var version$3 = "6.0.1";
var version$2 = "0.21.1";
var version$2 = "0.22.1";
var version$1 = "4.7.1";
var version$1 = "4.8.0";
var version = "3.1.3";
@ -26460,23 +26505,33 @@ var VhsSourceHandler = {
return tech.vhs;
},
canPlayType: function canPlayType(type, options) {
var simpleType = mediaTypes_js.simpleTypeFromSourceType(type);
if (!simpleType) {
return '';
}
var overrideNative = VhsSourceHandler.getOverrideNative(options);
var supportsTypeNatively = Vhs.supportsTypeNatively(simpleType);
var canUseMsePlayback = !supportsTypeNatively || overrideNative;
return canUseMsePlayback ? 'maybe' : '';
},
getOverrideNative: function getOverrideNative(options) {
if (options === void 0) {
options = {};
}
var _videojs$mergeOptions = videojs__default["default"].mergeOptions(videojs__default["default"].options, options),
_videojs$mergeOptions2 = _videojs$mergeOptions.vhs;
_videojs$mergeOptions2 = _videojs$mergeOptions2 === void 0 ? {} : _videojs$mergeOptions2;
var _videojs$mergeOptions3 = _videojs$mergeOptions2.overrideNative,
overrideNative = _videojs$mergeOptions3 === void 0 ? !videojs__default["default"].browser.IS_ANY_SAFARI : _videojs$mergeOptions3,
_videojs$mergeOptions4 = _videojs$mergeOptions.hls;
_videojs$mergeOptions4 = _videojs$mergeOptions4 === void 0 ? {} : _videojs$mergeOptions4;
var _videojs$mergeOptions5 = _videojs$mergeOptions4.overrideNative,
legacyOverrideNative = _videojs$mergeOptions5 === void 0 ? false : _videojs$mergeOptions5;
var supportedType = mediaTypes_js.simpleTypeFromSourceType(type);
var canUseMsePlayback = supportedType && (!Vhs.supportsTypeNatively(supportedType) || legacyOverrideNative || overrideNative);
return canUseMsePlayback ? 'maybe' : '';
var _options = options,
_options$vhs = _options.vhs,
vhs = _options$vhs === void 0 ? {} : _options$vhs,
_options$hls = _options.hls,
hls = _options$hls === void 0 ? {} : _options$hls;
var defaultOverrideNative = !(videojs__default["default"].browser.IS_ANY_SAFARI || videojs__default["default"].browser.IS_IOS);
var _vhs$overrideNative = vhs.overrideNative,
overrideNative = _vhs$overrideNative === void 0 ? defaultOverrideNative : _vhs$overrideNative;
var _hls$overrideNative = hls.overrideNative,
legacyOverrideNative = _hls$overrideNative === void 0 ? false : _hls$overrideNative;
return legacyOverrideNative || overrideNative;
}
};
/**

View file

@ -1,4 +1,4 @@
/*! @name @videojs/http-streaming @version 2.14.3 @license Apache-2.0 */
/*! @name @videojs/http-streaming @version 2.16.0 @license Apache-2.0 */
import _assertThisInitialized from '@babel/runtime/helpers/assertThisInitialized';
import _inheritsLoose from '@babel/runtime/helpers/inheritsLoose';
import document from 'global/document';
@ -16,6 +16,7 @@ import parseSidx from 'mux.js/lib/tools/parse-sidx';
import { getId3Offset } from '@videojs/vhs-utils/es/id3-helpers';
import { detectContainerForBytes, isLikelyFmp4MediaSegment } from '@videojs/vhs-utils/es/containers';
import { ONE_SECOND_IN_TS } from 'mux.js/lib/utils/clock';
import _wrapNativeSuper from '@babel/runtime/helpers/wrapNativeSuper';
/**
* @file resolve-url.js - Handling how URLs are resolved and manipulated
@ -4070,7 +4071,7 @@ var getWorkerString = function getWorkerString(fn) {
return fn.toString().replace(/^function.+?{/, '').slice(0, -1);
};
/* rollup-plugin-worker-factory start for worker!/Users/abarstow/videojs/http-streaming/src/transmuxer-worker.js */
/* rollup-plugin-worker-factory start for worker!/Users/ddashkevich/projects/vhs-release/src/transmuxer-worker.js */
var workerCode$1 = transform(getWorkerString(function () {
/**
* mux.js
@ -12873,7 +12874,7 @@ var workerCode$1 = transform(getWorkerString(function () {
};
}));
var TransmuxWorker = factory(workerCode$1);
/* rollup-plugin-worker-factory end for worker!/Users/abarstow/videojs/http-streaming/src/transmuxer-worker.js */
/* rollup-plugin-worker-factory end for worker!/Users/ddashkevich/projects/vhs-release/src/transmuxer-worker.js */
var handleData_ = function handleData_(event, transmuxedData, callback) {
var _event$data$segment = event.data.segment,
@ -17905,6 +17906,7 @@ var SegmentLoader = /*#__PURE__*/function (_videojs$EventTarget) {
this.bandwidth = 1;
this.roundTrip = NaN;
this.trigger('bandwidthupdate');
this.trigger('timeout');
}
/**
* Handle the callback from the segmentRequest function and set the
@ -19404,6 +19406,16 @@ var uint8ToUtf8 = function uint8ToUtf8(uintArray) {
var VTT_LINE_TERMINATORS = new Uint8Array('\n\n'.split('').map(function (char) {
return char.charCodeAt(0);
}));
var NoVttJsError = /*#__PURE__*/function (_Error) {
_inheritsLoose(NoVttJsError, _Error);
function NoVttJsError() {
return _Error.call(this, 'Trying to parse received VTT cues, but there is no WebVTT. Make sure vtt.js is loaded.') || this;
}
return NoVttJsError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
/**
* An object that manages segment loading and appending.
*
@ -19412,6 +19424,7 @@ var VTT_LINE_TERMINATORS = new Uint8Array('\n\n'.split('').map(function (char) {
* @extends videojs.EventTarget
*/
var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
_inheritsLoose(VTTSegmentLoader, _SegmentLoader);
@ -19428,7 +19441,8 @@ var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
_this.mediaSource_ = null;
_this.subtitlesTrack_ = null;
_this.loaderType_ = 'subtitle';
_this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks; // The VTT segment will have its own time mappings. Saving VTT segment timing info in
_this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks;
_this.loadVttJs = settings.loadVttJs; // The VTT segment will have its own time mappings. Saving VTT segment timing info in
// the sync controller leads to improper behavior.
_this.shouldSaveSegmentTimingInfo_ = false;
@ -19703,30 +19717,19 @@ var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
segment.map.bytes = simpleSegment.map.bytes;
}
segmentInfo.bytes = simpleSegment.bytes; // Make sure that vttjs has loaded, otherwise, wait till it finished loading
segmentInfo.bytes = simpleSegment.bytes; // Make sure that vttjs has loaded, otherwise, load it and wait till it finished loading
if (typeof window$1.WebVTT !== 'function' && this.subtitlesTrack_ && this.subtitlesTrack_.tech_) {
var loadHandler;
if (typeof window$1.WebVTT !== 'function' && typeof this.loadVttJs === 'function') {
this.state = 'WAITING_ON_VTTJS'; // should be fine to call multiple times
// script will be loaded once but multiple listeners will be added to the queue, which is expected.
var errorHandler = function errorHandler() {
_this3.subtitlesTrack_.tech_.off('vttjsloaded', loadHandler);
_this3.stopForError({
this.loadVttJs().then(function () {
return _this3.segmentRequestFinished_(error, simpleSegment, result);
}, function () {
return _this3.stopForError({
message: 'Error loading vtt.js'
});
return;
};
loadHandler = function loadHandler() {
_this3.subtitlesTrack_.tech_.off('vttjserror', errorHandler);
_this3.segmentRequestFinished_(error, simpleSegment, result);
};
this.state = 'WAITING_ON_VTTJS';
this.subtitlesTrack_.tech_.one('vttjsloaded', loadHandler);
this.subtitlesTrack_.tech_.one('vttjserror', errorHandler);
});
return;
}
@ -19786,6 +19789,8 @@ var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
/**
* Uses the WebVTT parser to parse the segment response
*
* @throws NoVttJsError
*
* @param {Object} segmentInfo
* a segment info object that describes the current segment
* @private
@ -19796,6 +19801,11 @@ var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
var decoder;
var decodeBytesToString = false;
if (typeof window$1.WebVTT !== 'function') {
// caller is responsible for exception handling.
throw new NoVttJsError();
}
if (typeof window$1.TextDecoder === 'function') {
decoder = new window$1.TextDecoder('utf8');
} else {
@ -20632,7 +20642,7 @@ var TimelineChangeController = /*#__PURE__*/function (_videojs$EventTarget) {
return TimelineChangeController;
}(videojs.EventTarget);
/* rollup-plugin-worker-factory start for worker!/Users/abarstow/videojs/http-streaming/src/decrypter-worker.js */
/* rollup-plugin-worker-factory start for worker!/Users/ddashkevich/projects/vhs-release/src/decrypter-worker.js */
var workerCode = transform(getWorkerString(function () {
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@ -21349,7 +21359,7 @@ var workerCode = transform(getWorkerString(function () {
};
}));
var Decrypter = factory(workerCode);
/* rollup-plugin-worker-factory end for worker!/Users/abarstow/videojs/http-streaming/src/decrypter-worker.js */
/* rollup-plugin-worker-factory end for worker!/Users/ddashkevich/projects/vhs-release/src/decrypter-worker.js */
/**
* Convert the properties of an HLS track into an audioTrackKind.
@ -22478,7 +22488,25 @@ var MasterPlaylistController = /*#__PURE__*/function (_videojs$EventTarget) {
}), options);
_this.subtitleSegmentLoader_ = new VTTSegmentLoader(videojs.mergeOptions(segmentLoaderSettings, {
loaderType: 'vtt',
featuresNativeTextTracks: _this.tech_.featuresNativeTextTracks
featuresNativeTextTracks: _this.tech_.featuresNativeTextTracks,
loadVttJs: function loadVttJs() {
return new Promise(function (resolve, reject) {
function onLoad() {
tech.off('vttjserror', onError);
resolve();
}
function onError() {
tech.off('vttjsloaded', onLoad);
reject();
}
tech.one('vttjsloaded', onLoad);
tech.one('vttjserror', onError); // safe to call multiple times, script will be loaded only once:
tech.addWebVttScript_();
});
}
}), options);
_this.setupSegmentLoaderListeners_();
@ -22568,16 +22596,20 @@ var MasterPlaylistController = /*#__PURE__*/function (_videojs$EventTarget) {
/**
* Run selectPlaylist and switch to the new playlist if we should
*
* @param {string} [reason=abr] a reason for why the ABR check is made
* @private
*
*/
;
_proto.checkABR_ = function checkABR_() {
_proto.checkABR_ = function checkABR_(reason) {
if (reason === void 0) {
reason = 'abr';
}
var nextPlaylist = this.selectPlaylist();
if (nextPlaylist && this.shouldSwitchToMedia_(nextPlaylist)) {
this.switchMedia_(nextPlaylist, 'abr');
this.switchMedia_(nextPlaylist, reason);
}
};
@ -22829,7 +22861,9 @@ var MasterPlaylistController = /*#__PURE__*/function (_videojs$EventTarget) {
_this3.requestOptions_.timeout = 0;
} else {
_this3.requestOptions_.timeout = requestTimeout;
} // TODO: Create a new event on the PlaylistLoader that signals
}
_this3.masterPlaylistLoader_.load(); // TODO: Create a new event on the PlaylistLoader that signals
// that the segments have changed in some way and use that to
// update the SegmentLoader instead of doing it twice here and
// on `loadedplaylist`
@ -23033,16 +23067,25 @@ var MasterPlaylistController = /*#__PURE__*/function (_videojs$EventTarget) {
_proto.setupSegmentLoaderListeners_ = function setupSegmentLoaderListeners_() {
var _this4 = this;
this.mainSegmentLoader_.on('bandwidthupdate', function () {
// Whether or not buffer based ABR or another ABR is used, on a bandwidth change it's
// useful to check to see if a rendition switch should be made.
_this4.checkABR_('bandwidthupdate');
_this4.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('timeout', function () {
if (_this4.experimentalBufferBasedABR) {
// If a rendition change is needed, then it would've be done on `bandwidthupdate`.
// Here the only consideration is that for buffer based ABR there's no guarantee
// of an immediate switch (since the bandwidth is averaged with a timeout
// bandwidth value of 1), so force a load on the segment loader to keep it going.
_this4.mainSegmentLoader_.load();
}
}); // `progress` events are not reliable enough of a bandwidth measure to trigger buffer
// based ABR.
if (!this.experimentalBufferBasedABR) {
this.mainSegmentLoader_.on('bandwidthupdate', function () {
var nextPlaylist = _this4.selectPlaylist();
if (_this4.shouldSwitchToMedia_(nextPlaylist)) {
_this4.switchMedia_(nextPlaylist, 'bandwidthupdate');
}
_this4.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('progress', function () {
_this4.trigger('progress');
});
@ -24339,6 +24382,7 @@ var Representation = function Representation(vhsHandler, playlist, id) {
this.width = resolution && resolution.width;
this.height = resolution && resolution.height;
this.bandwidth = playlist.attributes.BANDWIDTH;
this.frameRate = playlist.attributes['FRAME-RATE'];
}
this.codecs = codecsForPlaylist(mpc.master(), playlist);
@ -25178,13 +25222,13 @@ var reloadSourceOnError = function reloadSourceOnError(options) {
initPlugin(this, options);
};
var version$4 = "2.14.3";
var version$4 = "2.16.0";
var version$3 = "6.0.1";
var version$2 = "0.21.1";
var version$2 = "0.22.1";
var version$1 = "4.7.1";
var version$1 = "4.8.0";
var version = "3.1.3";
@ -26446,23 +26490,33 @@ var VhsSourceHandler = {
return tech.vhs;
},
canPlayType: function canPlayType(type, options) {
var simpleType = simpleTypeFromSourceType(type);
if (!simpleType) {
return '';
}
var overrideNative = VhsSourceHandler.getOverrideNative(options);
var supportsTypeNatively = Vhs.supportsTypeNatively(simpleType);
var canUseMsePlayback = !supportsTypeNatively || overrideNative;
return canUseMsePlayback ? 'maybe' : '';
},
getOverrideNative: function getOverrideNative(options) {
if (options === void 0) {
options = {};
}
var _videojs$mergeOptions = videojs.mergeOptions(videojs.options, options),
_videojs$mergeOptions2 = _videojs$mergeOptions.vhs;
_videojs$mergeOptions2 = _videojs$mergeOptions2 === void 0 ? {} : _videojs$mergeOptions2;
var _videojs$mergeOptions3 = _videojs$mergeOptions2.overrideNative,
overrideNative = _videojs$mergeOptions3 === void 0 ? !videojs.browser.IS_ANY_SAFARI : _videojs$mergeOptions3,
_videojs$mergeOptions4 = _videojs$mergeOptions.hls;
_videojs$mergeOptions4 = _videojs$mergeOptions4 === void 0 ? {} : _videojs$mergeOptions4;
var _videojs$mergeOptions5 = _videojs$mergeOptions4.overrideNative,
legacyOverrideNative = _videojs$mergeOptions5 === void 0 ? false : _videojs$mergeOptions5;
var supportedType = simpleTypeFromSourceType(type);
var canUseMsePlayback = supportedType && (!Vhs.supportsTypeNatively(supportedType) || legacyOverrideNative || overrideNative);
return canUseMsePlayback ? 'maybe' : '';
var _options = options,
_options$vhs = _options.vhs,
vhs = _options$vhs === void 0 ? {} : _options$vhs,
_options$hls = _options.hls,
hls = _options$hls === void 0 ? {} : _options$hls;
var defaultOverrideNative = !(videojs.browser.IS_ANY_SAFARI || videojs.browser.IS_IOS);
var _vhs$overrideNative = vhs.overrideNative,
overrideNative = _vhs$overrideNative === void 0 ? defaultOverrideNative : _vhs$overrideNative;
var _hls$overrideNative = hls.overrideNative,
legacyOverrideNative = _hls$overrideNative === void 0 ? false : _hls$overrideNative;
return legacyOverrideNative || overrideNative;
}
};
/**

View file

@ -1,4 +1,4 @@
/*! @name @videojs/http-streaming @version 2.14.3 @license Apache-2.0 */
/*! @name @videojs/http-streaming @version 2.16.0 @license Apache-2.0 */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('video.js'), require('@xmldom/xmldom')) :
typeof define === 'function' && define.amd ? define(['exports', 'video.js', '@xmldom/xmldom'], factory) :
@ -470,7 +470,7 @@
return array;
}
/*! @name m3u8-parser @version 4.7.1 @license Apache-2.0 */
/*! @name m3u8-parser @version 4.8.0 @license Apache-2.0 */
/**
* A stream that buffers string input and generates a `data` event for each
* line.
@ -877,6 +877,10 @@
event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
}
if (event.attributes['FRAME-RATE']) {
event.attributes['FRAME-RATE'] = parseFloat(event.attributes['FRAME-RATE']);
}
if (event.attributes['PROGRAM-ID']) {
event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
}
@ -5471,7 +5475,7 @@
});
};
/*! @name mpd-parser @version 0.21.1 @license Apache-2.0 */
/*! @name mpd-parser @version 0.22.1 @license Apache-2.0 */
var isObject = function isObject(obj) {
return !!obj && typeof obj === 'object';
@ -6562,6 +6566,10 @@
segments: segments
};
if (attributes.frameRate) {
playlist.attributes['FRAME-RATE'] = attributes.frameRate;
}
if (attributes.contentProtection) {
playlist.contentProtection = attributes.contentProtection;
}
@ -7219,6 +7227,20 @@
var getContent = function getContent(element) {
return element.textContent.trim();
};
/**
* Converts the provided string that may contain a division operation to a number.
*
* @param {string} value - the provided string value
*
* @return {number} the parsed string value
*/
var parseDivisionValue = function parseDivisionValue(value) {
return parseFloat(value.split('/').reduce(function (prev, current) {
return prev / current;
}));
};
var parseDuration = function parseDuration(str) {
var SECONDS_IN_YEAR = 365 * 24 * 60 * 60;
@ -7387,6 +7409,18 @@
return parseInt(value, 10);
},
/**
* Specifies the frame rate of the representation
*
* @param {string} value
* value of attribute as a string
* @return {number}
* The parsed frame rate
*/
frameRate: function frameRate(value) {
return parseDivisionValue(value);
},
/**
* Specifies the number of the first Media Segment in this Representation in the Period
*
@ -9875,7 +9909,7 @@
return fn.toString().replace(/^function.+?{/, '').slice(0, -1);
};
/* rollup-plugin-worker-factory start for worker!/Users/abarstow/videojs/http-streaming/src/transmuxer-worker.js */
/* rollup-plugin-worker-factory start for worker!/Users/ddashkevich/projects/vhs-release/src/transmuxer-worker.js */
var workerCode$1 = transform(getWorkerString(function () {
/**
* mux.js
@ -18678,7 +18712,7 @@
};
}));
var TransmuxWorker = factory(workerCode$1);
/* rollup-plugin-worker-factory end for worker!/Users/abarstow/videojs/http-streaming/src/transmuxer-worker.js */
/* rollup-plugin-worker-factory end for worker!/Users/ddashkevich/projects/vhs-release/src/transmuxer-worker.js */
var handleData_ = function handleData_(event, transmuxedData, callback) {
var _event$data$segment = event.data.segment,
@ -23770,6 +23804,7 @@
this.bandwidth = 1;
this.roundTrip = NaN;
this.trigger('bandwidthupdate');
this.trigger('timeout');
}
/**
* Handle the callback from the segmentRequest function and set the
@ -25262,6 +25297,111 @@
return SourceUpdater;
}(videojs__default["default"].EventTarget);
var getPrototypeOf = createCommonjsModule(function (module) {
function _getPrototypeOf(o) {
module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
module.exports["default"] = module.exports, module.exports.__esModule = true;
return _getPrototypeOf(o);
}
module.exports = _getPrototypeOf;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var isNativeFunction = createCommonjsModule(function (module) {
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
module.exports = _isNativeFunction;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var isNativeReflectConstruct = createCommonjsModule(function (module) {
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
module.exports = _isNativeReflectConstruct;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var construct = createCommonjsModule(function (module) {
function _construct(Parent, args, Class) {
if (isNativeReflectConstruct()) {
module.exports = _construct = Reflect.construct;
module.exports["default"] = module.exports, module.exports.__esModule = true;
} else {
module.exports = _construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) setPrototypeOf(instance, Class.prototype);
return instance;
};
module.exports["default"] = module.exports, module.exports.__esModule = true;
}
return _construct.apply(null, arguments);
}
module.exports = _construct;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var wrapNativeSuper = createCommonjsModule(function (module) {
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return construct(Class, arguments, getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return setPrototypeOf(Wrapper, Class);
};
module.exports["default"] = module.exports, module.exports.__esModule = true;
return _wrapNativeSuper(Class);
}
module.exports = _wrapNativeSuper;
module.exports["default"] = module.exports, module.exports.__esModule = true;
});
var uint8ToUtf8 = function uint8ToUtf8(uintArray) {
return decodeURIComponent(escape(String.fromCharCode.apply(null, uintArray)));
};
@ -25269,6 +25409,16 @@
var VTT_LINE_TERMINATORS = new Uint8Array('\n\n'.split('').map(function (char) {
return char.charCodeAt(0);
}));
var NoVttJsError = /*#__PURE__*/function (_Error) {
inheritsLoose(NoVttJsError, _Error);
function NoVttJsError() {
return _Error.call(this, 'Trying to parse received VTT cues, but there is no WebVTT. Make sure vtt.js is loaded.') || this;
}
return NoVttJsError;
}( /*#__PURE__*/wrapNativeSuper(Error));
/**
* An object that manages segment loading and appending.
*
@ -25277,6 +25427,7 @@
* @extends videojs.EventTarget
*/
var VTTSegmentLoader = /*#__PURE__*/function (_SegmentLoader) {
inheritsLoose(VTTSegmentLoader, _SegmentLoader);
@ -25293,7 +25444,8 @@
_this.mediaSource_ = null;
_this.subtitlesTrack_ = null;
_this.loaderType_ = 'subtitle';
_this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks; // The VTT segment will have its own time mappings. Saving VTT segment timing info in
_this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks;
_this.loadVttJs = settings.loadVttJs; // The VTT segment will have its own time mappings. Saving VTT segment timing info in
// the sync controller leads to improper behavior.
_this.shouldSaveSegmentTimingInfo_ = false;
@ -25568,30 +25720,19 @@
segment.map.bytes = simpleSegment.map.bytes;
}
segmentInfo.bytes = simpleSegment.bytes; // Make sure that vttjs has loaded, otherwise, wait till it finished loading
segmentInfo.bytes = simpleSegment.bytes; // Make sure that vttjs has loaded, otherwise, load it and wait till it finished loading
if (typeof window.WebVTT !== 'function' && this.subtitlesTrack_ && this.subtitlesTrack_.tech_) {
var loadHandler;
if (typeof window.WebVTT !== 'function' && typeof this.loadVttJs === 'function') {
this.state = 'WAITING_ON_VTTJS'; // should be fine to call multiple times
// script will be loaded once but multiple listeners will be added to the queue, which is expected.
var errorHandler = function errorHandler() {
_this3.subtitlesTrack_.tech_.off('vttjsloaded', loadHandler);
_this3.stopForError({
this.loadVttJs().then(function () {
return _this3.segmentRequestFinished_(error, simpleSegment, result);
}, function () {
return _this3.stopForError({
message: 'Error loading vtt.js'
});
return;
};
loadHandler = function loadHandler() {
_this3.subtitlesTrack_.tech_.off('vttjserror', errorHandler);
_this3.segmentRequestFinished_(error, simpleSegment, result);
};
this.state = 'WAITING_ON_VTTJS';
this.subtitlesTrack_.tech_.one('vttjsloaded', loadHandler);
this.subtitlesTrack_.tech_.one('vttjserror', errorHandler);
});
return;
}
@ -25651,6 +25792,8 @@
/**
* Uses the WebVTT parser to parse the segment response
*
* @throws NoVttJsError
*
* @param {Object} segmentInfo
* a segment info object that describes the current segment
* @private
@ -25661,6 +25804,11 @@
var decoder;
var decodeBytesToString = false;
if (typeof window.WebVTT !== 'function') {
// caller is responsible for exception handling.
throw new NoVttJsError();
}
if (typeof window.TextDecoder === 'function') {
decoder = new window.TextDecoder('utf8');
} else {
@ -26497,7 +26645,7 @@
return TimelineChangeController;
}(videojs__default["default"].EventTarget);
/* rollup-plugin-worker-factory start for worker!/Users/abarstow/videojs/http-streaming/src/decrypter-worker.js */
/* rollup-plugin-worker-factory start for worker!/Users/ddashkevich/projects/vhs-release/src/decrypter-worker.js */
var workerCode = transform(getWorkerString(function () {
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@ -27214,7 +27362,7 @@
};
}));
var Decrypter = factory(workerCode);
/* rollup-plugin-worker-factory end for worker!/Users/abarstow/videojs/http-streaming/src/decrypter-worker.js */
/* rollup-plugin-worker-factory end for worker!/Users/ddashkevich/projects/vhs-release/src/decrypter-worker.js */
/**
* Convert the properties of an HLS track into an audioTrackKind.
@ -28343,7 +28491,25 @@
}), options);
_this.subtitleSegmentLoader_ = new VTTSegmentLoader(videojs__default["default"].mergeOptions(segmentLoaderSettings, {
loaderType: 'vtt',
featuresNativeTextTracks: _this.tech_.featuresNativeTextTracks
featuresNativeTextTracks: _this.tech_.featuresNativeTextTracks,
loadVttJs: function loadVttJs() {
return new Promise(function (resolve, reject) {
function onLoad() {
tech.off('vttjserror', onError);
resolve();
}
function onError() {
tech.off('vttjsloaded', onLoad);
reject();
}
tech.one('vttjsloaded', onLoad);
tech.one('vttjserror', onError); // safe to call multiple times, script will be loaded only once:
tech.addWebVttScript_();
});
}
}), options);
_this.setupSegmentLoaderListeners_();
@ -28433,16 +28599,20 @@
/**
* Run selectPlaylist and switch to the new playlist if we should
*
* @param {string} [reason=abr] a reason for why the ABR check is made
* @private
*
*/
;
_proto.checkABR_ = function checkABR_() {
_proto.checkABR_ = function checkABR_(reason) {
if (reason === void 0) {
reason = 'abr';
}
var nextPlaylist = this.selectPlaylist();
if (nextPlaylist && this.shouldSwitchToMedia_(nextPlaylist)) {
this.switchMedia_(nextPlaylist, 'abr');
this.switchMedia_(nextPlaylist, reason);
}
};
@ -28694,7 +28864,9 @@
_this3.requestOptions_.timeout = 0;
} else {
_this3.requestOptions_.timeout = requestTimeout;
} // TODO: Create a new event on the PlaylistLoader that signals
}
_this3.masterPlaylistLoader_.load(); // TODO: Create a new event on the PlaylistLoader that signals
// that the segments have changed in some way and use that to
// update the SegmentLoader instead of doing it twice here and
// on `loadedplaylist`
@ -28898,16 +29070,25 @@
_proto.setupSegmentLoaderListeners_ = function setupSegmentLoaderListeners_() {
var _this4 = this;
this.mainSegmentLoader_.on('bandwidthupdate', function () {
// Whether or not buffer based ABR or another ABR is used, on a bandwidth change it's
// useful to check to see if a rendition switch should be made.
_this4.checkABR_('bandwidthupdate');
_this4.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('timeout', function () {
if (_this4.experimentalBufferBasedABR) {
// If a rendition change is needed, then it would've be done on `bandwidthupdate`.
// Here the only consideration is that for buffer based ABR there's no guarantee
// of an immediate switch (since the bandwidth is averaged with a timeout
// bandwidth value of 1), so force a load on the segment loader to keep it going.
_this4.mainSegmentLoader_.load();
}
}); // `progress` events are not reliable enough of a bandwidth measure to trigger buffer
// based ABR.
if (!this.experimentalBufferBasedABR) {
this.mainSegmentLoader_.on('bandwidthupdate', function () {
var nextPlaylist = _this4.selectPlaylist();
if (_this4.shouldSwitchToMedia_(nextPlaylist)) {
_this4.switchMedia_(nextPlaylist, 'bandwidthupdate');
}
_this4.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('progress', function () {
_this4.trigger('progress');
});
@ -30204,6 +30385,7 @@
this.width = resolution && resolution.width;
this.height = resolution && resolution.height;
this.bandwidth = playlist.attributes.BANDWIDTH;
this.frameRate = playlist.attributes['FRAME-RATE'];
}
this.codecs = codecsForPlaylist(mpc.master(), playlist);
@ -31043,13 +31225,13 @@
initPlugin(this, options);
};
var version$4 = "2.14.3";
var version$4 = "2.16.0";
var version$3 = "6.0.1";
var version$2 = "0.21.1";
var version$2 = "0.22.1";
var version$1 = "4.7.1";
var version$1 = "4.8.0";
var version = "3.1.3";
@ -32311,23 +32493,33 @@
return tech.vhs;
},
canPlayType: function canPlayType(type, options) {
var simpleType = simpleTypeFromSourceType(type);
if (!simpleType) {
return '';
}
var overrideNative = VhsSourceHandler.getOverrideNative(options);
var supportsTypeNatively = Vhs.supportsTypeNatively(simpleType);
var canUseMsePlayback = !supportsTypeNatively || overrideNative;
return canUseMsePlayback ? 'maybe' : '';
},
getOverrideNative: function getOverrideNative(options) {
if (options === void 0) {
options = {};
}
var _videojs$mergeOptions = videojs__default["default"].mergeOptions(videojs__default["default"].options, options),
_videojs$mergeOptions2 = _videojs$mergeOptions.vhs;
_videojs$mergeOptions2 = _videojs$mergeOptions2 === void 0 ? {} : _videojs$mergeOptions2;
var _videojs$mergeOptions3 = _videojs$mergeOptions2.overrideNative,
overrideNative = _videojs$mergeOptions3 === void 0 ? !videojs__default["default"].browser.IS_ANY_SAFARI : _videojs$mergeOptions3,
_videojs$mergeOptions4 = _videojs$mergeOptions.hls;
_videojs$mergeOptions4 = _videojs$mergeOptions4 === void 0 ? {} : _videojs$mergeOptions4;
var _videojs$mergeOptions5 = _videojs$mergeOptions4.overrideNative,
legacyOverrideNative = _videojs$mergeOptions5 === void 0 ? false : _videojs$mergeOptions5;
var supportedType = simpleTypeFromSourceType(type);
var canUseMsePlayback = supportedType && (!Vhs.supportsTypeNatively(supportedType) || legacyOverrideNative || overrideNative);
return canUseMsePlayback ? 'maybe' : '';
var _options = options,
_options$vhs = _options.vhs,
vhs = _options$vhs === void 0 ? {} : _options$vhs,
_options$hls = _options.hls,
hls = _options$hls === void 0 ? {} : _options$hls;
var defaultOverrideNative = !(videojs__default["default"].browser.IS_ANY_SAFARI || videojs__default["default"].browser.IS_IOS);
var _vhs$overrideNative = vhs.overrideNative,
overrideNative = _vhs$overrideNative === void 0 ? defaultOverrideNative : _vhs$overrideNative;
var _hls$overrideNative = hls.overrideNative,
legacyOverrideNative = _hls$overrideNative === void 0 ? false : _hls$overrideNative;
return legacyOverrideNative || overrideNative;
}
};
/**

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{
"name": "@videojs/http-streaming",
"version": "2.14.3",
"version": "2.16.0",
"description": "Play back HLS and DASH with Video.js, even where it's not natively supported",
"main": "dist/videojs-http-streaming.cjs.js",
"module": "dist/videojs-http-streaming.es.js",
@ -59,8 +59,8 @@
"@videojs/vhs-utils": "3.0.5",
"aes-decrypter": "3.1.3",
"global": "^4.4.0",
"m3u8-parser": "4.7.1",
"mpd-parser": "0.21.1",
"m3u8-parser": "4.8.0",
"mpd-parser": "^0.22.1",
"mux.js": "6.0.1",
"video.js": "^6 || ^7"
},

View file

@ -1,654 +0,0 @@
/*! @name @videojs/http-streaming @version 2.5.0 @license Apache-2.0 */
var decrypterWorker = (function () {
'use strict';
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var createClass = _createClass;
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
var inheritsLoose = _inheritsLoose;
/**
* @file stream.js
*/
/**
* A lightweight readable stream implemention that handles event dispatching.
*
* @class Stream
*/
var Stream = /*#__PURE__*/function () {
function Stream() {
this.listeners = {};
}
/**
* Add a listener for a specified event type.
*
* @param {string} type the event name
* @param {Function} listener the callback to be invoked when an event of
* the specified type occurs
*/
var _proto = Stream.prototype;
_proto.on = function on(type, listener) {
if (!this.listeners[type]) {
this.listeners[type] = [];
}
this.listeners[type].push(listener);
}
/**
* Remove a listener for a specified event type.
*
* @param {string} type the event name
* @param {Function} listener a function previously registered for this
* type of event through `on`
* @return {boolean} if we could turn it off or not
*/
;
_proto.off = function off(type, listener) {
if (!this.listeners[type]) {
return false;
}
var index = this.listeners[type].indexOf(listener); // TODO: which is better?
// In Video.js we slice listener functions
// on trigger so that it does not mess up the order
// while we loop through.
//
// Here we slice on off so that the loop in trigger
// can continue using it's old reference to loop without
// messing up the order.
this.listeners[type] = this.listeners[type].slice(0);
this.listeners[type].splice(index, 1);
return index > -1;
}
/**
* Trigger an event of the specified type on this stream. Any additional
* arguments to this function are passed as parameters to event listeners.
*
* @param {string} type the event name
*/
;
_proto.trigger = function trigger(type) {
var callbacks = this.listeners[type];
if (!callbacks) {
return;
} // Slicing the arguments on every invocation of this method
// can add a significant amount of overhead. Avoid the
// intermediate object creation for the common case of a
// single callback argument
if (arguments.length === 2) {
var length = callbacks.length;
for (var i = 0; i < length; ++i) {
callbacks[i].call(this, arguments[1]);
}
} else {
var args = Array.prototype.slice.call(arguments, 1);
var _length = callbacks.length;
for (var _i = 0; _i < _length; ++_i) {
callbacks[_i].apply(this, args);
}
}
}
/**
* Destroys the stream and cleans up.
*/
;
_proto.dispose = function dispose() {
this.listeners = {};
}
/**
* Forwards all `data` events on this stream to the destination stream. The
* destination stream should provide a method `push` to receive the data
* events as they arrive.
*
* @param {Stream} destination the stream that will receive all `data` events
* @see http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options
*/
;
_proto.pipe = function pipe(destination) {
this.on('data', function (data) {
destination.push(data);
});
};
return Stream;
}();
/*! @name pkcs7 @version 1.0.4 @license Apache-2.0 */
/**
* Returns the subarray of a Uint8Array without PKCS#7 padding.
*
* @param padded {Uint8Array} unencrypted bytes that have been padded
* @return {Uint8Array} the unpadded bytes
* @see http://tools.ietf.org/html/rfc5652
*/
function unpad(padded) {
return padded.subarray(0, padded.byteLength - padded[padded.byteLength - 1]);
}
/*! @name aes-decrypter @version 3.1.2 @license Apache-2.0 */
/**
* @file aes.js
*
* This file contains an adaptation of the AES decryption algorithm
* from the Standford Javascript Cryptography Library. That work is
* covered by the following copyright and permissions notice:
*
* Copyright 2009-2010 Emily Stark, Mike Hamburg, Dan Boneh.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* official policies, either expressed or implied, of the authors.
*/
/**
* Expand the S-box tables.
*
* @private
*/
var precompute = function precompute() {
var tables = [[[], [], [], [], []], [[], [], [], [], []]];
var encTable = tables[0];
var decTable = tables[1];
var sbox = encTable[4];
var sboxInv = decTable[4];
var i;
var x;
var xInv;
var d = [];
var th = [];
var x2;
var x4;
var x8;
var s;
var tEnc;
var tDec; // Compute double and third tables
for (i = 0; i < 256; i++) {
th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
}
for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
// Compute sbox
s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
s = s >> 8 ^ s & 255 ^ 99;
sbox[x] = s;
sboxInv[s] = x; // Compute MixColumns
x8 = d[x4 = d[x2 = d[x]]];
tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
tEnc = d[s] * 0x101 ^ s * 0x1010100;
for (i = 0; i < 4; i++) {
encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
}
} // Compactify. Considerable speedup on Firefox.
for (i = 0; i < 5; i++) {
encTable[i] = encTable[i].slice(0);
decTable[i] = decTable[i].slice(0);
}
return tables;
};
var aesTables = null;
/**
* Schedule out an AES key for both encryption and decryption. This
* is a low-level class. Use a cipher mode to do bulk encryption.
*
* @class AES
* @param key {Array} The key as an array of 4, 6 or 8 words.
*/
var AES = /*#__PURE__*/function () {
function AES(key) {
/**
* The expanded S-box and inverse S-box tables. These will be computed
* on the client so that we don't have to send them down the wire.
*
* There are two tables, _tables[0] is for encryption and
* _tables[1] is for decryption.
*
* The first 4 sub-tables are the expanded S-box with MixColumns. The
* last (_tables[01][4]) is the S-box itself.
*
* @private
*/
// if we have yet to precompute the S-box tables
// do so now
if (!aesTables) {
aesTables = precompute();
} // then make a copy of that object for use
this._tables = [[aesTables[0][0].slice(), aesTables[0][1].slice(), aesTables[0][2].slice(), aesTables[0][3].slice(), aesTables[0][4].slice()], [aesTables[1][0].slice(), aesTables[1][1].slice(), aesTables[1][2].slice(), aesTables[1][3].slice(), aesTables[1][4].slice()]];
var i;
var j;
var tmp;
var sbox = this._tables[0][4];
var decTable = this._tables[1];
var keyLen = key.length;
var rcon = 1;
if (keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
throw new Error('Invalid aes key size');
}
var encKey = key.slice(0);
var decKey = [];
this._key = [encKey, decKey]; // schedule encryption keys
for (i = keyLen; i < 4 * keyLen + 28; i++) {
tmp = encKey[i - 1]; // apply sbox
if (i % keyLen === 0 || keyLen === 8 && i % keyLen === 4) {
tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255]; // shift rows and add rcon
if (i % keyLen === 0) {
tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
rcon = rcon << 1 ^ (rcon >> 7) * 283;
}
}
encKey[i] = encKey[i - keyLen] ^ tmp;
} // schedule decryption keys
for (j = 0; i; j++, i--) {
tmp = encKey[j & 3 ? i : i - 4];
if (i <= 4 || j < 4) {
decKey[j] = tmp;
} else {
decKey[j] = decTable[0][sbox[tmp >>> 24]] ^ decTable[1][sbox[tmp >> 16 & 255]] ^ decTable[2][sbox[tmp >> 8 & 255]] ^ decTable[3][sbox[tmp & 255]];
}
}
}
/**
* Decrypt 16 bytes, specified as four 32-bit words.
*
* @param {number} encrypted0 the first word to decrypt
* @param {number} encrypted1 the second word to decrypt
* @param {number} encrypted2 the third word to decrypt
* @param {number} encrypted3 the fourth word to decrypt
* @param {Int32Array} out the array to write the decrypted words
* into
* @param {number} offset the offset into the output array to start
* writing results
* @return {Array} The plaintext.
*/
var _proto = AES.prototype;
_proto.decrypt = function decrypt(encrypted0, encrypted1, encrypted2, encrypted3, out, offset) {
var key = this._key[1]; // state variables a,b,c,d are loaded with pre-whitened data
var a = encrypted0 ^ key[0];
var b = encrypted3 ^ key[1];
var c = encrypted2 ^ key[2];
var d = encrypted1 ^ key[3];
var a2;
var b2;
var c2; // key.length === 2 ?
var nInnerRounds = key.length / 4 - 2;
var i;
var kIndex = 4;
var table = this._tables[1]; // load up the tables
var table0 = table[0];
var table1 = table[1];
var table2 = table[2];
var table3 = table[3];
var sbox = table[4]; // Inner rounds. Cribbed from OpenSSL.
for (i = 0; i < nInnerRounds; i++) {
a2 = table0[a >>> 24] ^ table1[b >> 16 & 255] ^ table2[c >> 8 & 255] ^ table3[d & 255] ^ key[kIndex];
b2 = table0[b >>> 24] ^ table1[c >> 16 & 255] ^ table2[d >> 8 & 255] ^ table3[a & 255] ^ key[kIndex + 1];
c2 = table0[c >>> 24] ^ table1[d >> 16 & 255] ^ table2[a >> 8 & 255] ^ table3[b & 255] ^ key[kIndex + 2];
d = table0[d >>> 24] ^ table1[a >> 16 & 255] ^ table2[b >> 8 & 255] ^ table3[c & 255] ^ key[kIndex + 3];
kIndex += 4;
a = a2;
b = b2;
c = c2;
} // Last round.
for (i = 0; i < 4; i++) {
out[(3 & -i) + offset] = sbox[a >>> 24] << 24 ^ sbox[b >> 16 & 255] << 16 ^ sbox[c >> 8 & 255] << 8 ^ sbox[d & 255] ^ key[kIndex++];
a2 = a;
a = b;
b = c;
c = d;
d = a2;
}
};
return AES;
}();
/**
* A wrapper around the Stream class to use setTimeout
* and run stream "jobs" Asynchronously
*
* @class AsyncStream
* @extends Stream
*/
var AsyncStream = /*#__PURE__*/function (_Stream) {
inheritsLoose(AsyncStream, _Stream);
function AsyncStream() {
var _this;
_this = _Stream.call(this, Stream) || this;
_this.jobs = [];
_this.delay = 1;
_this.timeout_ = null;
return _this;
}
/**
* process an async job
*
* @private
*/
var _proto = AsyncStream.prototype;
_proto.processJob_ = function processJob_() {
this.jobs.shift()();
if (this.jobs.length) {
this.timeout_ = setTimeout(this.processJob_.bind(this), this.delay);
} else {
this.timeout_ = null;
}
}
/**
* push a job into the stream
*
* @param {Function} job the job to push into the stream
*/
;
_proto.push = function push(job) {
this.jobs.push(job);
if (!this.timeout_) {
this.timeout_ = setTimeout(this.processJob_.bind(this), this.delay);
}
};
return AsyncStream;
}(Stream);
/**
* Convert network-order (big-endian) bytes into their little-endian
* representation.
*/
var ntoh = function ntoh(word) {
return word << 24 | (word & 0xff00) << 8 | (word & 0xff0000) >> 8 | word >>> 24;
};
/**
* Decrypt bytes using AES-128 with CBC and PKCS#7 padding.
*
* @param {Uint8Array} encrypted the encrypted bytes
* @param {Uint32Array} key the bytes of the decryption key
* @param {Uint32Array} initVector the initialization vector (IV) to
* use for the first round of CBC.
* @return {Uint8Array} the decrypted bytes
*
* @see http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
* @see http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29
* @see https://tools.ietf.org/html/rfc2315
*/
var decrypt = function decrypt(encrypted, key, initVector) {
// word-level access to the encrypted bytes
var encrypted32 = new Int32Array(encrypted.buffer, encrypted.byteOffset, encrypted.byteLength >> 2);
var decipher = new AES(Array.prototype.slice.call(key)); // byte and word-level access for the decrypted output
var decrypted = new Uint8Array(encrypted.byteLength);
var decrypted32 = new Int32Array(decrypted.buffer); // temporary variables for working with the IV, encrypted, and
// decrypted data
var init0;
var init1;
var init2;
var init3;
var encrypted0;
var encrypted1;
var encrypted2;
var encrypted3; // iteration variable
var wordIx; // pull out the words of the IV to ensure we don't modify the
// passed-in reference and easier access
init0 = initVector[0];
init1 = initVector[1];
init2 = initVector[2];
init3 = initVector[3]; // decrypt four word sequences, applying cipher-block chaining (CBC)
// to each decrypted block
for (wordIx = 0; wordIx < encrypted32.length; wordIx += 4) {
// convert big-endian (network order) words into little-endian
// (javascript order)
encrypted0 = ntoh(encrypted32[wordIx]);
encrypted1 = ntoh(encrypted32[wordIx + 1]);
encrypted2 = ntoh(encrypted32[wordIx + 2]);
encrypted3 = ntoh(encrypted32[wordIx + 3]); // decrypt the block
decipher.decrypt(encrypted0, encrypted1, encrypted2, encrypted3, decrypted32, wordIx); // XOR with the IV, and restore network byte-order to obtain the
// plaintext
decrypted32[wordIx] = ntoh(decrypted32[wordIx] ^ init0);
decrypted32[wordIx + 1] = ntoh(decrypted32[wordIx + 1] ^ init1);
decrypted32[wordIx + 2] = ntoh(decrypted32[wordIx + 2] ^ init2);
decrypted32[wordIx + 3] = ntoh(decrypted32[wordIx + 3] ^ init3); // setup the IV for the next round
init0 = encrypted0;
init1 = encrypted1;
init2 = encrypted2;
init3 = encrypted3;
}
return decrypted;
};
/**
* The `Decrypter` class that manages decryption of AES
* data through `AsyncStream` objects and the `decrypt`
* function
*
* @param {Uint8Array} encrypted the encrypted bytes
* @param {Uint32Array} key the bytes of the decryption key
* @param {Uint32Array} initVector the initialization vector (IV) to
* @param {Function} done the function to run when done
* @class Decrypter
*/
var Decrypter = /*#__PURE__*/function () {
function Decrypter(encrypted, key, initVector, done) {
var step = Decrypter.STEP;
var encrypted32 = new Int32Array(encrypted.buffer);
var decrypted = new Uint8Array(encrypted.byteLength);
var i = 0;
this.asyncStream_ = new AsyncStream(); // split up the encryption job and do the individual chunks asynchronously
this.asyncStream_.push(this.decryptChunk_(encrypted32.subarray(i, i + step), key, initVector, decrypted));
for (i = step; i < encrypted32.length; i += step) {
initVector = new Uint32Array([ntoh(encrypted32[i - 4]), ntoh(encrypted32[i - 3]), ntoh(encrypted32[i - 2]), ntoh(encrypted32[i - 1])]);
this.asyncStream_.push(this.decryptChunk_(encrypted32.subarray(i, i + step), key, initVector, decrypted));
} // invoke the done() callback when everything is finished
this.asyncStream_.push(function () {
// remove pkcs#7 padding from the decrypted bytes
done(null, unpad(decrypted));
});
}
/**
* a getter for step the maximum number of bytes to process at one time
*
* @return {number} the value of step 32000
*/
var _proto = Decrypter.prototype;
/**
* @private
*/
_proto.decryptChunk_ = function decryptChunk_(encrypted, key, initVector, decrypted) {
return function () {
var bytes = decrypt(encrypted, key, initVector);
decrypted.set(bytes, encrypted.byteOffset);
};
};
createClass(Decrypter, null, [{
key: "STEP",
get: function get() {
// 4 * 8000;
return 32000;
}
}]);
return Decrypter;
}();
/**
* @file bin-utils.js
*/
/**
* Creates an object for sending to a web worker modifying properties that are TypedArrays
* into a new object with seperated properties for the buffer, byteOffset, and byteLength.
*
* @param {Object} message
* Object of properties and values to send to the web worker
* @return {Object}
* Modified message with TypedArray values expanded
* @function createTransferableMessage
*/
var createTransferableMessage = function createTransferableMessage(message) {
var transferable = {};
Object.keys(message).forEach(function (key) {
var value = message[key];
if (ArrayBuffer.isView(value)) {
transferable[key] = {
bytes: value.buffer,
byteOffset: value.byteOffset,
byteLength: value.byteLength
};
} else {
transferable[key] = value;
}
});
return transferable;
};
/* global self */
/**
* Our web worker interface so that things can talk to aes-decrypter
* that will be running in a web worker. the scope is passed to this by
* webworkify.
*
* @param {Object} self
* the scope for the web worker
*/
var DecrypterWorker = function DecrypterWorker(self) {
self.onmessage = function (event) {
var data = event.data;
var encrypted = new Uint8Array(data.encrypted.bytes, data.encrypted.byteOffset, data.encrypted.byteLength);
var key = new Uint32Array(data.key.bytes, data.key.byteOffset, data.key.byteLength / 4);
var iv = new Uint32Array(data.iv.bytes, data.iv.byteOffset, data.iv.byteLength / 4);
/* eslint-disable no-new, handle-callback-err */
new Decrypter(encrypted, key, iv, function (err, bytes) {
self.postMessage(createTransferableMessage({
source: data.source,
decrypted: bytes
}), [bytes.buffer]);
});
/* eslint-enable */
};
};
var decrypterWorker = new DecrypterWorker(self);
return decrypterWorker;
}());

View file

@ -284,7 +284,24 @@ export class MasterPlaylistController extends videojs.EventTarget {
this.subtitleSegmentLoader_ =
new VTTSegmentLoader(videojs.mergeOptions(segmentLoaderSettings, {
loaderType: 'vtt',
featuresNativeTextTracks: this.tech_.featuresNativeTextTracks
featuresNativeTextTracks: this.tech_.featuresNativeTextTracks,
loadVttJs: () => new Promise((resolve, reject) => {
function onLoad() {
tech.off('vttjserror', onError);
resolve();
}
function onError() {
tech.off('vttjsloaded', onLoad);
reject();
}
tech.one('vttjsloaded', onLoad);
tech.one('vttjserror', onError);
// safe to call multiple times, script will be loaded only once:
tech.addWebVttScript_();
})
}), options);
this.setupSegmentLoaderListeners_();
@ -365,14 +382,14 @@ export class MasterPlaylistController extends videojs.EventTarget {
/**
* Run selectPlaylist and switch to the new playlist if we should
*
* @param {string} [reason=abr] a reason for why the ABR check is made
* @private
*
*/
checkABR_() {
checkABR_(reason = 'abr') {
const nextPlaylist = this.selectPlaylist();
if (nextPlaylist && this.shouldSwitchToMedia_(nextPlaylist)) {
this.switchMedia_(nextPlaylist, 'abr');
this.switchMedia_(nextPlaylist, reason);
}
}
@ -614,6 +631,8 @@ export class MasterPlaylistController extends videojs.EventTarget {
this.requestOptions_.timeout = requestTimeout;
}
this.masterPlaylistLoader_.load();
// TODO: Create a new event on the PlaylistLoader that signals
// that the segments have changed in some way and use that to
// update the SegmentLoader instead of doing it twice here and
@ -770,17 +789,26 @@ export class MasterPlaylistController extends videojs.EventTarget {
* @private
*/
setupSegmentLoaderListeners_() {
this.mainSegmentLoader_.on('bandwidthupdate', () => {
// Whether or not buffer based ABR or another ABR is used, on a bandwidth change it's
// useful to check to see if a rendition switch should be made.
this.checkABR_('bandwidthupdate');
this.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('timeout', () => {
if (this.experimentalBufferBasedABR) {
// If a rendition change is needed, then it would've be done on `bandwidthupdate`.
// Here the only consideration is that for buffer based ABR there's no guarantee
// of an immediate switch (since the bandwidth is averaged with a timeout
// bandwidth value of 1), so force a load on the segment loader to keep it going.
this.mainSegmentLoader_.load();
}
});
// `progress` events are not reliable enough of a bandwidth measure to trigger buffer
// based ABR.
if (!this.experimentalBufferBasedABR) {
this.mainSegmentLoader_.on('bandwidthupdate', () => {
const nextPlaylist = this.selectPlaylist();
if (this.shouldSwitchToMedia_(nextPlaylist)) {
this.switchMedia_(nextPlaylist, 'bandwidthupdate');
}
this.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('progress', () => {
this.trigger('progress');
});

View file

@ -65,6 +65,7 @@ class Representation {
this.height = resolution && resolution.height;
this.bandwidth = playlist.attributes.BANDWIDTH;
this.frameRate = playlist.attributes['FRAME-RATE'];
}
this.codecs = codecsForPlaylist(mpc.master(), playlist);

View file

@ -2634,6 +2634,7 @@ export default class SegmentLoader extends videojs.EventTarget {
this.bandwidth = 1;
this.roundTrip = NaN;
this.trigger('bandwidthupdate');
this.trigger('timeout');
}
/**

File diff suppressed because it is too large Load diff

View file

@ -1286,17 +1286,26 @@ const VhsSourceHandler = {
tech.vhs.src(source.src, source.type);
return tech.vhs;
},
canPlayType(type, options = {}) {
const {
vhs: { overrideNative = !videojs.browser.IS_ANY_SAFARI } = {},
hls: { overrideNative: legacyOverrideNative = false } = {}
} = videojs.mergeOptions(videojs.options, options);
canPlayType(type, options) {
const simpleType = simpleTypeFromSourceType(type);
const supportedType = simpleTypeFromSourceType(type);
const canUseMsePlayback = supportedType &&
(!Vhs.supportsTypeNatively(supportedType) || legacyOverrideNative || overrideNative);
if (!simpleType) {
return '';
}
const overrideNative = VhsSourceHandler.getOverrideNative(options);
const supportsTypeNatively = Vhs.supportsTypeNatively(simpleType);
const canUseMsePlayback = !supportsTypeNatively || overrideNative;
return canUseMsePlayback ? 'maybe' : '';
},
getOverrideNative(options = {}) {
const { vhs = {}, hls = {} } = options;
const defaultOverrideNative = !(videojs.browser.IS_ANY_SAFARI || videojs.browser.IS_IOS);
const { overrideNative = defaultOverrideNative } = vhs;
const { overrideNative: legacyOverrideNative = false } = hls;
return legacyOverrideNative || overrideNative;
}
};

View file

@ -13,6 +13,12 @@ import { ONE_SECOND_IN_TS } from 'mux.js/lib/utils/clock';
const VTT_LINE_TERMINATORS =
new Uint8Array('\n\n'.split('').map(char => char.charCodeAt(0)));
class NoVttJsError extends Error {
constructor() {
super('Trying to parse received VTT cues, but there is no WebVTT. Make sure vtt.js is loaded.');
}
}
/**
* An object that manages segment loading and appending.
*
@ -34,6 +40,8 @@ export default class VTTSegmentLoader extends SegmentLoader {
this.featuresNativeTextTracks_ = settings.featuresNativeTextTracks;
this.loadVttJs = settings.loadVttJs;
// The VTT segment will have its own time mappings. Saving VTT segment timing info in
// the sync controller leads to improper behavior.
this.shouldSaveSegmentTimingInfo_ = false;
@ -297,29 +305,16 @@ export default class VTTSegmentLoader extends SegmentLoader {
}
segmentInfo.bytes = simpleSegment.bytes;
// Make sure that vttjs has loaded, otherwise, wait till it finished loading
if (typeof window.WebVTT !== 'function' &&
this.subtitlesTrack_ &&
this.subtitlesTrack_.tech_) {
let loadHandler;
const errorHandler = () => {
this.subtitlesTrack_.tech_.off('vttjsloaded', loadHandler);
this.stopForError({
message: 'Error loading vtt.js'
});
return;
};
loadHandler = () => {
this.subtitlesTrack_.tech_.off('vttjserror', errorHandler);
this.segmentRequestFinished_(error, simpleSegment, result);
};
// Make sure that vttjs has loaded, otherwise, load it and wait till it finished loading
if (typeof window.WebVTT !== 'function' && typeof this.loadVttJs === 'function') {
this.state = 'WAITING_ON_VTTJS';
this.subtitlesTrack_.tech_.one('vttjsloaded', loadHandler);
this.subtitlesTrack_.tech_.one('vttjserror', errorHandler);
// should be fine to call multiple times
// script will be loaded once but multiple listeners will be added to the queue, which is expected.
this.loadVttJs()
.then(
() => this.segmentRequestFinished_(error, simpleSegment, result),
() => this.stopForError({ message: 'Error loading vtt.js' })
);
return;
}
@ -391,6 +386,8 @@ export default class VTTSegmentLoader extends SegmentLoader {
/**
* Uses the WebVTT parser to parse the segment response
*
* @throws NoVttJsError
*
* @param {Object} segmentInfo
* a segment info object that describes the current segment
* @private
@ -399,6 +396,11 @@ export default class VTTSegmentLoader extends SegmentLoader {
let decoder;
let decodeBytesToString = false;
if (typeof window.WebVTT !== 'function') {
// caller is responsible for exception handling.
throw new NoVttJsError();
}
if (typeof window.TextDecoder === 'function') {
decoder = new window.TextDecoder('utf8');
} else {