Skip to content
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

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6576e4e
Tech triggers on himself instead of the player
eXon Apr 22, 2015
ae25b8f
Dispose should already remove the event listeners
eXon Apr 22, 2015
34f90bb
Listen for tech error + save tech instance in the DOM for flash
eXon Apr 23, 2015
537907e
Added missing HTML5 events the player needs to listen and trigger bac…
eXon Apr 23, 2015
005aa9d
Player is responsible for adding the tech DOM element inside himself
eXon Apr 23, 2015
11bbb7b
Improved the check if the tech is in the DOM
Apr 23, 2015
19d19f8
Fix the HTML5 video reuse
eXon Apr 24, 2015
358880b
Removed player references in the Tech base class
eXon Apr 24, 2015
539c660
Enforce triple equals with jshint
Apr 24, 2015
d28137a
Listen for user activity by the player instead of the tech + some qui…
Apr 24, 2015
0147fc9
Refactor html5 tech to remove player references
Apr 25, 2015
779354c
Refactor flash tech to remove player references
eXon Apr 25, 2015
56d22ee
Removed player from tech tech signature
eXon Apr 25, 2015
1e47782
Only set controls on the tech if not using native
eXon Apr 25, 2015
6abec67
Merge with upstream
eXon Apr 28, 2015
54db3dd
Fixed a bunch of unit tests (not done yet)
eXon Apr 29, 2015
cbc0605
Merge with upstream
eXon Apr 29, 2015
6af5009
Fixed all unit tests
eXon Apr 30, 2015
f815c23
Merge with upstream
eXon Apr 30, 2015
6e803e5
Merge branch 'feature/tech-2.0' of https://github.com/eXon/video.js i…
heff May 1, 2015
693eab4
Merge pull request #1 from heff/eXon-feature/tech-2.0
eXon May 1, 2015
d699417
Fixed the setControls call when using native controls
eXon May 2, 2015
0b51928
Removed unused variable
eXon May 2, 2015
ccf0308
Removed firefox fix because it has been fixed in the browser
eXon May 2, 2015
a8062ed
Making sure textTracks_ is set before it can be touched
eXon May 2, 2015
5fa8eea
Merge with upstream
eXon May 5, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 173 additions & 32 deletions src/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Copy link
Member

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.

Copy link
Member

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.

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);
}

Expand All @@ -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');
Expand All @@ -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');
}
}

Expand All @@ -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');
}

/**
Expand All @@ -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');
Expand All @@ -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.
Expand All @@ -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');
Copy link
Member

Choose a reason for hiding this comment

The 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');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling player.error(err) already triggers the player error event, so this would be triggering a second. We should probably be more consistent with how we handle states like this, so we're adding css classes and triggering events the same way for all of them. We don't need to figure that out in this PR specifically though.

}

/**
* Fires when the browser is intentionally not getting media data
* @event suspend
*/
onTechSuspend() {
Copy link
Member

Choose a reason for hiding this comment

The 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');
}

/**
Expand Down Expand Up @@ -605,7 +746,7 @@ class Player extends Component {
}

if (this.cache_.duration === undefined) {
this.onDurationChange();
this.updateDuration();
}

return this.cache_.duration || 0;
Expand Down
Loading