UNPKG

videojs-contrib-media-sources

Version:

A Media Source Extensions plugin for video.js

1,609 lines (1,293 loc) 1.2 MB
/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { /* eslint-disable no-var */ /* eslint-env qunit */ var mediaSources = __webpack_require__(1); var q = window.QUnit; q.module('Webpack Require'); q.test('mediaSources should be requirable and bundled via webpack', function(assert) { assert.ok(mediaSources, 'videojs-contrib-media-sources is required properly'); }); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { /** * @file videojs-contrib-media-sources.js */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _globalWindow = __webpack_require__(2); var _globalWindow2 = _interopRequireDefault(_globalWindow); var _flashMediaSource = __webpack_require__(3); var _flashMediaSource2 = _interopRequireDefault(_flashMediaSource); var _htmlMediaSource = __webpack_require__(137); var _htmlMediaSource2 = _interopRequireDefault(_htmlMediaSource); var _videoJs = __webpack_require__(6); var _videoJs2 = _interopRequireDefault(_videoJs); var urlCount = 0; // ------------ // Media Source // ------------ var defaults = { // how to determine the MediaSource implementation to use. There // are three available modes: // - auto: use native MediaSources where available and Flash // everywhere else // - html5: always use native MediaSources // - flash: always use the Flash MediaSource polyfill mode: 'auto' }; // store references to the media sources so they can be connected // to a video element (a swf object) // TODO: can we store this somewhere local to this module? _videoJs2['default'].mediaSources = {}; /** * Provide a method for a swf object to notify JS that a * media source is now open. * * @param {String} msObjectURL string referencing the MSE Object URL * @param {String} swfId the swf id */ var open = function open(msObjectURL, swfId) { var mediaSource = _videoJs2['default'].mediaSources[msObjectURL]; if (mediaSource) { mediaSource.trigger({ type: 'sourceopen', swfId: swfId }); } else { throw new Error('Media Source not found (Video.js)'); } }; /** * Check to see if the native MediaSource object exists and supports * an MP4 container with both H.264 video and AAC-LC audio. * * @return {Boolean} if native media sources are supported */ var supportsNativeMediaSources = function supportsNativeMediaSources() { return !!_globalWindow2['default'].MediaSource && !!_globalWindow2['default'].MediaSource.isTypeSupported && _globalWindow2['default'].MediaSource.isTypeSupported('video/mp4;codecs="avc1.4d400d,mp4a.40.2"'); }; /** * An emulation of the MediaSource API so that we can support * native and non-native functionality such as flash and * video/mp2t videos. returns an instance of HtmlMediaSource or * FlashMediaSource depending on what is supported and what options * are passed in. * * @link https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/MediaSource * @param {Object} options options to use during setup. */ var MediaSource = function MediaSource(options) { var settings = _videoJs2['default'].mergeOptions(defaults, options); this.MediaSource = { open: open, supportsNativeMediaSources: supportsNativeMediaSources }; // determine whether HTML MediaSources should be used if (settings.mode === 'html5' || settings.mode === 'auto' && supportsNativeMediaSources()) { return new _htmlMediaSource2['default'](); } else if (_videoJs2['default'].getTech('Flash')) { return new _flashMediaSource2['default'](); } throw new Error('Cannot use Flash or Html5 to create a MediaSource for this video'); }; exports.MediaSource = MediaSource; MediaSource.open = open; MediaSource.supportsNativeMediaSources = supportsNativeMediaSources; /** * A wrapper around the native URL for our MSE object * implementation, this object is exposed under videojs.URL * * @link https://developer.mozilla.org/en-US/docs/Web/API/URL/URL */ var URL = { /** * A wrapper around the native createObjectURL for our objects. * This function maps a native or emulated mediaSource to a blob * url so that it can be loaded into video.js * * @link https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL * @param {MediaSource} object the object to create a blob url to */ createObjectURL: function createObjectURL(object) { var objectUrlPrefix = 'blob:vjs-media-source/'; var url = undefined; // use the native MediaSource to generate an object URL if (object instanceof _htmlMediaSource2['default']) { url = _globalWindow2['default'].URL.createObjectURL(object.nativeMediaSource_); object.url_ = url; return url; } // if the object isn't an emulated MediaSource, delegate to the // native implementation if (!(object instanceof _flashMediaSource2['default'])) { url = _globalWindow2['default'].URL.createObjectURL(object); object.url_ = url; return url; } // build a URL that can be used to map back to the emulated // MediaSource url = objectUrlPrefix + urlCount; urlCount++; // setup the mapping back to object _videoJs2['default'].mediaSources[url] = object; return url; } }; exports.URL = URL; _videoJs2['default'].MediaSource = MediaSource; _videoJs2['default'].URL = URL; /***/ }), /* 2 */ /***/ (function(module, exports) { /* WEBPACK VAR INJECTION */(function(global) {var win; if (typeof window !== "undefined") { win = window; } else if (typeof global !== "undefined") { win = global; } else if (typeof self !== "undefined"){ win = self; } else { win = {}; } module.exports = win; /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { /** * @file flash-media-source.js */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _globalDocument = __webpack_require__(4); var _globalDocument2 = _interopRequireDefault(_globalDocument); var _videoJs = __webpack_require__(6); var _videoJs2 = _interopRequireDefault(_videoJs); var _flashSourceBuffer = __webpack_require__(114); var _flashSourceBuffer2 = _interopRequireDefault(_flashSourceBuffer); var _flashConstants = __webpack_require__(135); var _flashConstants2 = _interopRequireDefault(_flashConstants); var _codecUtils = __webpack_require__(136); /** * A flash implmentation of HTML MediaSources and a polyfill * for browsers that don't support native or HTML MediaSources.. * * @link https://developer.mozilla.org/en-US/docs/Web/API/MediaSource * @class FlashMediaSource * @extends videojs.EventTarget */ var FlashMediaSource = (function (_videojs$EventTarget) { _inherits(FlashMediaSource, _videojs$EventTarget); function FlashMediaSource() { var _this = this; _classCallCheck(this, FlashMediaSource); _get(Object.getPrototypeOf(FlashMediaSource.prototype), 'constructor', this).call(this); this.sourceBuffers = []; this.readyState = 'closed'; this.on(['sourceopen', 'webkitsourceopen'], function (event) { // find the swf where we will push media data _this.swfObj = _globalDocument2['default'].getElementById(event.swfId); _this.player_ = (0, _videoJs2['default'])(_this.swfObj.parentNode); _this.tech_ = _this.swfObj.tech; _this.readyState = 'open'; _this.tech_.on('seeking', function () { var i = _this.sourceBuffers.length; while (i--) { _this.sourceBuffers[i].abort(); } }); // trigger load events if (_this.swfObj) { _this.swfObj.vjs_load(); } }); } /** * Set or return the presentation duration. * * @param {Double} value the duration of the media in seconds * @param {Double} the current presentation duration * @link http://www.w3.org/TR/media-source/#widl-MediaSource-duration */ /** * We have this function so that the html and flash interfaces * are the same. * * @private */ _createClass(FlashMediaSource, [{ key: 'addSeekableRange_', value: function addSeekableRange_() {} // intentional no-op /** * Create a new flash source buffer and add it to our flash media source. * * @link https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/addSourceBuffer * @param {String} type the content-type of the source * @return {Object} the flash source buffer */ }, { key: 'addSourceBuffer', value: function addSourceBuffer(type) { var parsedType = (0, _codecUtils.parseContentType)(type); var sourceBuffer = undefined; // if this is an FLV type, we'll push data to flash if (parsedType.type === 'video/mp2t' || parsedType.type === 'audio/mp2t') { // Flash source buffers sourceBuffer = new _flashSourceBuffer2['default'](this); } else { throw new Error('NotSupportedError (Video.js)'); } this.sourceBuffers.push(sourceBuffer); return sourceBuffer; } /** * Signals the end of the stream. * * @link https://w3c.github.io/media-source/#widl-MediaSource-endOfStream-void-EndOfStreamError-error * @param {String=} error Signals that a playback error * has occurred. If specified, it must be either "network" or * "decode". */ }, { key: 'endOfStream', value: function endOfStream(error) { if (error === 'network') { // MEDIA_ERR_NETWORK this.tech_.error(2); } else if (error === 'decode') { // MEDIA_ERR_DECODE this.tech_.error(3); } if (this.readyState !== 'ended') { this.readyState = 'ended'; this.swfObj.vjs_endOfStream(); } } }]); return FlashMediaSource; })(_videoJs2['default'].EventTarget); exports['default'] = FlashMediaSource; try { Object.defineProperty(FlashMediaSource.prototype, 'duration', { /** * Return the presentation duration. * * @return {Double} the duration of the media in seconds * @link http://www.w3.org/TR/media-source/#widl-MediaSource-duration */ get: function get() { if (!this.swfObj) { return NaN; } // get the current duration from the SWF return this.swfObj.vjs_getProperty('duration'); }, /** * Set the presentation duration. * * @param {Double} value the duration of the media in seconds * @return {Double} the duration of the media in seconds * @link http://www.w3.org/TR/media-source/#widl-MediaSource-duration */ set: function set(value) { var i = undefined; var oldDuration = this.swfObj.vjs_getProperty('duration'); this.swfObj.vjs_setProperty('duration', value); if (value < oldDuration) { // In MSE, this triggers the range removal algorithm which causes // an update to occur for (i = 0; i < this.sourceBuffers.length; i++) { this.sourceBuffers[i].remove(value, oldDuration); } } return value; } }); } catch (e) { // IE8 throws if defineProperty is called on a non-DOM node. We // don't support IE8 but we shouldn't throw an error if loaded // there. FlashMediaSource.prototype.duration = NaN; } for (var property in _flashConstants2['default']) { FlashMediaSource[property] = _flashConstants2['default'][property]; } module.exports = exports['default']; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {var topLevel = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : {} var minDoc = __webpack_require__(5); var doccy; if (typeof document !== 'undefined') { doccy = document; } else { doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; if (!doccy) { doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; } } module.exports = doccy; /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }), /* 5 */ /***/ (function(module, exports) { /* (ignored) */ /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;'use strict'; exports.__esModule = true; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /** * @file video.js * @module videojs */ /* global define */ // Include the built-in techs var _window = __webpack_require__(7); var _window2 = _interopRequireDefault(_window); var _document = __webpack_require__(8); var _document2 = _interopRequireDefault(_document); var _browser = __webpack_require__(10); var browser = _interopRequireWildcard(_browser); var _dom = __webpack_require__(11); var Dom = _interopRequireWildcard(_dom); var _setup = __webpack_require__(16); var setup = _interopRequireWildcard(_setup); var _stylesheet = __webpack_require__(18); var stylesheet = _interopRequireWildcard(_stylesheet); var _component = __webpack_require__(19); var _component2 = _interopRequireDefault(_component); var _eventTarget = __webpack_require__(23); var _eventTarget2 = _interopRequireDefault(_eventTarget); var _events = __webpack_require__(17); var Events = _interopRequireWildcard(_events); var _player = __webpack_require__(24); var _player2 = _interopRequireDefault(_player); var _plugins = __webpack_require__(110); var _plugins2 = _interopRequireDefault(_plugins); var _mergeOptions2 = __webpack_require__(22); var _mergeOptions3 = _interopRequireDefault(_mergeOptions2); var _fn = __webpack_require__(20); var Fn = _interopRequireWildcard(_fn); var _textTrack = __webpack_require__(34); var _textTrack2 = _interopRequireDefault(_textTrack); var _audioTrack = __webpack_require__(111); var _audioTrack2 = _interopRequireDefault(_audioTrack); var _videoTrack = __webpack_require__(112); var _videoTrack2 = _interopRequireDefault(_videoTrack); var _timeRanges = __webpack_require__(25); var _formatTime = __webpack_require__(67); var _formatTime2 = _interopRequireDefault(_formatTime); var _log = __webpack_require__(13); var _log2 = _interopRequireDefault(_log); var _url = __webpack_require__(38); var Url = _interopRequireWildcard(_url); var _obj = __webpack_require__(14); var _computedStyle = __webpack_require__(75); var _computedStyle2 = _interopRequireDefault(_computedStyle); var _extend = __webpack_require__(113); var _extend2 = _interopRequireDefault(_extend); var _xhr = __webpack_require__(39); var _xhr2 = _interopRequireDefault(_xhr); var _tech = __webpack_require__(32); var _tech2 = _interopRequireDefault(_tech); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } // HTML5 Element Shim for IE8 if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) { _document2['default'].createElement('video'); _document2['default'].createElement('audio'); _document2['default'].createElement('track'); } /** * Doubles as the main function for users to create a player instance and also * the main library object. * The `videojs` function can be used to initialize or retrieve a player. * * @param {string|Element} id * Video element or video element ID * * @param {Object} [options] * Optional options object for config/settings * * @param {Component~ReadyCallback} [ready] * Optional ready callback * * @return {Player} * A player instance * * @mixes videojs */ function videojs(id, options, ready) { var tag = void 0; // Allow for element or ID to be passed in // String ID if (typeof id === 'string') { // Adjust for jQuery ID syntax if (id.indexOf('#') === 0) { id = id.slice(1); } // If a player instance has already been created for this ID return it. if (videojs.getPlayers()[id]) { // If options or ready funtion are passed, warn if (options) { _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.'); } if (ready) { videojs.getPlayers()[id].ready(ready); } return videojs.getPlayers()[id]; } // Otherwise get element for ID tag = Dom.getEl(id); // ID is a media element } else { tag = id; } // Check for a useable element // re: nodeName, could be a box div also if (!tag || !tag.nodeName) { throw new TypeError('The element or ID supplied is not valid. (videojs)'); } // Element may have a player attr referring to an already created player instance. // If so return that otherwise set up a new player below if (tag.player || _player2['default'].players[tag.playerId]) { return tag.player || _player2['default'].players[tag.playerId]; } options = options || {}; videojs.hooks('beforesetup').forEach(function (hookFunction) { var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options)); if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) { _log2['default'].error('please return an object in beforesetup hooks'); return; } options = (0, _mergeOptions3['default'])(options, opts); }); var PlayerComponent = _component2['default'].getComponent('Player'); // If not, set up a new player var player = new PlayerComponent(tag, options, ready); videojs.hooks('setup').forEach(function (hookFunction) { return hookFunction(player); }); return player; } /** * An Object that contains lifecycle hooks as keys which point to an array * of functions that are run when a lifecycle is triggered */ videojs.hooks_ = {}; /** * Get a list of hooks for a specific lifecycle * * @param {string} type * the lifecyle to get hooks from * * @param {Function} [fn] * Optionally add a hook to the lifecycle that your are getting. * * @return {Array} * an array of hooks, or an empty array if there are none. */ videojs.hooks = function (type, fn) { videojs.hooks_[type] = videojs.hooks_[type] || []; if (fn) { videojs.hooks_[type] = videojs.hooks_[type].concat(fn); } return videojs.hooks_[type]; }; /** * Add a function hook to a specific videojs lifecycle. * * @param {string} type * the lifecycle to hook the function to. * * @param {Function|Function[]} * The function or array of functions to attach. */ videojs.hook = function (type, fn) { videojs.hooks(type, fn); }; /** * Remove a hook from a specific videojs lifecycle. * * @param {string} type * the lifecycle that the function hooked to * * @param {Function} fn * The hooked function to remove * * @return {boolean} * The function that was removed or undef */ videojs.removeHook = function (type, fn) { var index = videojs.hooks(type).indexOf(fn); if (index <= -1) { return false; } videojs.hooks_[type] = videojs.hooks_[type].slice(); videojs.hooks_[type].splice(index, 1); return true; }; // Add default styles if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) { var style = Dom.$('.vjs-styles-defaults'); if (!style) { style = stylesheet.createStyleElement('vjs-styles-defaults'); var head = Dom.$('head'); if (head) { head.insertBefore(style, head.firstChild); } stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n '); } } // Run Auto-load players // You have to wait at least once in case this script is loaded after your // video in the DOM (weird behavior only with minified version) setup.autoSetupTimeout(1, videojs); /** * Current software version. Follows semver. * * @type {string} */ videojs.VERSION = '5.20.3'; /** * The global options object. These are the settings that take effect * if no overrides are specified when the player is created. * * @type {Object} */ videojs.options = _player2['default'].prototype.options_; /** * Get an object with the currently created players, keyed by player ID * * @return {Object} * The created players */ videojs.getPlayers = function () { return _player2['default'].players; }; /** * Expose players object. * * @memberOf videojs * @property {Object} players */ videojs.players = _player2['default'].players; /** * Get a component class object by name * * @borrows Component.getComponent as videojs.getComponent */ videojs.getComponent = _component2['default'].getComponent; /** * Register a component so it can referred to by name. Used when adding to other * components, either through addChild `component.addChild('myComponent')` or through * default children options `{ children: ['myComponent'] }`. * * > NOTE: You could also just initialize the component before adding. * `component.addChild(new MyComponent());` * * @param {string} name * The class name of the component * * @param {Component} comp * The component class * * @return {Component} * The newly registered component */ videojs.registerComponent = function (name, comp) { if (_tech2['default'].isTech(comp)) { _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)'); } _component2['default'].registerComponent.call(_component2['default'], name, comp); }; /** * Get a Tech class object by name * * @borrows Tech.getTech as videojs.getTech */ videojs.getTech = _tech2['default'].getTech; /** * Register a Tech so it can referred to by name. * This is used in the tech order for the player. * * @borrows Tech.registerTech as videojs.registerTech */ videojs.registerTech = _tech2['default'].registerTech; /** * A suite of browser and device tests from {@link browser}. * * @type {Object} * @private */ videojs.browser = browser; /** * Whether or not the browser supports touch events. Included for backward * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED` * instead going forward. * * @deprecated since version 5.0 * @type {boolean} */ videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED; /** * Subclass an existing class * Mimics ES6 subclassing with the `extend` keyword * * @borrows extend:extendFn as videojs.extend */ videojs.extend = _extend2['default']; /** * Merge two options objects recursively * Performs a deep merge like lodash.merge but **only merges plain objects** * (not arrays, elements, anything else) * Other values will be copied directly from the second object. * * @borrows merge-options:mergeOptions as videojs.mergeOptions */ videojs.mergeOptions = _mergeOptions3['default']; /** * Change the context (this) of a function * * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native * `function() {}.bind(newContext);` instead of this. * * @borrows fn:bind as videojs.bind */ videojs.bind = Fn.bind; /** * Create a Video.js player plugin. * Plugins are only initialized when options for the plugin are included * in the player options, or the plugin function on the player instance is * called. * * @borrows plugin:plugin as videojs.plugin */ videojs.plugin = _plugins2['default']; /** * Adding languages so that they're available to all players. * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });` * * @param {string} code * The language code or dictionary property * * @param {Object} data * The data values to be translated * * @return {Object} * The resulting language dictionary object */ videojs.addLanguage = function (code, data) { var _mergeOptions; code = ('' + code).toLowerCase(); videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions)); return videojs.options.languages[code]; }; /** * Log messages * * @borrows log:log as videojs.log */ videojs.log = _log2['default']; /** * Creates an emulated TimeRange object. * * @borrows time-ranges:createTimeRanges as videojs.createTimeRange */ /** * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges */ videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges; /** * Format seconds as a time string, H:MM:SS or M:SS * Supplying a guide (in seconds) will force a number of leading zeros * to cover the length of the guide * * @borrows format-time:formatTime as videojs.formatTime */ videojs.formatTime = _formatTime2['default']; /** * Resolve and parse the elements of a URL * * @borrows url:parseUrl as videojs.parseUrl */ videojs.parseUrl = Url.parseUrl; /** * Returns whether the url passed is a cross domain request or not. * * @borrows url:isCrossOrigin as videojs.isCrossOrigin */ videojs.isCrossOrigin = Url.isCrossOrigin; /** * Event target class. * * @borrows EventTarget as videojs.EventTarget */ videojs.EventTarget = _eventTarget2['default']; /** * Add an event listener to element * It stores the handler function in a separate cache object * and adds a generic handler to the element's event, * along with a unique id (guid) to the element. * * @borrows events:on as videojs.on */ videojs.on = Events.on; /** * Trigger a listener only once for an event * * @borrows events:one as videojs.one */ videojs.one = Events.one; /** * Removes event listeners from an element * * @borrows events:off as videojs.off */ videojs.off = Events.off; /** * Trigger an event for an element * * @borrows events:trigger as videojs.trigger */ videojs.trigger = Events.trigger; /** * A cross-browser XMLHttpRequest wrapper. Here's a simple example: * * @param {Object} options * settings for the request. * * @return {XMLHttpRequest|XDomainRequest} * The request object. * * @see https://github.com/Raynos/xhr */ videojs.xhr = _xhr2['default']; /** * TextTrack class * * @borrows TextTrack as videojs.TextTrack */ videojs.TextTrack = _textTrack2['default']; /** * export the AudioTrack class so that source handlers can create * AudioTracks and then add them to the players AudioTrackList * * @borrows AudioTrack as videojs.AudioTrack */ videojs.AudioTrack = _audioTrack2['default']; /** * export the VideoTrack class so that source handlers can create * VideoTracks and then add them to the players VideoTrackList * * @borrows VideoTrack as videojs.VideoTrack */ videojs.VideoTrack = _videoTrack2['default']; /** * Determines, via duck typing, whether or not a value is a DOM element. * * @borrows dom:isEl as videojs.isEl */ videojs.isEl = Dom.isEl; /** * Determines, via duck typing, whether or not a value is a text node. * * @borrows dom:isTextNode as videojs.isTextNode */ videojs.isTextNode = Dom.isTextNode; /** * Creates an element and applies properties. * * @borrows dom:createEl as videojs.createEl */ videojs.createEl = Dom.createEl; /** * Check if an element has a CSS class * * @borrows dom:hasElClass as videojs.hasClass */ videojs.hasClass = Dom.hasElClass; /** * Add a CSS class name to an element * * @borrows dom:addElClass as videojs.addClass */ videojs.addClass = Dom.addElClass; /** * Remove a CSS class name from an element * * @borrows dom:removeElClass as videojs.removeClass */ videojs.removeClass = Dom.removeElClass; /** * Adds or removes a CSS class name on an element depending on an optional * condition or the presence/absence of the class name. * * @borrows dom:toggleElClass as videojs.toggleClass */ videojs.toggleClass = Dom.toggleElClass; /** * Apply attributes to an HTML element. * * @borrows dom:setElAttributes as videojs.setAttribute */ videojs.setAttributes = Dom.setElAttributes; /** * Get an element's attribute values, as defined on the HTML tag * Attributes are not the same as properties. They're defined on the tag * or with setAttribute (which shouldn't be used with HTML) * This will return true or false for boolean attributes. * * @borrows dom:getElAttributes as videojs.getAttributes */ videojs.getAttributes = Dom.getElAttributes; /** * Empties the contents of an element. * * @borrows dom:emptyEl as videojs.emptyEl */ videojs.emptyEl = Dom.emptyEl; /** * Normalizes and appends content to an element. * * The content for an element can be passed in multiple types and * combinations, whose behavior is as follows: * * - String * Normalized into a text node. * * - Element, TextNode * Passed through. * * - Array * A one-dimensional array of strings, elements, nodes, or functions (which * return single strings, elements, or nodes). * * - Function * If the sole argument, is expected to produce a string, element, * node, or array. * * @borrows dom:appendContents as videojs.appendContet */ videojs.appendContent = Dom.appendContent; /** * Normalizes and inserts content into an element; this is identical to * `appendContent()`, except it empties the element first. * * The content for an element can be passed in multiple types and * combinations, whose behavior is as follows: * * - String * Normalized into a text node. * * - Element, TextNode * Passed through. * * - Array * A one-dimensional array of strings, elements, nodes, or functions (which * return single strings, elements, or nodes). * * - Function * If the sole argument, is expected to produce a string, element, * node, or array. * * @borrows dom:insertContent as videojs.insertContent */ videojs.insertContent = Dom.insertContent; /** * A safe getComputedStyle with an IE8 fallback. * * This is because in Firefox, if the player is loaded in an iframe with `display:none`, * then `getComputedStyle` returns `null`, so, we do a null-check to make sure * that the player doesn't break in these cases. * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details. * * @borrows computed-style:computedStyle as videojs.computedStyle */ videojs.computedStyle = _computedStyle2['default']; /* * Custom Universal Module Definition (UMD) * * Video.js will never be a non-browser lib so we can simplify UMD a bunch and * still support requirejs and browserify. This also needs to be closure * compiler compatible, so string keys are used. */ if (true) { !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () { return videojs; }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); // checking that module is an object too because of umdjs/umd#35 } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { module.exports = videojs; } exports['default'] = videojs; /***/ }), /* 7 */ /***/ (function(module, exports) { /* WEBPACK VAR INJECTION */(function(global) {if (typeof window !== "undefined") { module.exports = window; } else if (typeof global !== "undefined") { module.exports = global; } else if (typeof self !== "undefined"){ module.exports = self; } else { module.exports = {}; } /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {var topLevel = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : {} var minDoc = __webpack_require__(9); if (typeof document !== 'undefined') { module.exports = document; } else { var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; if (!doccy) { doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; } module.exports = doccy; } /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }), /* 9 */ /***/ (function(module, exports) { /* (ignored) */ /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; exports.BACKGROUND_SIZE_SUPPORTED = exports.TOUCH_ENABLED = exports.IS_ANY_SAFARI = exports.IS_SAFARI = exports.IE_VERSION = exports.IS_IE8 = exports.CHROME_VERSION = exports.IS_CHROME = exports.IS_EDGE = exports.IS_FIREFOX = exports.IS_NATIVE_ANDROID = exports.IS_OLD_ANDROID = exports.ANDROID_VERSION = exports.IS_ANDROID = exports.IOS_VERSION = exports.IS_IOS = exports.IS_IPOD = exports.IS_IPHONE = exports.IS_IPAD = undefined; var _dom = __webpack_require__(11); var Dom = _interopRequireWildcard(_dom); var _window = __webpack_require__(7); var _window2 = _interopRequireDefault(_window); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } /** * @file browser.js * @module browser */ var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || ''; var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT); var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null; /* * Device is an iPhone * * @type {Boolean} * @constant * @private */ var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT); // The Facebook app's UIWebView identifies as both an iPhone and iPad, so // to identify iPhones, we need to exclude iPads. // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT); var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; var IOS_VERSION = exports.IOS_VERSION = function () { var match = USER_AGENT.match(/OS (\d+)_/i); if (match && match[1]) { return match[1]; } return null; }(); var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT); var ANDROID_VERSION = exports.ANDROID_VERSION = function () { // This matches Android Major.Minor.Patch versions // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i); if (!match) { return null; } var major = match[1] && parseFloat(match[1]); var minor = match[2] && parseFloat(match[2]); if (major && minor) { return parseFloat(match[1] + '.' + match[2]); } else if (major) { return major; } return null; }(); // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3; var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537; var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT); var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT); var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT); var CHROME_VERSION = exports.CHROME_VERSION = function () { var match = USER_AGENT.match(/Chrome\/(\d+)/); if (match && match[1]) { return parseFloat(match[1]); } return null; }(); var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT); var IE_VERSION = exports.IE_VERSION = function () { var result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT); var version = result && parseFloat(result[1]); if (!version && /Trident\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) { // IE 11 has a different user agent string than other IE versions version = 11.0; } return version; }(); var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE; var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS; var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch); var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; exports.$$ = exports.$ = undefined; var _templateObject = _taggedTemplateLiteralLoose(['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.'], ['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.']); exports.isReal = isReal; exports.isEl = isEl; exports.getEl = getEl; exports.createEl = createEl; exports.textContent = textContent; exports.insertElFirst = insertElFirst; exports.getElData = getElData; exports.hasElData = hasElData; exports.removeElData = removeElData; exports.hasElClass = hasElClass; exports.addElClass = addElClass; exports.removeElClass = removeElClass; exports.toggleElClass = toggleElClass; exports.setElAttributes = setElAttributes; exports.getElAttributes = getElAttributes; exports.getAttribute = getAttribute; exports.setAttribute = setAttribute; exports.removeAttribute = removeAttribute; exports.blockTextSelection = blockTextSelection; exports.unblockTextSelection = unblockTextSelection; exports.findElPosition = findElPosition; exports.getPointerPosition = getPointerPosition; exports.isTextNode = isTextNode; exports.emptyEl = emptyEl; exports.normalizeContent = normalizeContent; exports.appendContent = appendContent; exports.insertContent = insertContent; var _document = __webpack_require__(8); var _document2 = _interopRequireDefault(_document); var _window = __webpack_require__(7); var _window2 = _interopRequireDefault(_window); var _guid = __webpack_require__(12); var Guid = _interopRequireWildcard(_guid); var _log = __webpack_require__(13); var _log2 = _interopRequireDefault(_log); var _tsml = __webpack_require__(15); var _tsml2 = _interopRequireDefault(_tsml); var _obj = __webpack_require__(14); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /** * @file dom.js * @module dom */ /** * Detect if a value is a string with any non-whitespace characters. * * @param {string} str * The string to check * * @return {boolean} * - True if the string is non-blank * - False otherwise * */ function isNonBlankString(str) { return typeof str === 'string' && /\S/.test(str); } /** * Throws an error if the passed string has whitespace. This is used by * class methods to be relatively consistent with the classList API. * * @param {string} str * The string to check for whitespace. * * @throws {Error} * Throws an error if there is whitespace in the string. * */ function throwIfWhitespace(str) { if (/\s/.test(str)) { throw new Error('class has illegal whitespace characters'); } } /** * Produce a regular expression for matching a className within an elements className. * * @param {string} className * The className to generate the RegExp for. * * @return {RegExp} * The RegExp that will check for a specific `className` in an elements * className. */ function classRegExp(className) { return new RegExp('(^|\\s)' + className + '($|\\s)'); } /** * Whether the current DOM interface appears to be real. * * @return {Boolean} */ function isReal() { return ( // Both document and window will never be undefined thanks to `global`. _document2['default'] === _window2['default'].document && // In IE < 9, DOM methods return "object" as their type, so all we can // confidently check is that it exists. typeof _document2['default'].createElement !== 'undefined' ); } /** * Determines, via duck typing, whether or not a value is a DOM element. * * @param {Mixed} value * The thing to check * * @return {boolean} * - True if it is a DOM element * - False otherwise */ function isEl(value) { return (0, _obj.isObject)(value) && value.nodeType === 1; } /** * Creates functions to query the DOM using a given method. * * @param {string} method * The method to create the query with. * * @return {Function} * The query method */ function createQuerier(method) { return function (selector, context) { if (!isNonBlankString(selector)) { return _document2['default'][method](null); } if (isNonBlankString(context)) { context = _document2['default'].querySelector(context); } var ctx = isEl(context) ? context : _document2['default']; return ctx[method] && ctx[method](selector); }; } /** * Shorthand for document.getElementById() * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs. * * @param {string} id * The id of the element to get * * @return {Element|null} * Element with supplied ID or null if there wasn't one. */ function getEl(id) { if (id.indexOf('#') === 0) { id = id.slice(1); } return _document2['default'].getElementById(id); } /** * Creates an element and applies properties. * * @param {string} [tagName='div'] * Name of tag to be created. * * @param {Object} [properties={}] * Element properties to be applied. * * @param {Object} [attributes={}] * Element attributes to be applied. * * @param {String|Element|TextNode|Array|Function} [content] * Contents for the element (see: {@link dom:normalizeContent}) * * @return {Element} * The element that was created. */ function createEl() { var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div'; var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var content = arguments[3]; var el = _document2['default'].createElement(tagName); Object.getOwnPropertyNames(properties).forEach(function (propName) { var val = properties[propName]; // See #2176 // We originally were accepting both properties and attributes in the // same object, but that doesn't work so well. if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val)); el.setAttribute(propName, val); // Handle textContent since it's not supported everywhere and we have a // method for it. } else if (propName === 'textContent') { textContent(el, val); } else { el[propName] = val; } }); Object.getOwnPropertyNames(attributes).forEach(function (attrName) { el.setAttribute(attrName, attributes[attrName]); }); if (content) { appendContent(el, content); } return el; } /** * Injects text into an element, replacing any existing contents entirely.