aboutsummaryrefslogtreecommitdiffstats
path: root/src/js/plyr.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/plyr.js')
-rw-r--r--src/js/plyr.js132
1 files changed, 103 insertions, 29 deletions
diff --git a/src/js/plyr.js b/src/js/plyr.js
index 0d3d1674..83897cab 100644
--- a/src/js/plyr.js
+++ b/src/js/plyr.js
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr
-// plyr.js v3.5.2
+// plyr.js v3.5.3
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
@@ -25,7 +25,9 @@ import { createElement, hasClass, removeElement, replaceElement, toggleClass, wr
import { off, on, once, triggerEvent, unbindListeners } from './utils/events';
import is from './utils/is';
import loadSprite from './utils/loadSprite';
+import { clamp } from './utils/numbers';
import { cloneDeep, extend } from './utils/objects';
+import { getAspectRatio, reduceAspectRatio, setAspectRatio, validateRatio } from './utils/style';
import { parseUrl } from './utils/urls';
// Private properties
@@ -149,7 +151,6 @@ class Plyr {
// Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube
const type = this.media.tagName.toLowerCase();
-
// Embed properties
let iframe = null;
let url = null;
@@ -301,8 +302,8 @@ class Plyr {
}
// Autoplay if required
- if (this.config.autoplay) {
- this.play();
+ if (this.isHTML5 && this.config.autoplay) {
+ setTimeout(() => this.play(), 10);
}
// Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
@@ -322,27 +323,27 @@ class Plyr {
* Types and provider helpers
*/
get isHTML5() {
- return Boolean(this.provider === providers.html5);
+ return this.provider === providers.html5;
}
get isEmbed() {
- return Boolean(this.isYouTube || this.isVimeo);
+ return this.isYouTube || this.isVimeo;
}
get isYouTube() {
- return Boolean(this.provider === providers.youtube);
+ return this.provider === providers.youtube;
}
get isVimeo() {
- return Boolean(this.provider === providers.vimeo);
+ return this.provider === providers.vimeo;
}
get isVideo() {
- return Boolean(this.type === types.video);
+ return this.type === types.video;
}
get isAudio() {
- return Boolean(this.type === types.audio);
+ return this.type === types.audio;
}
/**
@@ -512,7 +513,6 @@ class Plyr {
get duration() {
// Faux duration set via config
const fauxDuration = parseFloat(this.config.duration);
-
// Media duration can be NaN or Infinity before the media has loaded
const realDuration = (this.media || {}).duration;
const duration = !is.number(realDuration) || realDuration === Infinity ? 0 : realDuration;
@@ -660,24 +660,17 @@ class Plyr {
speed = this.config.speed.selected;
}
- // Set min/max
- if (speed < 0.1) {
- speed = 0.1;
- }
- if (speed > 2.0) {
- speed = 2.0;
- }
-
- if (!this.config.speed.options.includes(speed)) {
- this.debug.warn(`Unsupported speed (${speed})`);
- return;
- }
+ // Clamp to min/max
+ const { minimumSpeed: min, maximumSpeed: max } = this;
+ speed = clamp(speed, min, max);
// Update config
this.config.speed.selected = speed;
// Set media speed
- this.media.playbackRate = speed;
+ setTimeout(() => {
+ this.media.playbackRate = speed;
+ }, 0);
}
/**
@@ -688,6 +681,42 @@ class Plyr {
}
/**
+ * Get the minimum allowed speed
+ */
+ get minimumSpeed() {
+ if (this.isYouTube) {
+ // https://developers.google.com/youtube/iframe_api_reference#setPlaybackRate
+ return Math.min(...this.options.speed);
+ }
+
+ if (this.isVimeo) {
+ // https://github.com/vimeo/player.js/#setplaybackrateplaybackrate-number-promisenumber-rangeerrorerror
+ return 0.5;
+ }
+
+ // https://stackoverflow.com/a/32320020/1191319
+ return 0.0625;
+ }
+
+ /**
+ * Get the maximum allowed speed
+ */
+ get maximumSpeed() {
+ if (this.isYouTube) {
+ // https://developers.google.com/youtube/iframe_api_reference#setPlaybackRate
+ return Math.max(...this.options.speed);
+ }
+
+ if (this.isVimeo) {
+ // https://github.com/vimeo/player.js/#setplaybackrateplaybackrate-number-promisenumber-rangeerrorerror
+ return 2;
+ }
+
+ // https://stackoverflow.com/a/32320020/1191319
+ return 16;
+ }
+
+ /**
* Set playback quality
* Currently HTML5 & YouTube only
* @param {Number} input - Quality level
@@ -823,6 +852,19 @@ class Plyr {
}
/**
+ * Set the download URL
+ */
+ set download(input) {
+ if (!is.url(input)) {
+ return;
+ }
+
+ this.config.urls.download = input;
+
+ controls.setDownloadUrl.call(this);
+ }
+
+ /**
* Set the poster image for a video
* @param {String} input - the URL for the new poster image
*/
@@ -847,6 +889,38 @@ class Plyr {
}
/**
+ * Get the current aspect ratio in use
+ */
+ get ratio() {
+ if (!this.isVideo) {
+ return null;
+ }
+
+ const ratio = reduceAspectRatio(getAspectRatio.call(this));
+
+ return is.array(ratio) ? ratio.join(':') : ratio;
+ }
+
+ /**
+ * Set video aspect ratio
+ */
+ set ratio(input) {
+ if (!this.isVideo) {
+ this.debug.warn('Aspect ratio can only be set for video');
+ return;
+ }
+
+ if (!is.string(input) || !validateRatio(input)) {
+ this.debug.error(`Invalid aspect ratio specified (${input})`);
+ return;
+ }
+
+ this.config.ratio = input;
+
+ setAspectRatio.call(this);
+ }
+
+ /**
* Set the autoplay state
* @param {Boolean} input - Whether to autoplay or not
*/
@@ -969,10 +1043,8 @@ class Plyr {
if (this.supported.ui && !this.isAudio) {
// Get state before change
const isHidden = hasClass(this.elements.container, this.config.classNames.hideControls);
-
// Negate the argument if not undefined since adding the class to hides the controls
const force = typeof toggle === 'undefined' ? undefined : !toggle;
-
// Apply and get updated state
const hiding = toggleClass(this.elements.container, this.config.classNames.hideControls, force);
@@ -1088,11 +1160,13 @@ class Plyr {
// Stop playback
this.stop();
+ // Clear timeouts
+ clearTimeout(this.timers.loading);
+ clearTimeout(this.timers.controls);
+ clearTimeout(this.timers.resized);
+
// Provider specific stuff
if (this.isHTML5) {
- // Clear timeout
- clearTimeout(this.timers.loading);
-
// Restore native video controls
ui.toggleNativeControls.call(this, true);