Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2fb922d73 | |||
| a6cc85c437 | |||
| d061be5d2b | |||
| dc2feedd79 | |||
| f8e4ba36e5 | |||
| f3d5389587 | |||
| d9ffb10b93 | |||
| 1186377b25 | |||
| 8616895e57 | |||
| 2cf5a22c85 | |||
| 763eb2df80 | |||
| 8bbf66a0fb | |||
| 676b46e4a7 | |||
| 82a119c67f | |||
| 6fd4389887 | |||
| 1e1a548459 | |||
| 8db9b53a8f | |||
| ba33fd8277 | |||
| 8071feda18 | |||
| a49b73cd01 | |||
| 8226493a9e | |||
| 38a8a0e8a1 | |||
| 6eeca8b5d1 | |||
| bf51ce4414 | |||
| 5ad614e251 | |||
| 93c890603d | |||
| 29fb4dfc2b | |||
| 7de9fd1d65 | |||
| 566c059832 | |||
| 0c9572f0a1 | |||
| c99607c85a | |||
| e2010bcd1a | |||
| e9f1b55f51 | |||
| 4f5152f526 | |||
| de9b53045a | |||
| df458c5e7a | |||
| e206554146 | |||
| e422806c44 | |||
| b6ddf144f4 | |||
| 86406ee59a | |||
| 81c5477f1d | |||
| ac64350a5f | |||
| 333619f1e3 |
+7
-12
@@ -5,8 +5,12 @@
|
||||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
"globals": { "Plyr": false, "jQuery": false },
|
||||
"globals": {
|
||||
"Plyr": false,
|
||||
"jQuery": false
|
||||
},
|
||||
"rules": {
|
||||
"import/no-cycle": 1,
|
||||
"no-const-assign": 1,
|
||||
"no-shadow": 0,
|
||||
"no-this-before-super": 1,
|
||||
@@ -21,17 +25,8 @@
|
||||
"eqeqeq": [2, "always"],
|
||||
"one-var": [2, "never"],
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
"no-restricted-globals": [
|
||||
"error",
|
||||
{
|
||||
"name": "event",
|
||||
"message": "Use local parameter instead."
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"message": "Use local parameter instead."
|
||||
}
|
||||
],
|
||||
"spaced-comment": [2, "always"],
|
||||
"no-restricted-globals": 2,
|
||||
"no-param-reassign": [2, { "props": false }]
|
||||
},
|
||||
"parserOptions": {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
<!---
|
||||
Please use this issue template as it makes replicating and fixing the issue easier!
|
||||
--->
|
||||
*Please _use this issue template_ as it makes replicating and fixing the issue easier for us. If you decide not to use it or you are vague your issue may be close instantly.*
|
||||
|
||||
### Expected behaviour
|
||||
|
||||
@@ -14,4 +12,4 @@ Please use this issue template as it makes replicating and fixing the issue easi
|
||||
- Version:
|
||||
|
||||
### Steps to reproduce
|
||||
-
|
||||
-
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
|
||||
### Checklist
|
||||
- [ ] Use `develop` as the base branch
|
||||
- [ ] Exclude the gulp build from the PR
|
||||
- [ ] Exclude the gulp build (`/dist` changes) from the PR
|
||||
- [ ] Test on [supported browsers](https://github.com/sampotts/plyr#browser-support)
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ aws.json
|
||||
!dist/blank.mp4
|
||||
index-*.html
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
package-lock.json
|
||||
*.webm
|
||||
/package-lock.json
|
||||
.idea/
|
||||
|
||||
.idea/
|
||||
@@ -2,3 +2,10 @@ demo
|
||||
.github
|
||||
.vscode
|
||||
*.code-workspace
|
||||
aws.json
|
||||
bundles.json
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
*.mp4
|
||||
*.webm
|
||||
!dist/blank.mp4
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"useTabs": false,
|
||||
"tabWidth": 4,
|
||||
"printWidth": 120,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
linters:
|
||||
eslint:
|
||||
files:
|
||||
ignore:
|
||||
- 'node_modules/*'
|
||||
+5
-4
@@ -1,7 +1,8 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 'lts/*'
|
||||
node_js: lts/*
|
||||
|
||||
script:
|
||||
- npm run lint
|
||||
- npm run build
|
||||
- bash .travis/prevent-base-master.sh
|
||||
- bash .travis/omit-dist.sh
|
||||
- npm run lint
|
||||
- npm run build
|
||||
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
if [ $TRAVIS_BRANCH == "develop" ] && $(git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qE "^(demo/)?dist/"); then
|
||||
echo 'Build output ("dist" and "demo/dist") not permitted in develop' >&2
|
||||
exit 1
|
||||
fi
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ] && [ $TRAVIS_BRANCH == "master" ] && $(git diff --name-only $TRAVIS_COMMIT_RANGE | grep -q "^src/"); then
|
||||
echo 'The base branch for pull requests must be "develop"' >&2
|
||||
exit 1
|
||||
fi
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"description": "A simple HTML5 media player using custom controls",
|
||||
"homepage": "http://plyr.io",
|
||||
"keywords": [
|
||||
"Audio",
|
||||
"Video",
|
||||
"HTML5 Audio",
|
||||
"HTML5 Video"
|
||||
],
|
||||
"authors": [
|
||||
"Sam Potts <sam@potts.es>"
|
||||
],
|
||||
"dependencies": {},
|
||||
"main": [
|
||||
"dist/plyr.css",
|
||||
"dist/plyr.js",
|
||||
"dist/plyr.svg",
|
||||
"src/less/plyr.less",
|
||||
"src/scss/plyr.scss",
|
||||
"src/js/plyr.js"
|
||||
],
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
".gitignore"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sampotts/plyr.git"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
@@ -1,3 +1,23 @@
|
||||
# v3.3.22
|
||||
|
||||
- Travis & CI improvements (thanks @friday)
|
||||
- Add navigator.languages fallback for iOS 9 (thanks @friday)
|
||||
|
||||
# v3.3.21
|
||||
|
||||
- Hide currentTime and progress for streams (thanks @mimse)
|
||||
- Fixed condition check (thanks @mimse)
|
||||
- Handle undefined this.player.elements.buttons.play (thanks @klassicd)
|
||||
- Fix captions.toggle() if there is no toggle button (thanks @friday)
|
||||
|
||||
# v3.3.20
|
||||
|
||||
- Fix for bug where controls wouldn't show on hover over YouTube video
|
||||
|
||||
# v3.3.19
|
||||
|
||||
- Remove `pointer-events: none` on embed `<iframe>` to comply with YouTube ToS
|
||||
|
||||
# 3.3.18
|
||||
|
||||
- Ads are now only supported on HTML5 videos as it violates terms of service for YouTube and Vimeo 😢
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
@@ -4137,6 +4137,7 @@ typeof navigator === "object" && (function () {
|
||||
tooltips: {
|
||||
controls: true
|
||||
},
|
||||
clickToPlay: false,
|
||||
/* controls: [
|
||||
'play-large',
|
||||
'restart',
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -57,6 +57,7 @@ import Raven from 'raven-js';
|
||||
tooltips: {
|
||||
controls: true,
|
||||
},
|
||||
clickToPlay: false,
|
||||
/* controls: [
|
||||
'play-large',
|
||||
'restart',
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+27
-10
@@ -1483,7 +1483,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
}
|
||||
|
||||
if ('class' in attributes) {
|
||||
if (attributes.class.includes(this.config.classNames.control)) {
|
||||
if (!attributes.class.includes(this.config.classNames.control)) {
|
||||
attributes.class += ' ' + this.config.classNames.control;
|
||||
}
|
||||
} else {
|
||||
@@ -1932,6 +1932,16 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If duration is the 2**32 (shaka), Infinity (HLS), DASH-IF (Number.MAX_SAFE_INTEGER || Number.MAX_VALUE) indicating live we hide the currentTime and progressbar.
|
||||
// https://github.com/video-dev/hls.js/blob/5820d29d3c4c8a46e8b75f1e3afa3e68c1a9a2db/src/controller/buffer-controller.js#L415
|
||||
// https://github.com/google/shaka-player/blob/4d889054631f4e1cf0fbd80ddd2b71887c02e232/lib/media/streaming_engine.js#L1062
|
||||
// https://github.com/Dash-Industry-Forum/dash.js/blob/69859f51b969645b234666800d4cb596d89c602d/src/dash/models/DashManifestModel.js#L338
|
||||
if (this.duration >= Math.pow(2, 32)) {
|
||||
toggleHidden(this.elements.display.currentTime, true);
|
||||
toggleHidden(this.elements.progress, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update ARIA values
|
||||
if (is.element(this.elements.inputs.seek)) {
|
||||
this.elements.inputs.seek.setAttribute('aria-valuemax', this.duration);
|
||||
@@ -2881,7 +2891,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// * active: The state preferred by user settings or config
|
||||
// * toggled: The real captions state
|
||||
|
||||
var languages = dedupe(Array.from(navigator.languages || navigator.userLanguage).map(function (language) {
|
||||
var languages = dedupe(Array.from(navigator.languages || navigator.language || navigator.userLanguage).map(function (language) {
|
||||
return language.split('-')[0];
|
||||
}));
|
||||
|
||||
@@ -3009,8 +3019,10 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Toggle state
|
||||
this.elements.buttons.captions.pressed = active;
|
||||
// Toggle button if it's enabled
|
||||
if (this.elements.buttons.captions) {
|
||||
this.elements.buttons.captions.pressed = active;
|
||||
}
|
||||
|
||||
// Add class hook
|
||||
toggleClass(this.elements.container, activeClass, active);
|
||||
@@ -4605,9 +4617,11 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
};
|
||||
|
||||
// Play/pause toggle
|
||||
Array.from(this.player.elements.buttons.play).forEach(function (button) {
|
||||
bind(button, 'click', _this4.player.togglePlay, 'play');
|
||||
});
|
||||
if (this.player.elements.buttons.play) {
|
||||
Array.from(this.player.elements.buttons.play).forEach(function (button) {
|
||||
bind(button, 'click', _this4.player.togglePlay, 'play');
|
||||
});
|
||||
}
|
||||
|
||||
// Pause
|
||||
bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
||||
@@ -6777,7 +6791,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
var params = {
|
||||
AV_PUBLISHERID: '58c25bb0073ef448b1087ad6',
|
||||
AV_CHANNELID: '5a0458dc28a06145e4519d21',
|
||||
AV_URL: location.hostname,
|
||||
AV_URL: window.location.hostname,
|
||||
cb: Date.now(),
|
||||
AV_WIDTH: 640,
|
||||
AV_HEIGHT: 480,
|
||||
@@ -7421,6 +7435,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
value: function on$$1(event, callback) {
|
||||
on.call(this, this.elements.container, event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add event listeners once
|
||||
* @param {string} event - Event type
|
||||
@@ -7432,6 +7447,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
value: function once$$1(event, callback) {
|
||||
once.call(this, this.elements.container, event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove event listeners
|
||||
* @param {string} event - Event type
|
||||
@@ -7707,8 +7723,9 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// Faux duration set via config
|
||||
var fauxDuration = parseFloat(this.config.duration);
|
||||
|
||||
// Media duration can be NaN before the media has loaded
|
||||
var duration = (this.media || {}).duration || 0;
|
||||
// Media duration can be NaN or Infinity before the media has loaded
|
||||
var realDuration = (this.media || {}).duration;
|
||||
var duration = !is.number(realDuration) || realDuration === Infinity ? 0 : realDuration;
|
||||
|
||||
// If config duration is funky, use regular duration
|
||||
return fauxDuration || duration;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+27
-10
@@ -6869,7 +6869,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
}
|
||||
|
||||
if ('class' in attributes) {
|
||||
if (attributes.class.includes(this.config.classNames.control)) {
|
||||
if (!attributes.class.includes(this.config.classNames.control)) {
|
||||
attributes.class += ' ' + this.config.classNames.control;
|
||||
}
|
||||
} else {
|
||||
@@ -7318,6 +7318,16 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If duration is the 2**32 (shaka), Infinity (HLS), DASH-IF (Number.MAX_SAFE_INTEGER || Number.MAX_VALUE) indicating live we hide the currentTime and progressbar.
|
||||
// https://github.com/video-dev/hls.js/blob/5820d29d3c4c8a46e8b75f1e3afa3e68c1a9a2db/src/controller/buffer-controller.js#L415
|
||||
// https://github.com/google/shaka-player/blob/4d889054631f4e1cf0fbd80ddd2b71887c02e232/lib/media/streaming_engine.js#L1062
|
||||
// https://github.com/Dash-Industry-Forum/dash.js/blob/69859f51b969645b234666800d4cb596d89c602d/src/dash/models/DashManifestModel.js#L338
|
||||
if (this.duration >= Math.pow(2, 32)) {
|
||||
toggleHidden(this.elements.display.currentTime, true);
|
||||
toggleHidden(this.elements.progress, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update ARIA values
|
||||
if (is$1.element(this.elements.inputs.seek)) {
|
||||
this.elements.inputs.seek.setAttribute('aria-valuemax', this.duration);
|
||||
@@ -8267,7 +8277,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// * active: The state preferred by user settings or config
|
||||
// * toggled: The real captions state
|
||||
|
||||
var languages = dedupe(Array.from(navigator.languages || navigator.userLanguage).map(function (language) {
|
||||
var languages = dedupe(Array.from(navigator.languages || navigator.language || navigator.userLanguage).map(function (language) {
|
||||
return language.split('-')[0];
|
||||
}));
|
||||
|
||||
@@ -8395,8 +8405,10 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Toggle state
|
||||
this.elements.buttons.captions.pressed = active;
|
||||
// Toggle button if it's enabled
|
||||
if (this.elements.buttons.captions) {
|
||||
this.elements.buttons.captions.pressed = active;
|
||||
}
|
||||
|
||||
// Add class hook
|
||||
toggleClass(this.elements.container, activeClass, active);
|
||||
@@ -9991,9 +10003,11 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
};
|
||||
|
||||
// Play/pause toggle
|
||||
Array.from(this.player.elements.buttons.play).forEach(function (button) {
|
||||
bind(button, 'click', _this4.player.togglePlay, 'play');
|
||||
});
|
||||
if (this.player.elements.buttons.play) {
|
||||
Array.from(this.player.elements.buttons.play).forEach(function (button) {
|
||||
bind(button, 'click', _this4.player.togglePlay, 'play');
|
||||
});
|
||||
}
|
||||
|
||||
// Pause
|
||||
bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
||||
@@ -12157,7 +12171,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
var params = {
|
||||
AV_PUBLISHERID: '58c25bb0073ef448b1087ad6',
|
||||
AV_CHANNELID: '5a0458dc28a06145e4519d21',
|
||||
AV_URL: location.hostname,
|
||||
AV_URL: window.location.hostname,
|
||||
cb: Date.now(),
|
||||
AV_WIDTH: 640,
|
||||
AV_HEIGHT: 480,
|
||||
@@ -12801,6 +12815,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
value: function on$$1(event, callback) {
|
||||
on.call(this, this.elements.container, event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add event listeners once
|
||||
* @param {string} event - Event type
|
||||
@@ -12812,6 +12827,7 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
value: function once$$1(event, callback) {
|
||||
once.call(this, this.elements.container, event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove event listeners
|
||||
* @param {string} event - Event type
|
||||
@@ -13087,8 +13103,9 @@ typeof navigator === "object" && (function (global, factory) {
|
||||
// Faux duration set via config
|
||||
var fauxDuration = parseFloat(this.config.duration);
|
||||
|
||||
// Media duration can be NaN before the media has loaded
|
||||
var duration = (this.media || {}).duration || 0;
|
||||
// Media duration can be NaN or Infinity before the media has loaded
|
||||
var realDuration = (this.media || {}).duration;
|
||||
var duration = !is$1.number(realDuration) || realDuration === Infinity ? 0 : realDuration;
|
||||
|
||||
// If config duration is funky, use regular duration
|
||||
return fauxDuration || duration;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+39
-27
@@ -1,26 +1,54 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "3.3.18",
|
||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"version": "3.3.22",
|
||||
"description":
|
||||
"A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"homepage": "https://plyr.io",
|
||||
"author": "Sam Potts <sam@potts.es>",
|
||||
"keywords": [
|
||||
"HTML5 Video",
|
||||
"HTML5 Audio",
|
||||
"Media Player",
|
||||
"DASH",
|
||||
"Shaka",
|
||||
"WordPress",
|
||||
"HLS"
|
||||
],
|
||||
"main": "./dist/plyr.js",
|
||||
"browser": "./dist/plyr.min.js",
|
||||
"sass": "./src/sass/plyr.scss",
|
||||
"style": "./dist/plyr.css",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sampotts/plyr.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sampotts/plyr/issues"
|
||||
},
|
||||
"directories": {
|
||||
"doc": "readme.md"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp build",
|
||||
"lint": "eslint src/js && npm run-script remark",
|
||||
"remark": "remark -f --use 'validate-links=repository:\"sampotts/plyr\"' '{,!(node_modules),.?**/}*.md'",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-eslint": "^8.2.3",
|
||||
"babel-eslint": "^8.2.6",
|
||||
"babel-plugin-external-helpers": "^6.22.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"del": "^3.0.0",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-config-airbnb-base": "^12.1.0",
|
||||
"eslint": "^5.1.0",
|
||||
"eslint-config-airbnb-base": "^13.0.0",
|
||||
"eslint-config-prettier": "^2.9.0",
|
||||
"eslint-plugin-import": "^2.12.0",
|
||||
"eslint-plugin-import": "^2.13.0",
|
||||
"git-branch": "^2.0.1",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^5.0.0",
|
||||
"gulp-better-rollup": "^3.2.1",
|
||||
"gulp-better-rollup": "^3.3.0",
|
||||
"gulp-clean-css": "^3.9.4",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-filter": "^5.1.0",
|
||||
@@ -38,9 +66,11 @@
|
||||
"gulp-uglify-es": "^1.0.4",
|
||||
"gulp-util": "^3.0.8",
|
||||
"postcss-custom-properties": "^7.0.0",
|
||||
"prettier-eslint": "^8.8.1",
|
||||
"prettier-eslint": "^8.8.2",
|
||||
"prettier-stylelint": "^0.4.2",
|
||||
"rollup-plugin-babel": "^3.0.4",
|
||||
"remark-cli": "^5.0.0",
|
||||
"remark-validate-links": "^7.0.0",
|
||||
"rollup-plugin-babel": "^3.0.7",
|
||||
"rollup-plugin-commonjs": "^9.1.3",
|
||||
"rollup-plugin-node-resolve": "^3.3.0",
|
||||
"run-sequence": "^2.2.1",
|
||||
@@ -52,24 +82,6 @@
|
||||
"stylelint-scss": "^3.1.3",
|
||||
"stylelint-selector-bem-pattern": "^2.0.0"
|
||||
},
|
||||
"keywords": ["HTML5 Video", "HTML5 Audio", "Media Player", "DASH", "Shaka", "WordPress", "HLS"],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/sampotts/plyr.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/sampotts/plyr/issues"
|
||||
},
|
||||
"directories": {
|
||||
"doc": "readme.md"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp build",
|
||||
"lint": "eslint src/js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Sam Potts <sam@potts.es>",
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"custom-event-polyfill": "^0.3.0",
|
||||
|
||||
@@ -16,7 +16,7 @@ A simple, lightweight, accessible and customizable HTML5, YouTube and Vimeo medi
|
||||
* **HTML Video & Audio** - support for both formats
|
||||
* **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback
|
||||
* **[Monetization](#ads)** - make money from your videos
|
||||
* **[Streaming](#streaming)** - support for hls.js, Shaka and dash.js streaming playback
|
||||
* **[Streaming](#try-plyr-online)** - support for hls.js, Shaka and dash.js streaming playback
|
||||
* **[API](#api)** - toggle playback, volume, seeking, and more through a standardized API
|
||||
* **[Events](#events)** - no messing around with Vimeo and YouTube APIs, all events are standardized across formats
|
||||
* **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes
|
||||
@@ -132,13 +132,13 @@ See [initialising](#initialising) for more information on advanced setups.
|
||||
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/3.3.18/plyr.js"></script>
|
||||
<script src="https://cdn.plyr.io/3.3.22/plyr.js"></script>
|
||||
```
|
||||
|
||||
...or...
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/3.3.18/plyr.polyfilled.js"></script>
|
||||
<script src="https://cdn.plyr.io/3.3.22/plyr.polyfilled.js"></script>
|
||||
```
|
||||
|
||||
### CSS
|
||||
@@ -152,13 +152,13 @@ Include the `plyr.css` stylsheet into your `<head>`
|
||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.3.18/plyr.css">
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.3.22/plyr.css">
|
||||
```
|
||||
|
||||
### SVG Sprite
|
||||
|
||||
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.3.18/plyr.svg`.
|
||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.3.22/plyr.svg`.
|
||||
|
||||
## Ads
|
||||
|
||||
@@ -409,7 +409,7 @@ player.fullscreen.active; // false;
|
||||
| `speed` | ✓ | ✓ | Gets or sets the speed for the player. The setter accepts a value in the options specified in your config. Generally the minimum should be 0.5. |
|
||||
| `quality`¹ | ✓ | ✓ | Gets or sets the quality for the player. The setter accepts a value from the options specified in your config. |
|
||||
| `loop` | ✓ | ✓ | Gets or sets the current loop state of the player. The setter accepts a boolean. |
|
||||
| `source` | ✓ | ✓ | Gets or sets the current source for the player. The setter accepts an object. See [source setter](#source-setter) below for examples. |
|
||||
| `source` | ✓ | ✓ | Gets or sets the current source for the player. The setter accepts an object. See [source setter](#the-source-setter) below for examples. |
|
||||
| `poster` | ✓ | ✓ | Gets or sets the current poster image for the player. The setter accepts a string; the URL for the updated poster image. |
|
||||
| `autoplay` | ✓ | ✓ | Gets or sets the autoplay state of the player. The setter accepts a boolean. |
|
||||
| `currentTrack` | ✓ | ✓ | Gets or sets the caption track by index. `-1` means the track is missing or captions is not active |
|
||||
@@ -435,10 +435,12 @@ player.source = {
|
||||
{
|
||||
src: '/path/to/movie.mp4',
|
||||
type: 'video/mp4',
|
||||
size: 720,
|
||||
},
|
||||
{
|
||||
src: '/path/to/movie.webm',
|
||||
type: 'video/webm',
|
||||
size: 1080,
|
||||
},
|
||||
],
|
||||
poster: '/path/to/poster.jpg',
|
||||
|
||||
+5
-3
@@ -84,7 +84,7 @@ const captions = {
|
||||
// * toggled: The real captions state
|
||||
|
||||
const languages = dedupe(
|
||||
Array.from(navigator.languages || navigator.userLanguage).map(language => language.split('-')[0]),
|
||||
Array.from(navigator.languages || navigator.language || navigator.userLanguage).map(language => language.split('-')[0]),
|
||||
);
|
||||
|
||||
let language = (this.storage.get('language') || this.config.captions.language || 'auto').toLowerCase();
|
||||
@@ -191,8 +191,10 @@ const captions = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Toggle state
|
||||
this.elements.buttons.captions.pressed = active;
|
||||
// Toggle button if it's enabled
|
||||
if (this.elements.buttons.captions) {
|
||||
this.elements.buttons.captions.pressed = active;
|
||||
}
|
||||
|
||||
// Add class hook
|
||||
toggleClass(this.elements.container, activeClass, active);
|
||||
|
||||
@@ -17,10 +17,12 @@ export default class Console {
|
||||
// eslint-disable-next-line no-console
|
||||
return this.enabled ? Function.prototype.bind.call(console.log, console) : noop;
|
||||
}
|
||||
|
||||
get warn() {
|
||||
// eslint-disable-next-line no-console
|
||||
return this.enabled ? Function.prototype.bind.call(console.warn, console) : noop;
|
||||
}
|
||||
|
||||
get error() {
|
||||
// eslint-disable-next-line no-console
|
||||
return this.enabled ? Function.prototype.bind.call(console.error, console) : noop;
|
||||
|
||||
Vendored
+12
-2
@@ -16,11 +16,11 @@ import {
|
||||
getElement,
|
||||
getElements,
|
||||
hasClass,
|
||||
matches,
|
||||
removeElement,
|
||||
setAttributes,
|
||||
toggleClass,
|
||||
toggleHidden,
|
||||
matches,
|
||||
} from './utils/elements';
|
||||
import { off, on } from './utils/events';
|
||||
import is from './utils/is';
|
||||
@@ -187,7 +187,7 @@ const controls = {
|
||||
}
|
||||
|
||||
if ('class' in attributes) {
|
||||
if (attributes.class.includes(this.config.classNames.control)) {
|
||||
if (!attributes.class.includes(this.config.classNames.control)) {
|
||||
attributes.class += ` ${this.config.classNames.control}`;
|
||||
}
|
||||
} else {
|
||||
@@ -633,6 +633,16 @@ const controls = {
|
||||
return;
|
||||
}
|
||||
|
||||
// If duration is the 2**32 (shaka), Infinity (HLS), DASH-IF (Number.MAX_SAFE_INTEGER || Number.MAX_VALUE) indicating live we hide the currentTime and progressbar.
|
||||
// https://github.com/video-dev/hls.js/blob/5820d29d3c4c8a46e8b75f1e3afa3e68c1a9a2db/src/controller/buffer-controller.js#L415
|
||||
// https://github.com/google/shaka-player/blob/4d889054631f4e1cf0fbd80ddd2b71887c02e232/lib/media/streaming_engine.js#L1062
|
||||
// https://github.com/Dash-Industry-Forum/dash.js/blob/69859f51b969645b234666800d4cb596d89c602d/src/dash/models/DashManifestModel.js#L338
|
||||
if (this.duration >= 2**32) {
|
||||
toggleHidden(this.elements.display.currentTime, true);
|
||||
toggleHidden(this.elements.progress, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update ARIA values
|
||||
if (is.element(this.elements.inputs.seek)) {
|
||||
this.elements.inputs.seek.setAttribute('aria-valuemax', this.duration);
|
||||
|
||||
+6
-5
@@ -431,9 +431,11 @@ class Listeners {
|
||||
};
|
||||
|
||||
// Play/pause toggle
|
||||
Array.from(this.player.elements.buttons.play).forEach(button => {
|
||||
bind(button, 'click', this.player.togglePlay, 'play');
|
||||
});
|
||||
if (this.player.elements.buttons.play) {
|
||||
Array.from(this.player.elements.buttons.play).forEach(button => {
|
||||
bind(button, 'click', this.player.togglePlay, 'play');
|
||||
});
|
||||
}
|
||||
|
||||
// Pause
|
||||
bind(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
|
||||
@@ -667,8 +669,7 @@ class Listeners {
|
||||
const inverted = event.webkitDirectionInvertedFromDevice;
|
||||
|
||||
// Get delta from event. Invert if `inverted` is true
|
||||
const [x, y] = [event.deltaX, -event.deltaY]
|
||||
.map(value => inverted ? -value : value);
|
||||
const [x, y] = [event.deltaX, -event.deltaY].map(value => (inverted ? -value : value));
|
||||
|
||||
// Using the biggest delta, normalize to 1 or -1 (or 0 if no delta)
|
||||
const direction = Math.sign(Math.abs(x) > Math.abs(y) ? x : y);
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
/* global google */
|
||||
|
||||
import i18n from '../i18n';
|
||||
import { createElement } from './../utils/elements';
|
||||
import { triggerEvent } from './../utils/events';
|
||||
import is from './../utils/is';
|
||||
import loadScript from './../utils/loadScript';
|
||||
import { formatTime } from './../utils/time';
|
||||
import { buildUrlParams } from './../utils/urls';
|
||||
import { createElement } from '../utils/elements';
|
||||
import { triggerEvent } from '../utils/events';
|
||||
import is from '../utils/is';
|
||||
import loadScript from '../utils/loadScript';
|
||||
import { formatTime } from '../utils/time';
|
||||
import { buildUrlParams } from '../utils/urls';
|
||||
|
||||
class Ads {
|
||||
/**
|
||||
@@ -100,7 +100,7 @@ class Ads {
|
||||
const params = {
|
||||
AV_PUBLISHERID: '58c25bb0073ef448b1087ad6',
|
||||
AV_CHANNELID: '5a0458dc28a06145e4519d21',
|
||||
AV_URL: location.hostname,
|
||||
AV_URL: window.location.hostname,
|
||||
cb: Date.now(),
|
||||
AV_WIDTH: 640,
|
||||
AV_HEIGHT: 480,
|
||||
|
||||
+10
-10
@@ -2,16 +2,16 @@
|
||||
// Vimeo plugin
|
||||
// ==========================================================================
|
||||
|
||||
import captions from './../captions';
|
||||
import controls from './../controls';
|
||||
import ui from './../ui';
|
||||
import { createElement, replaceElement, toggleClass } from './../utils/elements';
|
||||
import { triggerEvent } from './../utils/events';
|
||||
import fetch from './../utils/fetch';
|
||||
import is from './../utils/is';
|
||||
import loadScript from './../utils/loadScript';
|
||||
import { format, stripHTML } from './../utils/strings';
|
||||
import { buildUrlParams } from './../utils/urls';
|
||||
import captions from '../captions';
|
||||
import controls from '../controls';
|
||||
import ui from '../ui';
|
||||
import { createElement, replaceElement, toggleClass } from '../utils/elements';
|
||||
import { triggerEvent } from '../utils/events';
|
||||
import fetch from '../utils/fetch';
|
||||
import is from '../utils/is';
|
||||
import loadScript from '../utils/loadScript';
|
||||
import { format, stripHTML } from '../utils/strings';
|
||||
import { buildUrlParams } from '../utils/urls';
|
||||
|
||||
// Parse Vimeo ID from URL
|
||||
function parseId(url) {
|
||||
|
||||
+10
-10
@@ -2,16 +2,16 @@
|
||||
// YouTube plugin
|
||||
// ==========================================================================
|
||||
|
||||
import controls from './../controls';
|
||||
import ui from './../ui';
|
||||
import { dedupe } from './../utils/arrays';
|
||||
import { createElement, replaceElement, toggleClass } from './../utils/elements';
|
||||
import { triggerEvent } from './../utils/events';
|
||||
import fetch from './../utils/fetch';
|
||||
import is from './../utils/is';
|
||||
import loadImage from './../utils/loadImage';
|
||||
import loadScript from './../utils/loadScript';
|
||||
import { format, generateId } from './../utils/strings';
|
||||
import controls from '../controls';
|
||||
import ui from '../ui';
|
||||
import { dedupe } from '../utils/arrays';
|
||||
import { createElement, replaceElement, toggleClass } from '../utils/elements';
|
||||
import { triggerEvent } from '../utils/events';
|
||||
import fetch from '../utils/fetch';
|
||||
import is from '../utils/is';
|
||||
import loadImage from '../utils/loadImage';
|
||||
import loadScript from '../utils/loadScript';
|
||||
import { format, generateId } from '../utils/strings';
|
||||
|
||||
// Parse YouTube ID from URL
|
||||
function parseId(url) {
|
||||
|
||||
+11
-3
@@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v3.3.18
|
||||
// plyr.js v3.3.22
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
@@ -310,18 +310,23 @@ class Plyr {
|
||||
get isHTML5() {
|
||||
return Boolean(this.provider === providers.html5);
|
||||
}
|
||||
|
||||
get isEmbed() {
|
||||
return Boolean(this.isYouTube || this.isVimeo);
|
||||
}
|
||||
|
||||
get isYouTube() {
|
||||
return Boolean(this.provider === providers.youtube);
|
||||
}
|
||||
|
||||
get isVimeo() {
|
||||
return Boolean(this.provider === providers.vimeo);
|
||||
}
|
||||
|
||||
get isVideo() {
|
||||
return Boolean(this.type === types.video);
|
||||
}
|
||||
|
||||
get isAudio() {
|
||||
return Boolean(this.type === types.audio);
|
||||
}
|
||||
@@ -489,8 +494,9 @@ class Plyr {
|
||||
// Faux duration set via config
|
||||
const fauxDuration = parseFloat(this.config.duration);
|
||||
|
||||
// Media duration can be NaN before the media has loaded
|
||||
const duration = (this.media || {}).duration || 0;
|
||||
// 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;
|
||||
|
||||
// If config duration is funky, use regular duration
|
||||
return fauxDuration || duration;
|
||||
@@ -944,6 +950,7 @@ class Plyr {
|
||||
on(event, callback) {
|
||||
on.call(this, this.elements.container, event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add event listeners once
|
||||
* @param {string} event - Event type
|
||||
@@ -952,6 +959,7 @@ class Plyr {
|
||||
once(event, callback) {
|
||||
once.call(this, this.elements.container, event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove event listeners
|
||||
* @param {string} event - Event type
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr Polyfilled Build
|
||||
// plyr.js v3.3.18
|
||||
// plyr.js v3.3.22
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Sprite loader
|
||||
// ==========================================================================
|
||||
|
||||
import Storage from './../storage';
|
||||
import Storage from '../storage';
|
||||
import fetch from './fetch';
|
||||
import is from './is';
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
.plyr__controls {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
text-align: center;
|
||||
|
||||
// Spacing
|
||||
@@ -23,6 +24,7 @@
|
||||
&:first-child,
|
||||
&:first-child + [data-plyr='pause'] {
|
||||
margin-left: 0;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,13 +50,17 @@
|
||||
|
||||
// Video controls
|
||||
.plyr--video .plyr__controls {
|
||||
background: linear-gradient(rgba($plyr-video-controls-bg, 0), rgba($plyr-video-controls-bg, 0.7));
|
||||
background: linear-gradient(
|
||||
rgba($plyr-video-controls-bg, 0),
|
||||
rgba($plyr-video-controls-bg, 0.7)
|
||||
);
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
bottom: 0;
|
||||
color: $plyr-video-control-color;
|
||||
left: 0;
|
||||
padding: ($plyr-control-spacing * 3.5) $plyr-control-spacing $plyr-control-spacing;
|
||||
padding: ($plyr-control-spacing * 3.5) $plyr-control-spacing
|
||||
$plyr-control-spacing;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
transition: opacity 0.4s ease-in-out, transform 0.4s ease-in-out;
|
||||
|
||||
@@ -27,11 +27,6 @@ $embed-padding: ((100 / 16) * 9);
|
||||
$height: 240;
|
||||
$offset: to-percentage(($height - $embed-padding) / ($height / 50));
|
||||
|
||||
// To allow mouse events to be captured if full support
|
||||
iframe {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// Only used for Vimeo
|
||||
> .plyr__video-embed__container {
|
||||
padding-bottom: to-percentage($height);
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
transition: opacity 0.3s ease;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.plyr--stopped.plyr__poster-enabled .plyr__poster {
|
||||
opacity: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user