1
0
mirror of https://github.com/videojs/video.js.git synced 2025-03-17 21:18:27 +02:00

docs(jsdoc): Update the jsdoc comments to modern syntax - Part 4 (#3756)

Files in this PR:
* src/js/poster-image.js
* src/js/tech/flash-rtmp.js
* src/js/tech/flash.js
* src/js/tech/html5.js
* src/js/tech/loader.js
* src/js/tech/tech.js
This commit is contained in:
Brandon Casey 2016-12-02 15:14:36 -05:00 committed by Gary Katsevman
parent eb2093e16e
commit 15ce37e45d
6 changed files with 1649 additions and 474 deletions

View File

@ -8,15 +8,21 @@ import * as Dom from './utils/dom.js';
import * as browser from './utils/browser.js';
/**
* The component that handles showing the poster image.
* A `ClickableComponent` that handles showing the poster image for the player.
*
* @param {Player|Object} player
* @param {Object=} options
* @extends Button
* @class PosterImage
* @extends ClickableComponent
*/
class PosterImage extends ClickableComponent {
/**
* Create an instance of this class.
*
* @param {Player} player
* The `Player` that this class should attach to.
*
* @param {Object} [options]
* The key/value store of player options.
*/
constructor(player, options) {
super(player, options);
@ -25,9 +31,7 @@ class PosterImage extends ClickableComponent {
}
/**
* Clean up the poster image
*
* @method dispose
* Clean up and dispose of the `PosterImage`.
*/
dispose() {
this.player().off('posterchange', this.update);
@ -35,10 +39,10 @@ class PosterImage extends ClickableComponent {
}
/**
* Create the poster's image element
* Create the `PosterImage`s DOM element.
*
* @return {Element}
* @method createEl
* The element that gets created.
*/
createEl() {
const el = Dom.createEl('div', {
@ -61,11 +65,14 @@ class PosterImage extends ClickableComponent {
}
/**
* Event handler for updates to the player's poster source
* An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
*
* @method update
* @listens Player#posterchange
*
* @param {EventTarget~Event} [event]
* The `Player#posterchange` event that triggered this function.
*/
update() {
update(event) {
const url = this.player().poster();
this.setSrc(url);
@ -80,10 +87,10 @@ class PosterImage extends ClickableComponent {
}
/**
* Set the poster source depending on the display method
* Set the source of the `PosterImage` depending on the display method.
*
* @param {String} url The URL to the poster source
* @method setSrc
* @param {String} url
* The URL to the source for the `PosterImage`.
*/
setSrc(url) {
if (this.fallbackImg_) {
@ -102,11 +109,17 @@ class PosterImage extends ClickableComponent {
}
/**
* Event handler for clicks on the poster image
* An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
* {@link ClickableComponent#handleClick} for instances where this will be triggered.
*
* @method handleClick
* @listens tap
* @listens click
* @listens keydown
*
* @param {EventTarget~Event} event
+ The `click`, `tap` or `keydown` event that caused this function to be called.
*/
handleClick() {
handleClick(event) {
// We don't want a click to trigger playback when controls are disabled
// but CSS should be hiding the poster to prevent that from happening
if (this.player_.paused()) {

View File

@ -1,5 +1,15 @@
/**
* @file flash-rtmp.js
* @module flash-rtmp
*/
/**
* Add RTMP properties to the {@link Flash} Tech.
*
* @param {Flash} Flash
* The flash tech class.
*
* @mixin FlashRtmpDecorator
*/
function FlashRtmpDecorator(Flash) {
Flash.streamingFormats = {
@ -7,10 +17,40 @@ function FlashRtmpDecorator(Flash) {
'rtmp/flv': 'FLV'
};
/**
* Join connection and stream with an ampersand.
*
* @param {string} connection
* The connection string.
*
* @param {string} stream
* The stream string.
*/
Flash.streamFromParts = function(connection, stream) {
return connection + '&' + stream;
};
/**
* The flash parts object that contains connection and stream info.
*
* @typedef {Object} Flash~PartsObject
*
* @property {string} connection
* The connection string of a source, defaults to an empty string.
*
* @property {string} stream
* The stream string of the source, defaults to an empty string.
*/
/**
* Convert a source url into a stream and connection parts.
*
* @param {string} src
* the source url
*
* @return {Flash~PartsObject}
* The parts object that contains a connection and a stream
*/
Flash.streamToParts = function(src) {
const parts = {
connection: '',
@ -44,14 +84,41 @@ function FlashRtmpDecorator(Flash) {
return parts;
};
/**
* Check if the source type is a streaming type.
*
* @param {string} srcType
* The mime type to check.
*
* @return {boolean}
* - True if the source type is a streaming type.
* - False if the source type is not a streaming type.
*/
Flash.isStreamingType = function(srcType) {
return srcType in Flash.streamingFormats;
};
// RTMP has four variations, any string starting
// with one of these protocols should be valid
/**
* Regular expression used to check if the source is an rtmp source.
*
* @property
* @type {RegExp}
*/
Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
/**
* Check if the source itself is a streaming type.
*
* @param {string} src
* The url to the source.
*
* @return {boolean}
* - True if the source url indicates that the source is streaming.
* - False if the shource url indicates that the source url is not streaming.
*/
Flash.isStreamingSrc = function(src) {
return Flash.RTMP_RE.test(src);
};
@ -63,9 +130,13 @@ function FlashRtmpDecorator(Flash) {
Flash.rtmpSourceHandler = {};
/**
* Check if Flash can play the given videotype
* @param {String} type The mimetype to check
* @return {String} 'probably', 'maybe', or '' (empty string)
* Check if Flash can play the given mime type.
*
* @param {string} type
* The mime type to check
*
* @return {string}
* 'maybe', or '' (empty string)
*/
Flash.rtmpSourceHandler.canPlayType = function(type) {
if (Flash.isStreamingType(type)) {
@ -77,9 +148,15 @@ function FlashRtmpDecorator(Flash) {
/**
* Check if Flash can handle the source natively
* @param {Object} source The source object
* @param {Object} options The options passed to the tech
* @return {String} 'probably', 'maybe', or '' (empty string)
*
* @param {Object} source
* The source object
*
* @param {Object} [options]
* The options passed to the tech
*
* @return {string}
* 'maybe', or '' (empty string)
*/
Flash.rtmpSourceHandler.canHandleSource = function(source, options) {
const can = Flash.rtmpSourceHandler.canPlayType(source.type);
@ -96,12 +173,16 @@ function FlashRtmpDecorator(Flash) {
};
/**
* Pass the source to the flash object
* Adaptive source handlers will have more complicated workflows before passing
* video data to the video element
* @param {Object} source The source object
* @param {Flash} tech The instance of the Flash tech
* @param {Object} options The options to pass to the source
* Pass the source to the flash object.
*
* @param {Object} source
* The source object
*
* @param {Flash} tech
* The instance of the Flash tech
*
* @param {Object} [options]
* The options to pass to the source
*/
Flash.rtmpSourceHandler.handleSource = function(source, tech, options) {
const srcParts = Flash.streamToParts(source.src);

View File

@ -17,15 +17,23 @@ import assign from 'object.assign';
const navigator = window.navigator;
/**
* Flash Media Controller - Wrapper for fallback SWF API
* Flash Media Controller - Wrapper for Flash Media API
*
* @param {Object=} options Object of option names and values
* @param {Function=} ready Ready callback function
* @mixes FlashRtmpDecorator
* @mixes Tech~SouceHandlerAdditions
* @extends Tech
* @class Flash
*/
class Flash extends Tech {
/**
* Create an instance of this Tech.
*
* @param {Object} [options]
* The key/value store of player options.
*
* @param {Component~ReadyCallback} ready
* Callback function to call when the `Flash` Tech is ready.
*/
constructor(options, ready) {
super(options, ready);
@ -59,13 +67,14 @@ class Flash extends Tech {
this.on('seeked', function() {
this.lastSeekTarget_ = undefined;
});
}
/**
* Create the component's DOM element
* Create the `Flash` Tech's DOM element.
*
* @return {Element}
* @method createEl
* The element that gets created.
*/
createEl() {
const options = this.options_;
@ -122,9 +131,7 @@ class Flash extends Tech {
}
/**
* Play for flash tech
*
* @method play
* Called by {@link Player#play} to play using the `Flash` `Tech`.
*/
play() {
if (this.ended()) {
@ -134,20 +141,24 @@ class Flash extends Tech {
}
/**
* Pause for flash tech
*
* @method pause
* Called by {@link Player#pause} to pause using the `Flash` `Tech`.
*/
pause() {
this.el_.vjs_pause();
}
/**
* Get/set video
* A getter/setter for the `Flash` Tech's source object.
* > Note: Please use {@link Flash#setSource}
*
* @param {Object=} src Source object
* @return {Object}
* @method src
* @param {Tech~SourceObject} [src]
* The source object you want to set on the `Flash` techs.
*
* @return {Tech~SourceObject|undefined}
* - The current source object when a source is not passed in.
* - undefined when setting
*
* @deprecated Since version 5.
*/
src(src) {
if (src === undefined) {
@ -159,11 +170,14 @@ class Flash extends Tech {
}
/**
* Set video
* A getter/setter for the `Flash` Tech's source object.
*
* @param {Object=} src Source object
* @deprecated
* @method setSrc
* @param {Tech~SourceObject} [src]
* The source object you want to set on the `Flash` techs.
*
* @return {Tech~SourceObject|undefined}
* - The current source object when a source is not passed in.
* - undefined when setting
*/
setSrc(src) {
// Make sure source URL is absolute.
@ -178,18 +192,21 @@ class Flash extends Tech {
}
/**
* Returns true if the tech is currently seeking.
* @return {boolean} true if seeking
* Indicates whether the media is currently seeking to a new position or not.
*
* @return {boolean}
* - True if seeking to a new position
* - False otherwise
*/
seeking() {
return this.lastSeekTarget_ !== undefined;
}
/**
* Set current time
* Returns the current time in seconds that the media is at in playback.
*
* @param {Number} time Current time of video
* @method setCurrentTime
* @param {number} time
* Current playtime of the media in seconds.
*/
setCurrentTime(time) {
const seekable = this.seekable();
@ -207,13 +224,12 @@ class Flash extends Tech {
}
/**
* Get current time
* Get the current playback time in seconds
*
* @param {Number=} time Current time of video
* @return {Number} Current time
* @method currentTime
* @return {number}
* The current time of playback in seconds.
*/
currentTime(time) {
currentTime() {
// when seeking make the reported time keep up with the requested time
// by reading the time we're seeking to
if (this.seeking()) {
@ -223,9 +239,11 @@ class Flash extends Tech {
}
/**
* Get current source
* Get the current source
*
* @method currentSrc
* @return {Tech~SourceObject}
* The current source
*/
currentSrc() {
if (this.currentSource_) {
@ -235,9 +253,10 @@ class Flash extends Tech {
}
/**
* Get media duration
* Get the total duration of the current media.
*
* @returns {Number} Media duration
* @return {number}
8 The total duration of the current media.
*/
duration() {
if (this.readyState() === 0) {
@ -249,35 +268,29 @@ class Flash extends Tech {
}
/**
* Load media into player
*
* @method load
* Load media into Tech.
*/
load() {
this.el_.vjs_load();
}
/**
* Get poster
*
* @method poster
* Get the poster image that was set on the tech.
*/
poster() {
this.el_.vjs_getProperty('poster');
}
/**
* Poster images are not handled by the Flash tech so make this a no-op
*
* @method setPoster
* Poster images are not handled by the Flash tech so make this is a no-op.
*/
setPoster() {}
/**
* Determine if can seek in media
* Determine the time ranges that can be seeked to in the media.
*
* @return {TimeRangeObject}
* @method seekable
* @return {TimeRange}
* Returns the time ranges that can be seeked to.
*/
seekable() {
const duration = this.duration();
@ -289,10 +302,10 @@ class Flash extends Tech {
}
/**
* Get buffered time range
* Get and create a `TimeRange` object for buffering.
*
* @return {TimeRangeObject}
* @method buffered
* @return {TimeRange}
* The time range object that was created.
*/
buffered() {
const ranges = this.el_.vjs_getProperty('buffered');
@ -305,11 +318,12 @@ class Flash extends Tech {
/**
* Get fullscreen support -
* Flash does not allow fullscreen through javascript
* so always returns false
*
* @return {Boolean} false
* @method supportsFullScreen
* Flash does not allow fullscreen through javascript
* so this always returns false.
*
* @return {boolean}
* The Flash tech does not support fullscreen, so it will always return false.
*/
supportsFullScreen() {
// Flash does not allow fullscreen through javascript
@ -317,12 +331,11 @@ class Flash extends Tech {
}
/**
* Request to enter fullscreen
* Flash does not allow fullscreen through javascript
* so always returns false
* so this always returns false.
*
* @return {Boolean} false
* @method enterFullScreen
* @return {boolean}
* The Flash tech does not support fullscreen, so it will always return false.
*/
enterFullScreen() {
return false;
@ -360,8 +373,392 @@ for (let i = 0; i < _readOnly.length; i++) {
_createGetter(_readOnly[i]);
}
/** ------------------------------ Getters ------------------------------ **/
/**
* Get the value of `rtmpConnection` from the swf.
*
* @method Flash.prototype.rtmpConnection
* @return {string}
* The current value of `rtmpConnection` on the swf.
*/
/**
* Get the value of `rtmpStream` from the swf.
*
* @method Flash.prototype.rtmpStream
* @return {string}
* The current value of `rtmpStream` on the swf.
*/
/**
* Get the value of `preload` from the swf. `preload` indicates
* what should download before the media is interacted with. It can have the following
* values:
* - none: nothing should be downloaded
* - metadata: poster and the first few frames of the media may be downloaded to get
* media dimensions and other metadata
* - auto: allow the media and metadata for the media to be downloaded before
* interaction
*
* @method Flash.prototype.preload
* @return {string}
* The value of `preload` from the swf. Will be 'none', 'metadata',
* or 'auto'.
*/
/**
* Get the value of `defaultPlaybackRate` from the swf.
*
* @method Flash.prototype.defaultPlaybackRate
* @return {number}
* The current value of `defaultPlaybackRate` on the swf.
*/
/**
* Get the value of `playbackRate` from the swf. `playbackRate` indicates
* the rate at which the media is currently playing back. Examples:
* - if playbackRate is set to 2, media will play twice as fast.
* - if playbackRate is set to 0.5, media will play half as fast.
*
* @method Flash.prototype.playbackRate
* @return {number}
* The value of `playbackRate` from the swf. A number indicating
* the current playback speed of the media, where 1 is normal speed.
*/
/**
* Get the value of `autoplay` from the swf. `autoplay` indicates
* that the media should start to play as soon as the page is ready.
*
* @method Flash.prototype.autoplay
* @return {boolean}
* - The value of `autoplay` from the swf.
* - True indicates that the media ashould start as soon as the page loads.
* - False indicates that the media should not start as soon as the page loads.
*/
/**
* Get the value of `loop` from the swf. `loop` indicates
* that the media should return to the start of the media and continue playing once
* it reaches the end.
*
* @method Flash.prototype.loop
* @return {boolean}
* - The value of `loop` from the swf.
* - True indicates that playback should seek back to start once
* the end of a media is reached.
* - False indicates that playback should not loop back to the start when the
* end of the media is reached.
*/
/**
* Get the value of `mediaGroup` from the swf.
*
* @method Flash.prototype.mediaGroup
* @return {string}
* The current value of `mediaGroup` on the swf.
*/
/**
* Get the value of `controller` from the swf.
*
* @method Flash.prototype.controller
* @return {string}
* The current value of `controller` on the swf.
*/
/**
* Get the value of `controls` from the swf. `controls` indicates
* whether the native flash controls should be shown or hidden.
*
* @method Html5.prototype.controls
* @return {boolean}
* - The value of `controls` from the swf.
* - True indicates that native controls should be showing.
* - False indicates that native controls should be hidden.
*/
/**
* Get the value of the `volume` from the swf. `volume` indicates the current
* audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
* so on.
*
* @method Flash.prototype.volume
* @return {number}
* The volume percent as a decimal. Value will be between 0-1.
*/
/**
* Get the value of the `muted` from the swf. `muted` indicates the current
* audio level should be silent.
*
* @method Flash.prototype.muted
* @return {boolean}
* - True if the audio should be set to silent
* - False otherwise
*/
/**
* Get the value of `defaultMuted` from the swf. `defaultMuted` indicates
* whether the media should start muted or not. Only changes the default state of the
* media. `muted` and `defaultMuted` can have different values. `muted` indicates the
* current state.
*
* @method Flash.prototype.defaultMuted
* @return {boolean}
* - The value of `defaultMuted` from the swf.
* - True indicates that the media should start muted.
* - False indicates that the media should not start muted.
*/
/**
* Get the value of `networkState` from the swf. `networkState` indicates
* the current network state. It returns an enumeration from the following list:
* - 0: NETWORK_EMPTY
* - 1: NEWORK_IDLE
* - 2: NETWORK_LOADING
* - 3: NETWORK_NO_SOURCE
*
* @method Flash.prototype.networkState
* @return {number}
* The value of `networkState` from the swf. This will be a number
* from the list in the description.
*/
/**
* Get the value of `readyState` from the swf. `readyState` indicates
* the current state of the media element. It returns an enumeration from the
* following list:
* - 0: HAVE_NOTHING
* - 1: HAVE_METADATA
* - 2: HAVE_CURRENT_DATA
* - 3: HAVE_FUTURE_DATA
* - 4: HAVE_ENOUGH_DATA
*
* @method Flash.prototype.readyState
* @return {number}
* The value of `readyState` from the swf. This will be a number
* from the list in the description.
*/
/**
* Get the value of `readyState` from the swf. `readyState` indicates
* the current state of the media element. It returns an enumeration from the
* following list:
* - 0: HAVE_NOTHING
* - 1: HAVE_METADATA
* - 2: HAVE_CURRENT_DATA
* - 3: HAVE_FUTURE_DATA
* - 4: HAVE_ENOUGH_DATA
*
* @method Flash.prototype.readyState
* @return {number}
* The value of `readyState` from the swf. This will be a number
* from the list in the description.
*/
/**
* Get the value of `initialTime` from the swf.
*
* @method Flash.prototype.initialTime
* @return {number}
* The `initialTime` proprety on the swf.
*/
/**
* Get the value of `startOffsetTime` from the swf.
*
* @method Flash.prototype.startOffsetTime
* @return {number}
* The `startOffsetTime` proprety on the swf.
*/
/**
* Get the value of `paused` from the swf. `paused` indicates whether the swf
* is current paused or not.
*
* @method Flash.prototype.paused
* @return {boolean}
* The value of `paused` from the swf.
*/
/**
* Get the value of `ended` from the swf. `ended` indicates whether
* the media has reached the end or not.
*
* @method Flash.prototype.ended
* @return {boolean}
* - True indicates that the media has ended.
* - False indicates that the media has not ended.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
*/
/**
* Get the value of `videoWidth` from the swf. `videoWidth` indicates
* the current width of the media in css pixels.
*
* @method Flash.prototype.videoWidth
* @return {number}
* The value of `videoWidth` from the swf. This will be a number
* in css pixels.
*/
/**
* Get the value of `videoHeight` from the swf. `videoHeigth` indicates
* the current height of the media in css pixels.
*
* @method Flassh.prototype.videoHeight
* @return {number}
* The value of `videoHeight` from the swf. This will be a number
* in css pixels.
*/
/** ------------------------------ Setters ------------------------------ **/
/**
* Set the value of `rtmpConnection` on the swf.
*
* @method Flash.prototype.setRtmpConnection
* @param {string} rtmpConnection
* New value to set the `rtmpConnection` property to.
*/
/**
* Set the value of `rtmpStream` on the swf.
*
* @method Flash.prototype.setRtmpStream
* @param {string} rtmpStream
* New value to set the `rtmpStream` property to.
*/
/**
* Set the value of `preload` on the swf. `preload` indicates
* what should download before the media is interacted with. It can have the following
* values:
* - none: nothing should be downloaded
* - metadata: poster and the first few frames of the media may be downloaded to get
* media dimensions and other metadata
* - auto: allow the media and metadata for the media to be downloaded before
* interaction
*
* @method Flash.prototype.setPreload
* @param {string} preload
* The value of `preload` to set on the swf. Should be 'none', 'metadata',
* or 'auto'.
*/
/**
* Set the value of `defaultPlaybackRate` on the swf.
*
* @method Flash.prototype.setDefaultPlaybackRate
* @param {number} defaultPlaybackRate
* New value to set the `defaultPlaybackRate` property to.
*/
/**
* Set the value of `playbackRate` on the swf. `playbackRate` indicates
* the rate at which the media is currently playing back. Examples:
* - if playbackRate is set to 2, media will play twice as fast.
* - if playbackRate is set to 0.5, media will play half as fast.
*
* @method Flash.prototype.setPlaybackRate
* @param {number} playbackRate
* New value of `playbackRate` on the swf. A number indicating
* the current playback speed of the media, where 1 is normal speed.
*/
/**
* Set the value of `autoplay` on the swf. `autoplay` indicates
* that the media should start to play as soon as the page is ready.
*
* @method Flash.prototype.setAutoplay
* @param {boolean} autoplay
* - The value of `autoplay` from the swf.
* - True indicates that the media ashould start as soon as the page loads.
* - False indicates that the media should not start as soon as the page loads.
*/
/**
* Set the value of `loop` on the swf. `loop` indicates
* that the media should return to the start of the media and continue playing once
* it reaches the end.
*
* @method Flash.prototype.setLoop
* @param {boolean} loop
* - True indicates that playback should seek back to start once
* the end of a media is reached.
* - False indicates that playback should not loop back to the start when the
* end of the media is reached.
*/
/**
* Set the value of `mediaGroup` on the swf.
*
* @method Flash.prototype.setMediaGroup
* @param {string} mediaGroup
* New value of `mediaGroup` to set on the swf.
*/
/**
* Set the value of `controller` on the swf.
*
* @method Flash.prototype.setController
* @param {string} controller
* New value the current value of `controller` on the swf.
*/
/**
* Get the value of `controls` from the swf. `controls` indicates
* whether the native flash controls should be shown or hidden.
*
* @method Flash.prototype.controls
* @return {boolean}
* - The value of `controls` from the swf.
* - True indicates that native controls should be showing.
* - False indicates that native controls should be hidden.
*/
/**
* Set the value of the `volume` on the swf. `volume` indicates the current
* audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
* so on.
*
* @method Flash.prototype.setVolume
* @param {number} percentAsDecimal
* The volume percent as a decimal. Value will be between 0-1.
*/
/**
* Set the value of the `muted` on the swf. `muted` indicates that the current
* audio level should be silent.
*
* @method Flash.prototype.setMuted
* @param {boolean} muted
* - True if the audio should be set to silent
* - False otherwise
*/
/**
* Set the value of `defaultMuted` on the swf. `defaultMuted` indicates
* whether the media should start muted or not. Only changes the default state of the
* media. `muted` and `defaultMuted` can have different values. `muted` indicates the
* current state.
*
* @method Flash.prototype.setDefaultMuted
* @param {boolean} defaultMuted
* - True indicates that the media should start muted.
* - False indicates that the media should not start muted.
*/
/* Flash Support Testing -------------------------------------------------------- */
/**
* Check if the Flash tech is currently supported.
*
* @return {boolean}
* - True if the flash tech is supported.
* - False otherwise.
*/
Flash.isSupported = function() {
return Flash.version()[0] >= 10;
// return swfobject.hasFlashPlayerVersion('10');
@ -371,18 +768,24 @@ Flash.isSupported = function() {
Tech.withSourceHandlers(Flash);
/*
* The default native source handler.
* This simply passes the source to the video element. Nothing fancy.
* Native source handler for flash, simply passes the source to the swf element.
*
* @param {Object} source The source object
* @param {Flash} tech The instance of the Flash tech
* @property {Tech~SourceObject} source
* The source object
*
* @property {Flash} tech
* The instance of the Flash tech
*/
Flash.nativeSourceHandler = {};
/**
* Check if Flash can play the given videotype
* @param {String} type The mimetype to check
* @return {String} 'probably', 'maybe', or '' (empty string)
* Check if the Flash can play the given mime type.
*
* @param {string} type
* The mimetype to check
*
* @return {string}
* 'maybe', or '' (empty string)
*/
Flash.nativeSourceHandler.canPlayType = function(type) {
if (type in Flash.formats) {
@ -392,12 +795,17 @@ Flash.nativeSourceHandler.canPlayType = function(type) {
return '';
};
/*
* Check Flash can handle the source natively
/**
* Check if the media element can handle a source natively.
*
* @param {Object} source The source object
* @param {Object} options The options passed to the tech
* @return {String} 'probably', 'maybe', or '' (empty string)
* @param {Tech~SourceObject} source
* The source object
*
* @param {Object} [options]
* Options to be passed to the tech.
*
* @return {string}
* 'maybe', or '' (empty string).
*/
Flash.nativeSourceHandler.canHandleSource = function(source, options) {
let type;
@ -421,28 +829,35 @@ Flash.nativeSourceHandler.canHandleSource = function(source, options) {
return Flash.nativeSourceHandler.canPlayType(type);
};
/*
* Pass the source to the flash object
* Adaptive source handlers will have more complicated workflows before passing
* video data to the video element
/**
* Pass the source to the swf.
*
* @param {Object} source The source object
* @param {Flash} tech The instance of the Flash tech
* @param {Object} options The options to pass to the source
* @param {Tech~SourceObject} source
* The source object
*
* @param {Flash} tech
* The instance of the Flash tech
*
* @param {Object} [options]
* The options to pass to the source
*/
Flash.nativeSourceHandler.handleSource = function(source, tech, options) {
tech.setSrc(source.src);
};
/*
* Clean up the source handler when disposing the player or switching sources..
* (no cleanup is needed when supporting the format natively)
/**
* noop for native source handler dispose, as cleanup will happen automatically.
*/
Flash.nativeSourceHandler.dispose = function() {};
// Register the native source handler
Flash.registerSourceHandler(Flash.nativeSourceHandler);
/**
* Flash supported mime types.
*
* @constant {Object}
*/
Flash.formats = {
'video/flv': 'FLV',
'video/x-flv': 'FLV',
@ -450,6 +865,10 @@ Flash.formats = {
'video/m4v': 'MP4'
};
/**
* Called when the the swf is "ready", and makes sure that the swf is really
* ready using {@link Flash#checkReady}
*/
Flash.onReady = function(currSwf) {
const el = Dom.getEl(currSwf);
const tech = el && el.tech;
@ -462,8 +881,14 @@ Flash.onReady = function(currSwf) {
}
};
// The SWF isn't always ready when it says it is. Sometimes the API functions still need to be added to the object.
// If it's not ready, we set a timeout to check again shortly.
/**
* The SWF isn't always ready when it says it is. Sometimes the API functions still
* need to be added to the object. If it's not ready, we set a timeout to check again
* shortly.
*
* @param {Flash} tech
* The instance of the flash tech to check.
*/
Flash.checkReady = function(tech) {
// stop worrying if the tech has been disposed
if (!tech.el()) {
@ -482,7 +907,15 @@ Flash.checkReady = function(tech) {
}
};
// Trigger events from the swf on the player
/**
* Trigger events from the swf on the Flash Tech.
*
* @param {number} swfID
* The id of the swf that had the event
*
* @param {string} eventName
* The name of the event to trigger
*/
Flash.onEvent = function(swfID, eventName) {
const tech = Dom.getEl(swfID).tech;
const args = Array.prototype.slice.call(arguments, 2);
@ -497,7 +930,19 @@ Flash.onEvent = function(swfID, eventName) {
}, 1);
};
// Log errors from the swf
/**
* Log errors from the swf on the Flash tech.
*
* @param {number} swfID
* The id of the swf that had an error.
*
* @param {string} The error string
* The error to set on the Flash Tech.
*
* @return {MediaError|undefined}
* - Returns a MediaError when err is 'srcnotfound'
* - Returns undefined otherwise.
*/
Flash.onError = function(swfID, err) {
const tech = Dom.getEl(swfID).tech;
@ -510,7 +955,12 @@ Flash.onError = function(swfID, err) {
tech.error('FLASH: ' + err);
};
// Flash Version Check
/**
* Get the current version of Flash that is in use on the page.
*
* @return {Array}
* an array of versions that are available.
*/
Flash.version = function() {
let version = '0,0,0';
@ -531,7 +981,24 @@ Flash.version = function() {
return version.split(',');
};
// Flash embedding method. Only used in non-iframe mode
/**
* Only use for non-iframe embeds.
*
* @param {Object} swf
* The videojs-swf object.
*
* @param {Object} flashVars
* Names and values to use as flash option variables.
*
* @param {Object} params
* Style parameters to set on the object.
*
* @param {Object} attributes
* Attributes to set on the element.
*
* @return {Element}
* The embeded Flash DOM element.
*/
Flash.embed = function(swf, flashVars, params, attributes) {
const code = Flash.getEmbedCode(swf, flashVars, params, attributes);
@ -541,6 +1008,24 @@ Flash.embed = function(swf, flashVars, params, attributes) {
return obj;
};
/**
* Only use for non-iframe embeds.
*
* @param {Object} swf
* The videojs-swf object.
*
* @param {Object} flashVars
* Names and values to use as flash option variables.
*
* @param {Object} params
* Style parameters to set on the object.
*
* @param {Object} attributes
* Attributes to set on the element.
*
* @return {Element}
* The embeded Flash DOM element.
*/
Flash.getEmbedCode = function(swf, flashVars, params, attributes) {
const objTag = '<object type="application/x-shockwave-flash" ';
let flashVarsString = '';

File diff suppressed because it is too large Load Diff

View File

@ -6,17 +6,25 @@ import Tech from './tech.js';
import toTitleCase from '../utils/to-title-case.js';
/**
* The Media Loader is the component that decides which playback technology to load
* when the player is initialized.
* The `MediaLoader` is the `Component` that decides which playback technology to load
* when a player is initialized.
*
* @param {Object} player Main Player
* @param {Object=} options Object of option names and values
* @param {Function=} ready Ready callback function
* @extends Component
* @class MediaLoader
*/
class MediaLoader extends Component {
/**
* Create an instance of this class.
*
* @param {Player} player
* The `Player` that this class should attach to.
*
* @param {Object} [options]
* The key/value stroe of player options.
*
* @param {Component~ReadyCallback} [ready]
* The function that is run when this component is ready.
*/
constructor(player, options, ready) {
super(player, options, ready);

View File

@ -1,7 +1,5 @@
/**
* @file tech.js
* Media Technology Controller - Base class for media playback
* technology controllers like Flash and HTML5
*/
import Component from '../component';
@ -20,6 +18,48 @@ import MediaError from '../media-error.js';
import window from 'global/window';
import document from 'global/document';
/**
* An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
* that just contains the src url alone.
*
* ``` js
* var SourceObject = {
* src: 'http://example.com/some-video.mp4',
* type: 'video/mp4'
* };
* var SourceString = 'http://example.com/some-video.mp4';
* ```
*
* @typedef {Object|string} Tech~SourceObject
*
* @property {string} src
* The url to the source
*
* @property {string} type
* The mime type of the source
*/
/**
* A function used by {@link Tech} to create a new {@link TextTrack}.
*
* @param {Tech} self
* An instance of the Tech class.
*
* @param {string} kind
* `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
*
* @param {string} [label]
* Label to identify the text track
*
* @param {string} [language]
* Two letter language abbreviation
*
* @param {Object} [options={}]
* An object with additional text track options
*
* @return {TextTrack}
* The text track that was created.
*/
function createTrackHelper(self, kind, label, language, options = {}) {
const tracks = self.textTracks();
@ -41,15 +81,22 @@ function createTrackHelper(self, kind, label, language, options = {}) {
}
/**
* Base class for media (HTML5 Video, Flash) controllers
* This is the base class for media playback technology controllers, such as
* {@link Flash} and {@link HTML5}
*
* @param {Object=} options Options object
* @param {Function=} ready Ready callback function
* @extends Component
* @class Tech
*/
class Tech extends Component {
/**
* Create an instance of this Tech.
*
* @param {Object} [options]
* The key/value store of player options.
*
* @param {Component~ReadyCallback} ready
* Callback function to call when the `HTML5` Tech is ready.
*/
constructor(options = {}, ready = function() {}) {
// we don't want the tech to report user activity automatically.
// This is done manually in addControlsListeners
@ -105,12 +152,11 @@ class Tech extends Component {
/* Fallbacks for unsupported event types
================================================================================ */
// Manually trigger progress events based on changes to the buffered amount
// Many flash players and older HTML5 browsers don't send progress or progress-like events
/**
* Turn on progress events
* Polyfill the `progress` event for browsers that don't support it natively.
*
* @method manualProgressOn
* @see {@link Tech#trackProgress}
*/
manualProgressOn() {
this.on('durationchange', this.onDurationChange);
@ -122,9 +168,8 @@ class Tech extends Component {
}
/**
* Turn off progress events
*
* @method manualProgressOff
* Turn off the polyfill for `progress` events that was created in
* {@link Tech#manualProgressOn}
*/
manualProgressOff() {
this.manualProgress = false;
@ -134,11 +179,19 @@ class Tech extends Component {
}
/**
* Track progress
* This is used to trigger a `progress` event when the buffered percent changes. It
* sets an interval function that will be called every 500 milliseconds to check if the
* buffer end percent has changed.
*
* @method trackProgress
* > This function is called by {@link Tech#manualProgressOn}
*
* @param {EventTarget~Event} event
* The `ready` event that caused this to run.
*
* @listens Tech#ready
* @fires Tech#progress
*/
trackProgress() {
trackProgress(event) {
this.stopTrackingProgress();
this.progressInterval = this.setInterval(Fn.bind(this, function() {
// Don't trigger unless buffered amount is greater than last time
@ -146,6 +199,12 @@ class Tech extends Component {
const numBufferedPercent = this.bufferedPercent();
if (this.bufferedPercent_ !== numBufferedPercent) {
/**
* See {@link Player#progress}
*
* @event Tech#progress
* @type {EventTarget~Event}
*/
this.trigger('progress');
}
@ -158,47 +217,54 @@ class Tech extends Component {
}
/**
* Update duration
* Update our internal duration on a `durationchange` event by calling
* {@link Tech#duration}.
*
* @method onDurationChange
* @param {EventTarget~Event} event
* The `durationchange` event that caused this to run.
*
* @listens Tech#durationchange
*/
onDurationChange() {
onDurationChange(event) {
this.duration_ = this.duration();
}
/**
* Create and get TimeRange object for buffering
* Get and create a `TimeRange` object for buffering.
*
* @return {TimeRangeObject}
* @method buffered
* @return {TimeRange}
* The time range object that was created.
*/
buffered() {
return createTimeRange(0, 0);
}
/**
* Get buffered percent
* Get the percentage of the current video that is currently buffered.
*
* @return {number}
* A number from 0 to 1 that represents the decimal percentage of the
* video that is buffered.
*
* @return {Number}
* @method bufferedPercent
*/
bufferedPercent() {
return bufferedPercent(this.buffered(), this.duration_);
}
/**
* Stops tracking progress by clearing progress interval
*
* @method stopTrackingProgress
* Turn off the polyfill for `progress` events that was created in
* {@link Tech#manualProgressOn}
* Stop manually tracking progress events by clearing the interval that was set in
* {@link Tech#trackProgress}.
*/
stopTrackingProgress() {
this.clearInterval(this.progressInterval);
}
/**
* Set event listeners for on play and pause and tracking current time
* Polyfill the `timeupdate` event for browsers that don't support it.
*
* @method manualTimeUpdatesOn
* @see {@link Tech#trackCurrentTime}
*/
manualTimeUpdatesOn() {
this.manualTimeUpdates = true;
@ -208,9 +274,8 @@ class Tech extends Component {
}
/**
* Remove event listeners for on play and pause and tracking current time
*
* @method manualTimeUpdatesOff
* Turn off the polyfill for `timeupdate` events that was created in
* {@link Tech#manualTimeUpdatesOn}
*/
manualTimeUpdatesOff() {
this.manualTimeUpdates = false;
@ -220,15 +285,23 @@ class Tech extends Component {
}
/**
* Tracks current time
* Sets up an interval function to track current time and trigger `timeupdate` every
* 250 milliseconds.
*
* @method trackCurrentTime
* @listens Tech#play
* @triggers Tech#timeupdate
*/
trackCurrentTime() {
if (this.currentTimeInterval) {
this.stopTrackingCurrentTime();
}
this.currentTimeInterval = this.setInterval(function() {
/**
* Triggered at an interval of 250ms to indicated that time is passing in the video.
*
* @event Tech#timeupdate
* @type {EventTarget~Event}
*/
this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
// 42 = 24 fps // 250 is what Webkit uses // FF uses 15
@ -236,9 +309,10 @@ class Tech extends Component {
}
/**
* Turn off play progress tracking (when paused or dragging)
* Stop the interval function created in {@link Tech#trackCurrentTime} so that the
* `timeupdate` event is no longer triggered.
*
* @method stopTrackingCurrentTime
* @listens {Tech#pause}
*/
stopTrackingCurrentTime() {
this.clearInterval(this.currentTimeInterval);
@ -249,9 +323,10 @@ class Tech extends Component {
}
/**
* Turn off any manual progress or timeupdate tracking
* Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList},
* {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.
*
* @method dispose
* @fires Component#dispose
*/
dispose() {
@ -271,15 +346,14 @@ class Tech extends Component {
}
/**
* clear out a track list, or multiple track lists
* Clear out a single `TrackList` or an array of `TrackLists` given their names.
*
* Note: Techs without source handlers should call this between
* sources for video & audio tracks, as usually you don't want
* to use them between tracks and we have no automatic way to do
* it for you
* > Note: Techs without source handlers should call this between sources for `video`
* & `audio` tracks. You don't want to use them between tracks!
*
* @method clearTracks
* @param {Array|String} types type(s) of track lists to empty
* @param {string[]|string} types
* TrackList names to clear, valid names are `video`, `audio`, and
* `text`.
*/
clearTracks(types) {
types = [].concat(types);
@ -302,8 +376,6 @@ class Tech extends Component {
/**
* Remove any TextTracks added via addRemoteTextTrack that are
* flagged for automatic garbage collection
*
* @method cleanupAutoTextTracks
*/
cleanupAutoTextTracks() {
const list = this.autoRemoteTextTracks_ || [];
@ -317,20 +389,20 @@ class Tech extends Component {
}
/**
* Reset the tech. Removes all sources and resets readyState.
* Reset the tech, which will removes all sources and reset the internal readyState.
*
* @method reset
* @abstract
*/
reset() {}
/**
* When invoked without an argument, returns a MediaError object
* representing the current error state of the player or null if
* there is no error. When invoked with an argument, set the current
* error state of the player.
* @param {MediaError=} err Optional an error object
* @return {MediaError} the current error object or null
* @method error
* Get or set an error on the Tech.
*
* @param {MediaError} [err]
* Error to set on the Tech
*
* @return {MediaError|null}
* The current error object on the tech, or null if there isn't one.
*/
error(err) {
if (err !== undefined) {
@ -341,13 +413,14 @@ class Tech extends Component {
}
/**
* Return the time ranges that have been played through for the
* current source. This implementation is incomplete. It does not
* track the played time ranges, only whether the source has played
* at all or not.
* @return {TimeRangeObject} a single time range if this video has
* played or an empty set of ranges if not.
* @method played
* Returns the `TimeRange`s that have been played through for the current source.
*
* > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.
* It only checks wether the source has played at all or not.
*
* @return {TimeRange}
* - A single time range if this video has played
* - An empty set of ranges if not.
*/
played() {
if (this.hasStarted_) {
@ -357,24 +430,39 @@ class Tech extends Component {
}
/**
* Set current time
* Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was
* previously called.
*
* @method setCurrentTime
* @fires Tech#timeupdate
*/
setCurrentTime() {
// improve the accuracy of manual timeupdates
if (this.manualTimeUpdates) {
/**
* A manual `timeupdate` event.
*
* @event Tech#timeupdate
* @type {EventTarget~Event}
*/
this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
}
}
/**
* Initialize texttrack listeners
* Turn on listeners for {@link TextTrackList} events. This adds
* {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and
* `removetrack`.
*
* @method initTextTrackListeners
* @fires Tech#texttrackchange
*/
initTextTrackListeners() {
const textTrackListChanges = Fn.bind(this, function() {
/**
* Triggered when tracks are added or removed on the Tech {@link TextTrackList}
*
* @event Tech#texttrackchange
* @type {EventTarget~Event}
*/
this.trigger('texttrackchange');
});
@ -394,14 +482,29 @@ class Tech extends Component {
}
/**
* Initialize audio and video track listeners
* Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events.
* This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`.
*
* @method initTrackListeners
* @fires Tech#audiotrackchange
* @fires Tech#videotrackchange
*/
initTrackListeners() {
const trackTypes = ['video', 'audio'];
trackTypes.forEach((type) => {
/**
* Triggered when tracks are added or removed on the Tech {@link AudioTrackList}
*
* @event Tech#audiotrackchange
* @type {EventTarget~Event}
*/
/**
* Triggered when tracks are added or removed on the Tech {@link VideoTrackList}
*
* @event Tech#videotrackchange
* @type {EventTarget~Event}
*/
const trackListChanges = () => {
this.trigger(`${type}trackchange`);
};
@ -419,9 +522,11 @@ class Tech extends Component {
}
/**
* Add vtt.js if necessary
* Emulate TextTracks using vtt.js if necessary
*
* @private
* @fires Tech#vttjsloaded
* @fires Tech#vttjserror
* @fires Tech#texttrackchange
*/
addWebVttScript_() {
if (!window.WebVTT && this.el().parentNode !== null && this.el().parentNode !== undefined) {
@ -429,9 +534,21 @@ class Tech extends Component {
script.src = this.options_['vtt.js'] || '../node_modules/videojs-vtt.js/dist/vtt.js';
script.onload = () => {
/**
* Fired when vtt.js is loaded.
*
* @event Tech#vttjsloaded
* @type {EventTarget~Event}
*/
this.trigger('vttjsloaded');
};
script.onerror = () => {
/**
* Fired when vtt.js was not loaded due to an error
*
* @event Tech#vttjsloaded
* @type {EventTarget~Event}
*/
this.trigger('vttjserror');
};
this.on('dispose', () => {
@ -493,10 +610,10 @@ class Tech extends Component {
}
/**
* Get videotracks
* Get the `Tech`s {@link VideoTrackList}.
*
* @returns {VideoTrackList}
* @method videoTracks
* @return {VideoTrackList}
* The video track list that the Tech is currently using.
*/
videoTracks() {
this.videoTracks_ = this.videoTracks_ || new VideoTrackList();
@ -504,27 +621,21 @@ class Tech extends Component {
}
/**
* Get audiotracklist
* Get the `Tech`s {@link AudioTrackList}.
*
* @returns {AudioTrackList}
* @method audioTracks
* @return {AudioTrackList}
* The audio track list that the Tech is currently using.
*/
audioTracks() {
this.audioTracks_ = this.audioTracks_ || new AudioTrackList();
return this.audioTracks_;
}
/*
* Provide default methods for text tracks.
*
* Html5 tech overrides these.
*/
/**
* Get texttracks
* Get the `Tech`s {@link TextTrackList}.
*
* @returns {TextTrackList}
* @method textTracks
* @return {TextTrackList}
* The text track list that the Tech is currently using.
*/
textTracks() {
this.textTracks_ = this.textTracks_ || new TextTrackList();
@ -532,10 +643,11 @@ class Tech extends Component {
}
/**
* Get remote texttracks
* Get the `Tech`s remote {@link TextTrackList}, which is created from elements
* that were added to the DOM.
*
* @returns {TextTrackList}
* @method remoteTextTracks
* @return {TextTrackList}
* The remote text track list that the Tech is currently using.
*/
remoteTextTracks() {
this.remoteTextTracks_ = this.remoteTextTracks_ || new TextTrackList();
@ -543,10 +655,11 @@ class Tech extends Component {
}
/**
* Get remote htmltrackelements
* Get The `Tech`s {HTMLTrackElementList}, which are the elements in the DOM that are
* being used as TextTracks.
*
* @returns {HTMLTrackElementList}
* @method remoteTextTrackEls
* @return {HTMLTrackElementList}
* The current HTML track elements that exist for the tech.
*/
remoteTextTrackEls() {
this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new HTMLTrackElementList();
@ -554,14 +667,19 @@ class Tech extends Component {
}
/**
* Creates and returns a remote text track object
* Create and returns a remote {@link TextTrack} object.
*
* @param {String} kind Text track kind (subtitles, captions, descriptions
* chapters and metadata)
* @param {String=} label Label to identify the text track
* @param {String=} language Two letter language abbreviation
* @return {TextTrackObject}
* @method addTextTrack
* @param {string} kind
* `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
*
* @param {string} [label]
* Label to identify the text track
*
* @param {string} [language]
* Two letter language abbreviation
*
* @return {TextTrack}
* The TextTrack that gets created.
*/
addTextTrack(kind, label, language) {
if (!kind) {
@ -577,8 +695,20 @@ class Tech extends Component {
* This is intended to be overridden by classes that inherit from
* Tech in order to create native or custom TextTracks.
*
* @param {Object} options The object should contain values for
* kind, language, label and src (location of the WebVTT file)
* @param {Object} options
* The object should contain the options to initialize the TextTrack with.
*
* @param {string} [options.kind]
* `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
*
* @param {string} [options.label].
* Label to identify the text track
*
* @param {string} [options.language]
* Two letter language abbreviation.
*
* @return {HTMLTrackElement}
* The track element that gets created.
*/
createRemoteTextTrack(options) {
const track = mergeOptions(options, {
@ -591,14 +721,22 @@ class Tech extends Component {
/**
* Creates a remote text track object and returns an html track element.
*
* @param {Object} options The object should contain values for
* kind, language, label, and src (location of the WebVTT file)
* @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be
* automatically removed from the video element whenever the source changes
* @return {HTMLTrackElement} An Html Track Element.
* This can be an emulated {@link HTMLTrackElement} or a native one.
* @deprecated The default value of the "manualCleanup" parameter will default
* to "false" in upcoming versions of Video.js
* > Note: This can be an emulated {@link HTMLTrackElement} or a native one.
*
* @param {Object} options
* See {@link Tech#createRemoteTextTrack} for more detailed properties.
*
* @param {boolean} [manualCleanup=true]
* - When false: the TextTrack will be automatically removed from the video
* element whenever the source changes
* - When True: The TextTrack will have to be cleaned up manually
*
* @return {HTMLTrackElement}
* An Html Track Element.
*
* @deprecated The default functionality for this function will be equivalent
* to "manualCleanup=false" in the future. The manualCleanup parameter will
* also be removed.
*/
addRemoteTextTrack(options = {}, manualCleanup) {
const htmlTrackElement = this.createRemoteTextTrack(options);
@ -622,10 +760,10 @@ class Tech extends Component {
}
/**
* Remove remote texttrack
* Remove a remote text track from the remote `TextTrackList`.
*
* @param {TextTrackObject} track Texttrack to remove
* @method removeRemoteTextTrack
* @param {TextTrack} track
* `TextTrack` to remove from the `TextTrackList`
*/
removeRemoteTextTrack(track) {
const trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
@ -637,22 +775,27 @@ class Tech extends Component {
}
/**
* Provide a default setPoster method for techs
* Poster support for techs should be optional, so we don't want techs to
* break if they don't have a way to set a poster.
* A method to set a poster from a `Tech`.
*
* @method setPoster
* @abstract
*/
setPoster() {}
/*
* Check if the tech can support the given type
* Check if the tech can support the given mime-type.
*
* The base tech does not support any type, but source handlers might
* overwrite this.
*
* @param {String} type The mimetype to check
* @return {String} 'probably', 'maybe', or '' (empty string)
* @param {string} type
* The mimetype to check for support
*
* @return {string}
* 'probably', 'maybe', or empty string
*
* @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType}
*
* @abstract
*/
canPlayType() {
return '';
@ -662,8 +805,13 @@ class Tech extends Component {
* Return whether the argument is a Tech or not.
* Can be passed either a Class like `Html5` or a instance like `player.tech_`
*
* @param {Object} component An item to check
* @return {Boolean} Whether it is a tech or not
* @param {Object} component
* The item to check
*
* @return {boolean}
* Whether it is a tech or not
* - True if it is a tech
* - False if it is not
*/
static isTech(component) {
return component.prototype instanceof Tech ||
@ -672,12 +820,13 @@ class Tech extends Component {
}
/**
* Registers a Tech
* Registers a `Tech` into a shared list for videojs.
*
* @param {String} name Name of the Tech to register
* @param {Object} tech The tech to register
* @static
* @method registerComponent
* @param {string} name
* Name of the `Tech` to register.
*
* @param {Object} tech
* The `Tech` class to register.
*/
static registerTech(name, tech) {
if (!Tech.techs_) {
@ -693,12 +842,13 @@ class Tech extends Component {
}
/**
* Gets a component by name
* Get a `Tech` from the shared list by name.
*
* @param {String} name Name of the component to get
* @return {Component}
* @static
* @method getComponent
* @param {string} name
* Name of the component to get
*
* @return {Tech|undefined}
* The `Tech` or undefined if there was no tech with the name requsted.
*/
static getTech(name) {
if (Tech.techs_ && Tech.techs_[name]) {
@ -713,7 +863,7 @@ class Tech extends Component {
}
/**
* List of associated text tracks
* List of associated text tracks.
*
* @type {TextTrackList}
* @private
@ -721,7 +871,7 @@ class Tech extends Component {
Tech.prototype.textTracks_; // eslint-disable-line
/**
* List of associated audio tracks
* List of associated audio tracks.
*
* @type {AudioTrackList}
* @private
@ -729,43 +879,95 @@ Tech.prototype.textTracks_; // eslint-disable-line
Tech.prototype.audioTracks_; // eslint-disable-line
/**
* List of associated video tracks
* List of associated video tracks.
*
* @type {VideoTrackList}
* @private
*/
Tech.prototype.videoTracks_; // eslint-disable-line
/**
* Boolean indicating wether the `Tech` supports volume control.
*
* @type {boolean}
* @default
*/
Tech.prototype.featuresVolumeControl = true;
// Resizing plugins using request fullscreen reloads the plugin
/**
* Boolean indicating wether the `Tech` support fullscreen resize control.
* Resizing plugins using request fullscreen reloads the plugin
*
* @type {boolean}
* @default
*/
Tech.prototype.featuresFullscreenResize = false;
/**
* Boolean indicating wether the `Tech` supports changing the speed at which the video
* plays. Examples:
* - Set player to play 2x (twice) as fast
* - Set player to play 0.5x (half) as fast
*
* @type {boolean}
* @default
*/
Tech.prototype.featuresPlaybackRate = false;
// Optional events that we can manually mimic with timers
// currently not triggered by video-js-swf
/**
* Boolean indicating wether the `Tech` supports the `progress` event. This is currently
* not triggered by video-js-swf. This will be used to determine if
* {@link Tech#manualProgressOn} should be called.
*
* @type {boolean}
* @default
*/
Tech.prototype.featuresProgressEvents = false;
/**
* Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently
* not triggered by video-js-swf. This will be used to determine if
* {@link Tech#manualTimeUpdates} should be called.
*
* @type {boolean}
* @default
*/
Tech.prototype.featuresTimeupdateEvents = false;
/**
* Boolean indicating wether the `Tech` supports the native `TextTrack`s.
* This will help us integrate with native `TextTrack`s if the browser supports them.
*
* @type {boolean}
* @default
*/
Tech.prototype.featuresNativeTextTracks = false;
/**
* A functional mixin for techs that want to use the Source Handler pattern.
* Source handlers are scripts for handling specific formats.
* The source handler pattern is used for adaptive formats (HLS, DASH) that
* manually load video data and feed it into a Source Buffer (Media Source Extensions)
*
* ##### EXAMPLE:
* ```js
* Tech.withSourceHandlers.call(MyTech);
* ```
*
* Tech.withSourceHandlers(MyTech);
* @param {Tech} _Tech
* The tech to add source handler functions to.
*
* @mixes Tech~SourceHandlerAdditions
*/
Tech.withSourceHandlers = function(_Tech) {
/**
* Register a source handler
* Source handlers are scripts for handling specific formats.
* The source handler pattern is used for adaptive formats (HLS, DASH) that
* manually load video data and feed it into a Source Buffer (Media Source Extensions)
* @param {Function} handler The source handler
* @param {Number} index The index to register the handler among existing handlers
*
* @param {Function} handler
* The source handler class
*
* @param {number} [index]
* Register it at the following index
*/
_Tech.registerSourceHandler = function(handler, index) {
let handlers = _Tech.sourceHandlers;
@ -783,9 +985,14 @@ Tech.withSourceHandlers = function(_Tech) {
};
/**
* Check if the tech can support the given type
* @param {String} type The mimetype to check
* @return {String} 'probably', 'maybe', or '' (empty string)
* Check if the tech can support the given type. Also checks the
* Techs sourceHandlers.
*
* @param {string} type
* The mimetype to check.
*
* @return {string}
* 'probably', 'maybe', or '' (empty string)
*/
_Tech.canPlayType = function(type) {
const handlers = _Tech.sourceHandlers || [];
@ -803,12 +1010,19 @@ Tech.withSourceHandlers = function(_Tech) {
};
/**
* Return the first source handler that supports the source
* Returns the first source handler that supports the source.
*
* TODO: Answer question: should 'probably' be prioritized over 'maybe'
* @param {Object} source The source object
* @param {Object} options The options passed to the tech
* @returns {Object} The first source handler that supports the source
* @returns {null} Null if no source handler is found
*
* @param {Tech~SourceObject} source
* The source object
*
* @param {Object} options
* The options passed to the tech
*
* @return {SourceHandler|null}
* The first source handler that supports the source or null if
* no SourceHandler supports the source
*/
_Tech.selectSourceHandler = function(source, options) {
const handlers = _Tech.sourceHandlers || [];
@ -826,10 +1040,16 @@ Tech.withSourceHandlers = function(_Tech) {
};
/**
* Check if the tech can support the given source
* @param {Object} srcObj The source object
* @param {Object} options The options passed to the tech
* @return {String} 'probably', 'maybe', or '' (empty string)
* Check if the tech can support the given source.
*
* @param {Tech~SourceObject} srcObj
* The source object
*
* @param {Object} options
* The options passed to the tech
*
* @return {string}
* 'probably', 'maybe', or '' (empty string)
*/
_Tech.canPlaySource = function(srcObj, options) {
const sh = _Tech.selectSourceHandler(srcObj, options);
@ -850,6 +1070,20 @@ Tech.withSourceHandlers = function(_Tech) {
'duration'
];
/**
* A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable
* function if it exists, with a fallback to the Techs seekable function.
*
* @method _Tech.seekable
*/
/**
* A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration
* function if it exists, otherwise it will fallback to the techs duration function.
*
* @method _Tech.duration
*/
deferrable.forEach(function(fnName) {
const originalFn = this[fnName];
@ -869,8 +1103,12 @@ Tech.withSourceHandlers = function(_Tech) {
* Create a function for setting the source using a source object
* and source handlers.
* Should never be called unless a source handler was found.
* @param {Object} source A source object with src and type keys
* @return {Tech} self
*
* @param {Tech~SourceObject} source
* A source object with src and type keys
*
* @return {Tech}
* Returns itself; this method is chainable
*/
_Tech.prototype.setSource = function(source) {
let sh = _Tech.selectSourceHandler(source, this.options_);
@ -905,19 +1143,30 @@ Tech.withSourceHandlers = function(_Tech) {
return this;
};
// On the first loadstart after setSource
/**
* Called once for the first loadstart of a video.
*
* @listens Tech#loadstart
*/
_Tech.prototype.firstLoadStartListener_ = function() {
this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
};
// On successive loadstarts when setSource has not been called again
/**
* Called after the first loadstart for a video occurs.
*
* @listens Tech#loadstart
*/
_Tech.prototype.successiveLoadStartListener_ = function() {
this.disposeSourceHandler();
this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
};
/*
* Clean up any existing source handler
/**
* Clean up any existing SourceHandlers and listeners when the Tech is disposed.
*
* @listens Tech#dispose
*/
_Tech.prototype.disposeSourceHandler = function() {
// if we have a source and get another one
@ -947,6 +1196,7 @@ Tech.withSourceHandlers = function(_Tech) {
Component.registerComponent('Tech', Tech);
// Old name for Tech
// @deprecated
Component.registerComponent('MediaTechController', Tech);
Tech.registerTech('Tech', Tech);
export default Tech;