aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Potts <sam@potts.es>2018-05-19 16:49:31 +1000
committerGitHub <noreply@github.com>2018-05-19 16:49:31 +1000
commitf4858f0c62ec8ab4d217f13aae02c277e4ae061d (patch)
treea59808199cf851b4fdca8e0d8b3e097594d5dcd4
parent3ab2295fe7f77766d85c76fdefa3ecd8e10dd165 (diff)
parent121093ae7113cbd74d4202332a88d184c0049320 (diff)
downloadplyr-f4858f0c62ec8ab4d217f13aae02c277e4ae061d.tar.lz
plyr-f4858f0c62ec8ab4d217f13aae02c277e4ae061d.tar.xz
plyr-f4858f0c62ec8ab4d217f13aae02c277e4ae061d.zip
Merge pull request #959 from friday/876
Youtube and vimeo fixes
-rw-r--r--src/js/controls.js6
-rw-r--r--src/js/listeners.js4
-rw-r--r--src/js/plugins/vimeo.js67
-rw-r--r--src/js/plugins/youtube.js89
4 files changed, 91 insertions, 75 deletions
diff --git a/src/js/controls.js b/src/js/controls.js
index 3f720925..d266ed6b 100644
--- a/src/js/controls.js
+++ b/src/js/controls.js
@@ -481,6 +481,7 @@ const controls = {
// Video playing
case 'timeupdate':
case 'seeking':
+ case 'seeked':
value = utils.getPercentage(this.currentTime, this.duration);
// Set seek range value only if it's a 'natural' time event
@@ -601,9 +602,10 @@ const controls = {
controls.updateProgress.call(this, event);
},
- // Show the duration on metadataloaded
+ // Show the duration on metadataloaded or durationchange events
durationUpdate() {
- if (!this.supported.ui) {
+ // Bail if no ui or durationchange event triggered after playing/seek when invertTime is false
+ if (!this.supported.ui || (!this.config.invertTime && this.currentTime)) {
return;
}
diff --git a/src/js/listeners.js b/src/js/listeners.js
index d5748806..99eeade4 100644
--- a/src/js/listeners.js
+++ b/src/js/listeners.js
@@ -273,7 +273,7 @@ class Listeners {
// Listen for media events
media() {
// Time change on media
- utils.on(this.player.media, 'timeupdate seeking', event => controls.timeUpdate.call(this.player, event));
+ utils.on(this.player.media, 'timeupdate seeking seeked', event => controls.timeUpdate.call(this.player, event));
// Display duration
utils.on(this.player.media, 'durationchange loadeddata loadedmetadata', event => controls.durationUpdate.call(this.player, event));
@@ -295,7 +295,7 @@ class Listeners {
});
// Check for buffer progress
- utils.on(this.player.media, 'progress playing', event => controls.updateProgress.call(this.player, event));
+ utils.on(this.player.media, 'progress playing seeking seeked', event => controls.updateProgress.call(this.player, event));
// Handle volume changes
utils.on(this.player.media, 'volumechange', event => controls.updateVolume.call(this.player, event));
diff --git a/src/js/plugins/vimeo.js b/src/js/plugins/vimeo.js
index 96b36781..46d4f3f9 100644
--- a/src/js/plugins/vimeo.js
+++ b/src/js/plugins/vimeo.js
@@ -7,6 +7,14 @@ import controls from './../controls';
import ui from './../ui';
import utils from './../utils';
+// Set playback state and trigger change (only on actual change)
+function assurePlaybackState(play) {
+ if (this.media.paused === play) {
+ this.media.paused = !play;
+ utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
+ }
+}
+
const vimeo = {
setup() {
// Add embed class for responsive
@@ -120,15 +128,13 @@ const vimeo = {
// Create a faux HTML5 API using the Vimeo API
player.media.play = () => {
- player.embed.play().then(() => {
- player.media.paused = false;
- });
+ assurePlaybackState.call(player, true);
+ return player.embed.play();
};
player.media.pause = () => {
- player.embed.pause().then(() => {
- player.media.paused = true;
- });
+ assurePlaybackState.call(player, false);
+ return player.embed.pause();
};
player.media.stop = () => {
@@ -143,25 +149,26 @@ const vimeo = {
return currentTime;
},
set(time) {
- // Get current paused state
- // Vimeo will automatically play on seek
- const { paused } = player.media;
-
- // Set seeking flag
- player.media.seeking = true;
-
- // Trigger seeking
- utils.dispatchEvent.call(player, player.media, 'seeking');
-
- // Seek after events
- player.embed.setCurrentTime(time).catch(() => {
- // Do nothing
- });
-
- // Restore pause state
- if (paused) {
- player.pause();
- }
+ // Vimeo will automatically play on seek if the video hasn't been played before
+
+ // Get current paused state and volume etc
+ const { embed, media, paused, volume } = player;
+
+ // Set seeking state and trigger event
+ media.seeking = true;
+ utils.dispatchEvent.call(player, media, 'seeking');
+
+ // If paused, mute until seek is complete
+ Promise.resolve(paused && embed.setVolume(0))
+ // Seek
+ .then(() => embed.setCurrentTime(time))
+ // Restore paused
+ .then(() => paused && embed.pause())
+ // Restore volume
+ .then(() => paused && embed.setVolume(volume))
+ .catch(() => {
+ // Do nothing
+ });
},
});
@@ -315,17 +322,12 @@ const vimeo = {
});
player.embed.on('play', () => {
- // Only fire play if paused before
- if (player.media.paused) {
- utils.dispatchEvent.call(player, player.media, 'play');
- }
- player.media.paused = false;
+ assurePlaybackState.call(player, true);
utils.dispatchEvent.call(player, player.media, 'playing');
});
player.embed.on('pause', () => {
- player.media.paused = true;
- utils.dispatchEvent.call(player, player.media, 'pause');
+ assurePlaybackState.call(player, false);
});
player.embed.on('timeupdate', data => {
@@ -356,7 +358,6 @@ const vimeo = {
player.embed.on('seeked', () => {
player.media.seeking = false;
utils.dispatchEvent.call(player, player.media, 'seeked');
- utils.dispatchEvent.call(player, player.media, 'play');
});
player.embed.on('ended', () => {
diff --git a/src/js/plugins/youtube.js b/src/js/plugins/youtube.js
index 10283998..67b8093e 100644
--- a/src/js/plugins/youtube.js
+++ b/src/js/plugins/youtube.js
@@ -64,6 +64,14 @@ function mapQualityUnits(levels) {
return utils.dedupe(levels.map(level => mapQualityUnit(level)));
}
+// Set playback state and trigger change (only on actual change)
+function assurePlaybackState(play) {
+ if (this.media.paused === play) {
+ this.media.paused = !play;
+ utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
+ }
+}
+
const youtube = {
setup() {
// Add embed class for responsive
@@ -264,10 +272,12 @@ const youtube = {
// Create a faux HTML5 API using the YouTube API
player.media.play = () => {
+ assurePlaybackState.call(player, true);
instance.playVideo();
};
player.media.pause = () => {
+ assurePlaybackState.call(player, false);
instance.pauseVideo();
};
@@ -285,22 +295,17 @@ const youtube = {
return Number(instance.getCurrentTime());
},
set(time) {
- // Vimeo will automatically play on seek
- const { paused } = player.media;
+ // If paused, mute audio preventively (YouTube starts playing on seek if the video hasn't been played yet).
+ if (player.paused) {
+ player.embed.mute();
+ }
- // Set seeking flag
+ // Set seeking state and trigger event
player.media.seeking = true;
-
- // Trigger seeking
utils.dispatchEvent.call(player, player.media, 'seeking');
// Seek after events sent
instance.seekTo(time);
-
- // Restore pause state
- if (paused) {
- player.pause();
- }
},
});
@@ -419,6 +424,17 @@ const youtube = {
// Reset timer
clearInterval(player.timers.playing);
+ const seeked = player.media.seeking && [
+ 1,
+ 2,
+ ].includes(event.data);
+
+ if (seeked) {
+ // Unset seeking and fire seeked event
+ player.media.seeking = false;
+ utils.dispatchEvent.call(player, player.media, 'seeked');
+ }
+
// Handle events
// -1 Unstarted
// 0 Ended
@@ -438,7 +454,7 @@ const youtube = {
break;
case 0:
- player.media.paused = true;
+ assurePlaybackState.call(player, false);
// YouTube doesn't support loop for a single video, so mimick it.
if (player.media.loop) {
@@ -452,42 +468,39 @@ const youtube = {
break;
case 1:
- // If we were seeking, fire seeked event
- if (player.media.seeking) {
- utils.dispatchEvent.call(player, player.media, 'seeked');
- }
- player.media.seeking = false;
-
- // Only fire play if paused before
+ // Restore paused state (YouTube starts playing on seek if the video hasn't been played yet)
if (player.media.paused) {
- utils.dispatchEvent.call(player, player.media, 'play');
- }
- player.media.paused = false;
+ player.media.pause();
+ } else {
+ assurePlaybackState.call(player, true);
- utils.dispatchEvent.call(player, player.media, 'playing');
+ utils.dispatchEvent.call(player, player.media, 'playing');
- // Poll to get playback progress
- player.timers.playing = setInterval(() => {
- utils.dispatchEvent.call(player, player.media, 'timeupdate');
- }, 50);
+ // Poll to get playback progress
+ player.timers.playing = setInterval(() => {
+ utils.dispatchEvent.call(player, player.media, 'timeupdate');
+ }, 50);
- // Check duration again due to YouTube bug
- // https://github.com/sampotts/plyr/issues/374
- // https://code.google.com/p/gdata-issues/issues/detail?id=8690
- if (player.media.duration !== instance.getDuration()) {
- player.media.duration = instance.getDuration();
- utils.dispatchEvent.call(player, player.media, 'durationchange');
- }
+ // Check duration again due to YouTube bug
+ // https://github.com/sampotts/plyr/issues/374
+ // https://code.google.com/p/gdata-issues/issues/detail?id=8690
+ if (player.media.duration !== instance.getDuration()) {
+ player.media.duration = instance.getDuration();
+ utils.dispatchEvent.call(player, player.media, 'durationchange');
+ }
- // Get quality
- controls.setQualityMenu.call(player, mapQualityUnits(instance.getAvailableQualityLevels()));
+ // Get quality
+ controls.setQualityMenu.call(player, mapQualityUnits(instance.getAvailableQualityLevels()));
+ }
break;
case 2:
- player.media.paused = true;
-
- utils.dispatchEvent.call(player, player.media, 'pause');
+ // Restore audio (YouTube starts playing on seek if the video hasn't been played yet)
+ if (!player.muted) {
+ player.embed.unMute();
+ }
+ assurePlaybackState.call(player, false);
break;