-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tech 2.0 #2057
Tech 2.0 #2057
Changes from 6 commits
6576e4e
ae25b8f
34f90bb
537907e
005aa9d
11bbb7b
19d19f8
358880b
539c660
d28137a
0147fc9
779354c
56d22ee
1e47782
6abec67
54db3dd
cbc0605
6af5009
f815c23
6e803e5
693eab4
d699417
0b51928
ccf0308
a8062ed
5fa8eea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -210,25 +210,7 @@ class Player extends Component { | |
} | ||
Lib.insertFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup. | ||
|
||
// The event listeners need to be added before the children are added | ||
// in the component init because the tech (loaded with mediaLoader) may | ||
// fire events, like loadstart, that these events need to capture. | ||
// Long term it might be better to expose a way to do this in component.init | ||
// like component.initEventListeners() that runs between el creation and | ||
// adding children | ||
this.el_ = el; | ||
this.on('loadstart', this.onLoadStart); | ||
this.on('waiting', this.onWaiting); | ||
this.on(['canplay', 'canplaythrough', 'playing', 'ended'], this.onWaitEnd); | ||
this.on('seeking', this.onSeeking); | ||
this.on('seeked', this.onSeeked); | ||
this.on('ended', this.onEnded); | ||
this.on('play', this.onPlay); | ||
this.on('firstplay', this.onFirstPlay); | ||
this.on('pause', this.onPause); | ||
this.on('progress', this.onProgress); | ||
this.on('durationchange', this.onDurationChange); | ||
this.on('fullscreenchange', this.onFullscreenChange); | ||
|
||
return el; | ||
} | ||
|
@@ -276,6 +258,38 @@ class Player extends Component { | |
let techComponent = Component.getComponent(techName); | ||
this.tech = new techComponent(this, techOptions); | ||
|
||
// Listen to every HTML5 events and trigger them back on the player for the plugins | ||
this.on(this.tech, 'loadstart', this.onTechLoadStart); | ||
this.on(this.tech, 'waiting', this.onTechWaiting); | ||
this.on(this.tech, 'canplay', this.onTechCanPlay); | ||
this.on(this.tech, 'canplaythrough', this.onTechCanPlayThrough); | ||
this.on(this.tech, 'playing', this.onTechPlaying); | ||
this.on(this.tech, 'ended', this.onTechEnded); | ||
this.on(this.tech, 'seeking', this.onTechSeeking); | ||
this.on(this.tech, 'seeked', this.onTechSeeked); | ||
this.on(this.tech, 'ended', this.onTechEnded); | ||
this.on(this.tech, 'play', this.onTechPlay); | ||
this.on(this.tech, 'firstplay', this.onTechFirstPlay); | ||
this.on(this.tech, 'pause', this.onTechPause); | ||
this.on(this.tech, 'progress', this.onTechProgress); | ||
this.on(this.tech, 'durationchange', this.onTechDurationChange); | ||
this.on(this.tech, 'fullscreenchange', this.onTechFullscreenChange); | ||
this.on(this.tech, 'error', this.onTechError); | ||
this.on(this.tech, 'suspend', this.onTechSuspend); | ||
this.on(this.tech, 'abort', this.onTechAbort); | ||
this.on(this.tech, 'emptied', this.onTechEmptied); | ||
this.on(this.tech, 'stalled', this.onTechStalled); | ||
this.on(this.tech, 'loadedmetadata', this.onTechLoadedMetaData); | ||
this.on(this.tech, 'loadeddata', this.onTechLoadedData); | ||
this.on(this.tech, 'timeupdate', this.onTechTimeUpdate); | ||
this.on(this.tech, 'ratechange', this.onTechRateChange); | ||
this.on(this.tech, 'volumechange', this.onTechVolumeChange); | ||
|
||
// Add the tech element in the DOM if it was not already there | ||
if (this.tech.el().parentNode != this.el()) { | ||
Lib.insertFirst(this.tech.el(), this.el()); | ||
} | ||
|
||
this.tech.ready(techReady); | ||
} | ||
|
||
|
@@ -291,7 +305,7 @@ class Player extends Component { | |
* Fired when the user agent begins looking for media data | ||
* @event loadstart | ||
*/ | ||
onLoadStart() { | ||
onTechLoadStart() { | ||
// TODO: Update to use `emptied` event instead. See #1277. | ||
|
||
this.removeClass('vjs-ended'); | ||
|
@@ -303,10 +317,12 @@ class Player extends Component { | |
// The firstplay event relies on both the play and loadstart events | ||
// which can happen in any order for a new source | ||
if (!this.paused()) { | ||
this.trigger('loadstart'); | ||
this.trigger('firstplay'); | ||
} else { | ||
// reset the hasStarted state | ||
this.hasStarted(false); | ||
this.trigger('loadstart'); | ||
} | ||
} | ||
|
||
|
@@ -332,47 +348,73 @@ class Player extends Component { | |
* Fired whenever the media begins or resumes playback | ||
* @event play | ||
*/ | ||
onPlay() { | ||
onTechPlay() { | ||
this.removeClass('vjs-ended'); | ||
this.removeClass('vjs-paused'); | ||
this.addClass('vjs-playing'); | ||
|
||
// hide the poster when the user hits play | ||
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play | ||
this.hasStarted(true); | ||
|
||
this.trigger('play'); | ||
} | ||
|
||
/** | ||
* Fired whenever the media begins waiting | ||
* @event waiting | ||
*/ | ||
onWaiting() { | ||
onTechWaiting() { | ||
this.addClass('vjs-waiting'); | ||
this.trigger('waiting'); | ||
} | ||
|
||
/** | ||
* A handler for events that signal that waiting has ended | ||
* which is not consistent between browsers. See #1351 | ||
* @private | ||
* @event canplay | ||
*/ | ||
onTechCanPlay() { | ||
this.removeClass('vjs-waiting'); | ||
this.trigger('canplay'); | ||
} | ||
|
||
/** | ||
* A handler for events that signal that waiting has ended | ||
* which is not consistent between browsers. See #1351 | ||
* @event canplaythrough | ||
*/ | ||
onTechCanPlayThrough() { | ||
this.removeClass('vjs-waiting'); | ||
this.trigger('canplaythrough'); | ||
} | ||
|
||
/** | ||
* A handler for events that signal that waiting has ended | ||
* which is not consistent between browsers. See #1351 | ||
* @event playing | ||
*/ | ||
onWaitEnd() { | ||
onTechPlaying() { | ||
this.removeClass('vjs-waiting'); | ||
this.trigger('playing'); | ||
} | ||
|
||
/** | ||
* Fired whenever the player is jumping to a new time | ||
* @event seeking | ||
*/ | ||
onSeeking() { | ||
onTechSeeking() { | ||
this.addClass('vjs-seeking'); | ||
this.trigger('seeking'); | ||
} | ||
|
||
/** | ||
* Fired when the player has finished jumping to a new time | ||
* @event seeked | ||
*/ | ||
onSeeked() { | ||
onTechSeeked() { | ||
this.removeClass('vjs-seeking'); | ||
this.trigger('seeked'); | ||
} | ||
|
||
/** | ||
|
@@ -384,29 +426,34 @@ class Player extends Component { | |
* | ||
* @event firstplay | ||
*/ | ||
onFirstPlay() { | ||
onTechFirstPlay() { | ||
//If the first starttime attribute is specified | ||
//then we will start at the given offset in seconds | ||
if(this.options_['starttime']){ | ||
this.currentTime(this.options_['starttime']); | ||
} | ||
|
||
this.addClass('vjs-has-started'); | ||
this.trigger('firstplay'); | ||
} | ||
|
||
/** | ||
* Fired whenever the media has been paused | ||
* @event pause | ||
*/ | ||
onPause() { | ||
onTechPause() { | ||
this.removeClass('vjs-playing'); | ||
this.addClass('vjs-paused'); | ||
this.trigger('pause'); | ||
} | ||
|
||
/** | ||
* Fired while the user agent is downloading media data | ||
* @event progress | ||
*/ | ||
onProgress() { | ||
onTechProgress() { | ||
this.trigger('progress'); | ||
|
||
// Add custom event for when source is finished downloading. | ||
if (this.bufferedPercent() == 1) { | ||
this.trigger('loadedalldata'); | ||
|
@@ -417,21 +464,32 @@ class Player extends Component { | |
* Fired when the end of the media resource is reached (currentTime == duration) | ||
* @event ended | ||
*/ | ||
onEnded() { | ||
onTechEnded() { | ||
this.addClass('vjs-ended'); | ||
if (this.options_['loop']) { | ||
this.currentTime(0); | ||
this.play(); | ||
} else if (!this.paused()) { | ||
this.pause(); | ||
} | ||
|
||
this.trigger('ended'); | ||
} | ||
|
||
/** | ||
* Fired when the duration of the media resource is first known or changed | ||
* @event durationchange | ||
*/ | ||
onDurationChange() { | ||
onTechDurationChange() { | ||
this.updateDuration(); | ||
this.trigger('durationchange'); | ||
} | ||
|
||
/** | ||
* Update the duration of the player using the tech | ||
* @private | ||
*/ | ||
updateDuration() { | ||
// Allows for caching value instead of asking player each time. | ||
// We need to get the techGet response and check for a value so we don't | ||
// accidentally cause the stack to blow up. | ||
|
@@ -454,12 +512,95 @@ class Player extends Component { | |
* Fired when the player switches in or out of fullscreen mode | ||
* @event fullscreenchange | ||
*/ | ||
onFullscreenChange() { | ||
onTechFullscreenChange() { | ||
if (this.isFullscreen()) { | ||
this.addClass('vjs-fullscreen'); | ||
} else { | ||
this.removeClass('vjs-fullscreen'); | ||
} | ||
|
||
this.trigger('fullscreenchange'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be reverted since it's a player event. |
||
} | ||
|
||
/** | ||
* Fires when an error occurred during the loading of an audio/video | ||
* @event error | ||
*/ | ||
onTechError() { | ||
this.error(this.tech.error().code); | ||
this.trigger('error'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Calling |
||
} | ||
|
||
/** | ||
* Fires when the browser is intentionally not getting media data | ||
* @event suspend | ||
*/ | ||
onTechSuspend() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For these simple ones we could probably loop though a list of the events and create these dynamically. Though it is kind of nice to have an excuse to add the event jsdoc tag. |
||
this.trigger('suspend'); | ||
} | ||
|
||
/** | ||
* Fires when the loading of an audio/video is aborted | ||
* @event abort | ||
*/ | ||
onTechAbort() { | ||
this.trigger('abort'); | ||
} | ||
|
||
/** | ||
* Fires when the current playlist is empty | ||
* @event emptied | ||
*/ | ||
onTechEmptied() { | ||
this.trigger('emptied'); | ||
} | ||
|
||
/** | ||
* Fires when the browser is trying to get media data, but data is not available | ||
* @event stalled | ||
*/ | ||
onTechStalled() { | ||
this.trigger('stalled'); | ||
} | ||
|
||
/** | ||
* Fires when the browser has loaded meta data for the audio/video | ||
* @event loadedmetadata | ||
*/ | ||
onTechLoadedMetaData() { | ||
this.trigger('loadedmetadata'); | ||
} | ||
|
||
/** | ||
* Fires when the browser has loaded the current frame of the audio/video | ||
* @event loaddata | ||
*/ | ||
onTechLoadedData() { | ||
this.trigger('loadeddata'); | ||
} | ||
|
||
/** | ||
* Fires when the current playback position has changed | ||
* @event timeupdate | ||
*/ | ||
onTechTimeUpdate() { | ||
this.trigger('timeupdate'); | ||
} | ||
|
||
/** | ||
* Fires when the playing speed of the audio/video is changed | ||
* @event ratechange | ||
*/ | ||
onTechRateChange() { | ||
this.trigger('ratechange'); | ||
} | ||
|
||
/** | ||
* Fires when the volume has been changed | ||
* @event volumechange | ||
*/ | ||
onTechVolumeChange() { | ||
this.trigger('volumechange'); | ||
} | ||
|
||
/** | ||
|
@@ -605,7 +746,7 @@ class Player extends Component { | |
} | ||
|
||
if (this.cache_.duration === undefined) { | ||
this.onDurationChange(); | ||
this.updateDuration(); | ||
} | ||
|
||
return this.cache_.duration || 0; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fullscreenchange is actually a player event, not tech.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fullscreenchange listener could still be removed, now that you've added it to the player.