Compare commits

..

62 Commits

Author SHA1 Message Date
Sam Potts 2679c5898e v3.2.23 2018-07-30 22:55:34 +10:00
Sam Potts efb7401e6d Merge pull request #1136 from sampotts/develop
v3.3.23
2018-07-30 22:54:03 +10:00
Sam Potts 60a0f0c979 Missed reference 2018-07-30 22:53:42 +10:00
Sam Potts 5d168d0e14 v3.3.23 2018-07-30 22:53:09 +10:00
Sam Potts f964e34d8c Merge pull request #1134 from mjfwebb/hide-empty-controls
Hide empty controls
2018-07-30 22:47:10 +10:00
Sam Potts 021ba0b8e9 Update controls.scss 2018-07-30 22:46:48 +10:00
Sam Potts 96d371546c Merge pull request #1135 from sampotts/master
Merge back
2018-07-30 22:45:59 +10:00
Sam Potts e1780a4df0 Fix for redraw issue 2018-07-30 22:44:19 +10:00
Albin Larsson e5e169a1e2 Don't move caption up when "showing" the lower controls when the controls are empty 2018-07-30 01:02:13 +02:00
mjfwebb 5eda498516 If the plyr__controls is empty it is still showing the transition causing captions to be pushed up when hovering over where the controls would be. This change hides the plyr__controls div when it is empty. 2018-07-29 22:02:16 +02:00
Sam Potts 44b5d9f6b9 Merge pull request #1131 from friday/1108
Make sure youtube.onReady doesn't run twice
2018-07-29 00:19:37 +10:00
Albin Larsson 24deff0e2d Fix #1108: Make sure youtube.onReady doesn't run twice 2018-07-28 04:04:57 +02:00
Sam Potts 0933b48c2a Merge pull request #1113 from friday/issue-templates
Use GitHub's new issue template prompt
2018-07-27 13:12:49 +10:00
Sam Potts 71578e07ec Merge pull request #1120 from didacte/add-missing-youtube-hl-param
Add support for YouTube's hl param
2018-07-26 00:03:10 +10:00
Léo Renaud-Allaire 671325dd17 Add support for YouTube's hl param 2018-07-24 16:36:25 -04:00
Albin Larsson ad1989e45e New issue templates (with prompt) 2018-07-23 06:21:46 +02:00
Albin Larsson f9ac98bc6d Lowercase contributing.md (like the other docs) 2018-07-23 06:21:25 +02:00
Sam Potts 544ab0086b Logic fix 2018-07-19 10:02:41 +10:00
Sam Potts 13bf80d372 Deployment improvements (auto purge cache etc) 2018-07-19 09:47:11 +10:00
Sam Potts e2fb922d73 v3.3.22 2018-07-18 21:47:46 +10:00
Sam Potts a6cc85c437 Merge branch 'develop' 2018-07-18 21:46:43 +10:00
Sam Potts d061be5d2b Changelog 2018-07-18 21:46:23 +10:00
Sam Potts dc2feedd79 Merge pull request #1103 from sampotts/develop
v3.3.12
2018-07-18 21:45:31 +10:00
Sam Potts f8e4ba36e5 Merge branch 'master' into develop
# Conflicts:
#	changelog.md
#	dist/plyr.js.map
#	dist/plyr.min.js.map
#	dist/plyr.polyfilled.js.map
#	dist/plyr.polyfilled.min.js.map
#	package.json
2018-07-18 21:44:39 +10:00
Sam Potts f3d5389587 3.3.17 2018-07-18 21:41:46 +10:00
Sam Potts d9ffb10b93 Merge pull request #1080 from gurupras/html5-quality-source-setter-readme
Updated README.md to show how to add quality options to HTML5 videos
2018-07-18 15:32:46 +10:00
Sam Potts 1186377b25 Merge pull request #1095 from friday/stickler
Add stickler config
2018-07-11 23:32:49 +10:00
Sam Potts 8616895e57 Merge pull request #1094 from friday/remark
Verify internal documentation links with "remark"
2018-07-11 09:17:24 +10:00
Albin Larsson 2cf5a22c85 Fix internal link for the source setter 2018-07-10 23:56:00 +02:00
Albin Larsson 763eb2df80 Add 'remark' and plugin to verify internal links in markdown 2018-07-10 23:56:00 +02:00
Albin Larsson 8bbf66a0fb Add stickler config 2018-07-10 20:53:09 +02:00
Sam Potts 676b46e4a7 Merge pull request #1093 from friday/travis-2
Verify PR instructions with Travis
2018-07-10 15:24:22 +10:00
Albin Larsson 82a119c67f Add travis check for the base branch (only permit develop for code changes) 2018-07-10 05:16:05 +02:00
Albin Larsson 6fd4389887 Add travis check for omitting dist in development branch 2018-07-10 05:16:05 +02:00
Albin Larsson 1e1a548459 Simplify travis conf 2018-07-10 02:44:15 +02:00
Sam Potts 8db9b53a8f Merge pull request #1092 from friday/readme-streaming-link
Fix streaming link in docs
2018-07-10 09:50:43 +10:00
Sam Potts ba33fd8277 Merge pull request #1091 from friday/1085
Add navigator.languages fallback for ios 9
2018-07-10 09:50:24 +10:00
Albin Larsson 8071feda18 Fix streaming link 2018-07-09 18:47:16 +02:00
Albin Larsson a49b73cd01 Add navigator.languages fallback for ios 9 2018-07-09 18:38:23 +02:00
Sam Potts 8226493a9e Update pull_request_template.md 2018-07-05 09:49:25 +10:00
Sam Potts 38a8a0e8a1 Update issue_template.md 2018-07-05 09:45:17 +10:00
Sam Potts 6eeca8b5d1 Merge pull request #1083 from friday/fix-travis
Change "no-cycle" lint-error to warning
2018-07-02 08:53:50 +10:00
Sam Potts bf51ce4414 Merge pull request #1082 from friday/yarn-error.log
Gitignore yarn-error.log
2018-07-02 08:53:32 +10:00
Albin Larsson 5ad614e251 Change linting import/no-cycle to warning (not error) 2018-07-01 19:50:58 +02:00
Albin Larsson 93c890603d Gitignore yarn-error.log 2018-07-01 19:33:47 +02:00
Guru Prasad Srinivasa 29fb4dfc2b Updated README.md to show up to add quality options to HTML5 videos
initialized via the source setter
2018-06-30 08:04:32 -04:00
Sam Potts 7de9fd1d65 Merge branch 'develop'
# Conflicts:
#	changelog.md
#	demo/dist/demo.css
#	demo/dist/demo.js.map
#	demo/dist/demo.min.js
#	demo/dist/demo.min.js.map
#	dist/plyr.css
#	dist/plyr.js.map
#	dist/plyr.min.js.map
#	dist/plyr.polyfilled.js.map
#	dist/plyr.polyfilled.min.js
#	dist/plyr.polyfilled.min.js.map
#	package.json
#	readme.md
#	src/js/plyr.js
#	src/js/plyr.polyfilled.js
2018-06-29 00:43:02 +10:00
Sam Potts 566c059832 3.3.16 2018-06-29 00:38:11 +10:00
Sam Potts 0c9572f0a1 Merge branch 'develop' of github.com:sampotts/plyr into develop 2018-06-29 00:21:28 +10:00
Sam Potts c99607c85a Linting, housekeeping, duration fix (fixes #1074) 2018-06-29 00:21:22 +10:00
Sam Potts e2010bcd1a Merge pull request #1075 from mimse/feature/handle_live_stream
Hide currentTime and progress
2018-06-28 23:52:58 +10:00
mimse e9f1b55f51 Hide currentTime and progress 2018-06-28 11:25:55 +02:00
Sam Potts 4f5152f526 Merge pull request #1070 from mimse/fix_condition_check
Fixed condition check
2018-06-27 22:47:42 +10:00
Morten Vestergaard Hansen de9b53045a Fixed condition check
If class includes "control" it will add it again.
2018-06-27 14:33:51 +02:00
Sam Potts df458c5e7a Merge branch 'develop' of github.com:sampotts/plyr into develop 2018-06-25 22:31:43 +10:00
Sam Potts e206554146 Linting and package tweak 2018-06-25 22:31:38 +10:00
Sam Potts e422806c44 Merge pull request #1063 from klassicd/develop
Handle undefined this.player.elements.buttons.play
2018-06-25 20:21:49 +10:00
Michael DePetrillo b6ddf144f4 handle undefined player.elements.buttons.play 2018-06-25 12:00:02 +02:00
Sam Potts 86406ee59a Merge pull request #1061 from friday/captions-no-toggle-button
Fix captions.toggle() if there is no toggle button
2018-06-22 08:19:33 +10:00
Albin Larsson 81c5477f1d Fix captions.toggle() if there is no toggle button 2018-06-21 15:22:30 +02:00
Sam Potts ac64350a5f Fix for bug where controls wouldn't show on hover over YouTube video 2018-06-21 19:26:56 +10:00
Sam Potts 333619f1e3 Remove pointer-events: none on embed <iframe> to comply with YouTube ToS 2018-06-21 14:26:40 +10:00
50 changed files with 1275 additions and 413 deletions
+7 -12
View File
@@ -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": {
+55
View File
@@ -0,0 +1,55 @@
---
name: Bug report
about: Report an issue or unexpected behaviour with Plyr
---
<!--
Before creating the issue, please make sure that...
* You aren't getting any errors in your own code, causing the problem.
* You are using the latest version of Plyr.
* There isn't already an open issue for your problem.
* You are following the documentation correctly (https://github.com/sampotts/plyr/)
* Your problem doesn't happen if you remove Plyr and use native HTML5 media (when applicable).
For problems with autoplay, see our FAQ (https://github.com/sampotts/plyr/wiki/FAQ)
If you have multiple unrelated problems, create separate issues rather than combining them into one.
Note that leaving sections blank or being vague will make it difficult for us to troubleshoot and we may close the issue.
-->
### Expected behaviour
### Actual behaviour
### Steps to reproduce
### Environment
- Browser:
- Version:
- Operating System:
- Version:
### Console errors (if any)
### Link to where the bug is happening
<!--
This link can be either to our demo at https://plyr.io/ if the problem can be observed there, or to a code playground with a **minimal** test case that demonstrates the problem.
You can use one of our prepared templates to get started creating the test case:
* HTML5 video: https://codepen.io/pen?template=bKeqpr
* HTML5 audio: https://codepen.io/pen?template=rKLywR
* YouTube: https://codepen.io/pen?template=GGqbbJ
* Vimeo: https://codepen.io/pen?template=bKeXNq
* Dash.js integration: https://codepen.io/pen?template=zaBgBy
* Hls.js integration: https://codepen.io/pen?template=oyLKQb
* Shaka Player integration: https://codepen.io/pen?template=ZRpzZO
It's important that you keep the issue description and replication demo **minimal**. If your replication includes frameworks, libraries or customizations, this makes it much harder to understand the problem and find the bug. For more help on how to create the demo, see https://github.com/sampotts/plyr/wiki/Writing-helpful-issue-descriptions
-->
+10
View File
@@ -0,0 +1,10 @@
---
name: New feature
about: Request new functionality
---
<!--
Please describe the behaviour that you want to add, and why. Be as clear as possible to avoid confusion.
If you want to request multiple features that aren't directly related, then create one issue per feature.
-->
+10
View File
@@ -0,0 +1,10 @@
---
name: Improvement
about: Request a change that isn't a bug or new feature
---
<!--
Please describe the behaviour that you want to change, and why. Be as clear as possible to avoid confusion.
If you want to request multiple changes that aren't directly related, then create one issue per change.
-->
+2 -16
View File
@@ -1,17 +1,3 @@
<!---
Please use this issue template as it makes replicating and fixing the issue easier!
--->
PLEASE USE OUR SPECIFIC ISSUE TEMPLATES for bug reports, features and improvement suggestions.
### Expected behaviour
### Actual behaviour
### Environment
- Browser:
- Version:
- Operating System:
- Version:
### Steps to reproduce
-
Our issue tracker is not for support questions. If you need help, follow our support instructions: https://github.com/sampotts/plyr/blob/master/contributing.md#support
+1 -1
View File
@@ -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)
+4 -4
View File
@@ -1,11 +1,11 @@
node_modules
.DS_Store
aws.json
credentials.json
*.mp4
!dist/blank.mp4
index-*.html
npm-debug.log
yarn-error.log
package-lock.json
*.webm
/package-lock.json
.idea/
.idea/
+7
View File
@@ -2,3 +2,10 @@ demo
.github
.vscode
*.code-workspace
credentials.json
bundles.json
yarn.lock
package-lock.json
*.mp4
*.webm
!dist/blank.mp4
-1
View File
@@ -1,7 +1,6 @@
{
"useTabs": false,
"tabWidth": 4,
"printWidth": 120,
"singleQuote": true,
"trailingComma": "all"
}
+5
View File
@@ -0,0 +1,5 @@
linters:
eslint:
files:
ignore:
- 'node_modules/*'
+5 -4
View File
@@ -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
+5
View File
@@ -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
+5
View File
@@ -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
-61
View File
@@ -1,61 +0,0 @@
# Contributing
We welcome bug reports, feature requests and pull requests. If you want to help us out, please follow these guidelines, in order to avoid redundant work.
## Commenting
When commenting, keep a civil tone and stay on topic. Don't ask for support (use [Stack Overflow](https://stackoverflow.com/) or [our Slack](https://bit.ly/plyr-chat) for that), or post "+1" or "I agree" type of comments. Use the emojis instead.
Asking for the status on issues is discouraged. Unless someone has explicitly said in an issue that it's work in progress, most likely that means no one is working on it. We have a lot to do, and it may not be a top priority for us.
We *may* moderate discussions. We do this to avoid threads being "hijacked", to avoid confusion in case the content is misleading or outdated, and to avoid bothering people with github notifications.
## Reporting issues
Our GitHub issue tracker is for bug reports and feature requests. Don't ask for support here. Use [Stack Overflow](https://stackoverflow.com/) or [our Slack](https://bit.ly/plyr-chat) for that.
Please verify that your issue hasn't already been answered by our [FAQ](https://github.com/sampotts/plyr/wiki/FAQ), and that there isn't already an open issue for it.
When applicable, check that your problem doesn't happen without Plyr (see [FAQ#1](https://github.com/sampotts/plyr/wiki/FAQ#1-does-plyr-work-with--)).
Verify that you are following the documentation, are using the latest version of Plyr, and aren't getting any errors in your own code, causing the issues.
Create one issue per problem or request (i.e. don't combine multiple problems to one git issue). Describe the issue as detailed as possible (see [Replication](#replication))
## Replication
In order to solve a problem, we first need to understand it. Please answer these questions when reporting issues or asking for help in [our Slack](https://bit.ly/plyr-chat).
* Does it happen only with specific options and/or specific browsers?
* Does is happen only with HTML5 video, audio, YouTube, Vimeo or a specific library?
* Does the issue happen on [our demo](https://plyr.io/)? If not, please recreate it with a **minimal** example online. You can use our Codepen templates to get started:
* [HTML5 video](https://codepen.io/pen?template=bKeqpr)
* [HTML5 audio](https://codepen.io/pen?template=rKLywR)
* [YouTube](https://codepen.io/pen?template=GGqbbJ)
* [Vimeo](https://codepen.io/pen?template=bKeXNq)
* [Dash.js integration](https://codepen.io/pen?template=zaBgBy)
* [Hls.js integration](https://codepen.io/pen?template=oyLKQb)
* [Shaka Player integration](https://codepen.io/pen?template=ZRpzZO)
It's important that you keep the issue description and replication demo **minimal**. If your replication includes frameworks, libraries or customizations, this makes it harder to debug and understand the issue. While it may be relevant to bring this up (ex: "I need Plyr to trigger the event sooner or it breaks Framework X"), please keep these out of your replication demo if they aren't strictly needed to reproduce the issue. If the issue is caused by something a library does that Plyr doesn't handle, it's more helpful for us if you find out what it is, and replicate the same problem without the library. Otherwise any developer who is willing to help out with the issue has to understand the frameworks, libraries and customizations of *your* choice, or no one will try to fix your issue because it's too much work.
## Requesting features and improvements
If you are missing something in Plyr, you can create a GitHub issue for this as well. Since we prioritize fixing bugs first, and may have a lot of other suggestions and architectural changes to work on as well, these may not be at the top of our list.
If your suggestion is important or urgent to you, you may want to first ensure it's something we want to have in Plyr, and then contribute it as a pull request. [Our Slack](https://bit.ly/plyr-chat) is the best place for questions like this.
## Contributing features and documentation
* Fork Plyr, and create a new branch in your fork, based on the **develop** branch
* To test locally, you can use the demo. First make sure you have installed the dependencies with `npm install` or `yarn`. Run `gulp` to build while you are working, and run a local server from the repository root directory. If you have Python installed, this command should work: `python -m SimpleHTTPServer 8080`. Then go to `http://localhost:8080/demo/`
* Develop and test your modifications.
* Preferably commit your changes as independent logical chunks, with meaningful messages. Make sure you do not commit unnecessary files or changes, such as the build output, or logging and breakpoints you added for testing.
* If your modifications changes the documented behavior or add new features, document these changes in readme.md.
* When finished, push the changes to your GitHub repository and send a pull request to **develop**. Describe what your PR does.
* If the Travis build fails, or if you get a code review with change requests, you can fix these by pushing new or rebased commits to the branch.
-33
View File
@@ -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"
}
+27
View File
@@ -1,3 +1,30 @@
# v3.3.23
- Add support for YouTube's hl param (thanks @renaudleo)
- Fix for captions positioning when no controls (thanks @friday and @mjfwebb)
- Fix #1108: Make sure youtube.onReady doesn't run twice (thanks @friday)
- Fix for WebKit redraw loop on the `<input type="range">` elements
# 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 😢
+40
View File
@@ -0,0 +1,40 @@
# Contributing
We welcome bug reports, feature requests and pull requests. If you want to help us out, please follow these guidelines, in order to avoid redundant work.
## Support
Before asking questions, read our [documentation](https://github.com/sampotts/plyr) and [FAQ](https://github.com/sampotts/plyr/wiki/FAQ).
If these doesn't answer your question
* Use [Stack Overflow](https://stackoverflow.com/) for questions that doesn't directly involve Plyr. This includes for example how to use Javascript, CSS or HTML5 media in general, and how to use other frameworks, libraries and technology.
* Use [our Slack](https://bit.ly/plyr-chat) if you need help using Plyr or have questions about Plyr.
## Commenting
When commenting, keep a civil tone and stay on topic. Don't ask for [support](#support), or post "+1" or "I agree" type of comments. Use the emojis instead.
Asking for the status on issues is discouraged. Unless someone has explicitly said in an issue that it's work in progress, most likely that means no one is working on it. We have a lot to do, and it may not be a top priority for us.
We *may* moderate discussions. We do this to avoid threads being "hijacked", to avoid confusion in case the content is misleading or outdated, and to avoid bothering people with github notifications.
## Creating issues
Please follow the instructions in our issue templates. Don't use github issues to ask for [support](#support).
## Contributing features and documentation
* If you want to add a feature or make critical changes, you may want to ensure that this is something we also want (so you don't waste your time). Ask us about this in the corresponding issue if there is one, or on [our Slack](https://bit.ly/plyr-chat) otherwise.
* Fork Plyr, and create a new branch in your fork, based on the **develop** branch
* To test locally, you can use the demo. First make sure you have installed the dependencies with `npm install` or `yarn`. Run `gulp` to build while you are working, and run a local server from the repository root directory. If you have Python installed, this command should work: `python -m SimpleHTTPServer 8080`. Then go to `http://localhost:8080/demo/`
* Develop and test your modifications.
* Preferably commit your changes as independent logical chunks, with meaningful messages. Make sure you do not commit unnecessary files or changes, such as the build output, or logging and breakpoints you added for testing.
* If your modifications changes the documented behavior or add new features, document these changes in readme.md.
* When finished, push the changes to your GitHub repository and send a pull request to **develop**. Describe what your PR does.
* If the Travis build fails, or if you get a code review with change requests, you can fix these by pushing new or rebased commits to the branch.
+1 -1
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -4137,6 +4137,7 @@ typeof navigator === "object" && (function () {
tooltips: {
controls: true
},
clickToPlay: false,
/* controls: [
'play-large',
'restart',
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -57,6 +57,7 @@ import Raven from 'raven-js';
tooltips: {
controls: true,
},
clickToPlay: false,
/* controls: [
'play-large',
'restart',
+1 -1
View File
File diff suppressed because one or more lines are too long
+37 -17
View File
@@ -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);
@@ -2752,12 +2762,9 @@ typeof navigator === "object" && (function (global, factory) {
target = this.elements.container;
}
// Inject controls HTML
if (is.element(container)) {
target.appendChild(container);
} else if (container) {
target.insertAdjacentHTML('beforeend', container);
}
// Inject controls HTML (needs to be before captions, hence "afterbegin")
var insertMethod = is.element(container) ? 'insertAdjacentElement' : 'insertAdjacentHTML';
target[insertMethod]('afterbegin', container);
// Find the elements if need be
if (!is.element(this.elements.controls)) {
@@ -2881,7 +2888,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 +3016,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 +4614,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');
@@ -5768,6 +5779,7 @@ typeof navigator === "object" && (function (global, factory) {
videoId: videoId,
playerVars: {
autoplay: player.config.autoplay ? 1 : 0, // Autoplay
hl: player.config.hl, // iframe interface language
controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported
rel: 0, // No related vids
showinfo: 0, // Hide info
@@ -5818,6 +5830,10 @@ typeof navigator === "object" && (function (global, factory) {
triggerEvent.call(player, player.media, 'ratechange');
},
onReady: function onReady(event) {
// Bail if onReady has already been called. See issue #1108
if (is.function(player.media.play)) {
return;
}
// Get the instance
var instance = event.target;
@@ -6777,7 +6793,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,
@@ -7073,7 +7089,7 @@ typeof navigator === "object" && (function (global, factory) {
this.elements.container.className = '';
// Get attributes from URL and set config
if (url.searchParams.length) {
if (url.search.length) {
var truthy = ['1', 'true'];
if (truthy.includes(url.searchParams.get('autoplay'))) {
@@ -7087,6 +7103,7 @@ typeof navigator === "object" && (function (global, factory) {
// YouTube requires the playsinline in the URL
if (this.isYouTube) {
this.config.playsinline = truthy.includes(url.searchParams.get('playsinline'));
this.config.hl = url.searchParams.get('hl');
} else {
this.config.playsinline = true;
}
@@ -7421,6 +7438,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 +7450,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 +7726,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;
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+37 -17
View File
@@ -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);
@@ -8138,12 +8148,9 @@ typeof navigator === "object" && (function (global, factory) {
target = this.elements.container;
}
// Inject controls HTML
if (is$1.element(container)) {
target.appendChild(container);
} else if (container) {
target.insertAdjacentHTML('beforeend', container);
}
// Inject controls HTML (needs to be before captions, hence "afterbegin")
var insertMethod = is$1.element(container) ? 'insertAdjacentElement' : 'insertAdjacentHTML';
target[insertMethod]('afterbegin', container);
// Find the elements if need be
if (!is$1.element(this.elements.controls)) {
@@ -8267,7 +8274,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 +8402,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 +10000,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');
@@ -11148,6 +11159,7 @@ typeof navigator === "object" && (function (global, factory) {
videoId: videoId,
playerVars: {
autoplay: player.config.autoplay ? 1 : 0, // Autoplay
hl: player.config.hl, // iframe interface language
controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported
rel: 0, // No related vids
showinfo: 0, // Hide info
@@ -11198,6 +11210,10 @@ typeof navigator === "object" && (function (global, factory) {
triggerEvent.call(player, player.media, 'ratechange');
},
onReady: function onReady(event) {
// Bail if onReady has already been called. See issue #1108
if (is$1.function(player.media.play)) {
return;
}
// Get the instance
var instance = event.target;
@@ -12157,7 +12173,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,
@@ -12453,7 +12469,7 @@ typeof navigator === "object" && (function (global, factory) {
this.elements.container.className = '';
// Get attributes from URL and set config
if (url.searchParams.length) {
if (url.search.length) {
var truthy = ['1', 'true'];
if (truthy.includes(url.searchParams.get('autoplay'))) {
@@ -12467,6 +12483,7 @@ typeof navigator === "object" && (function (global, factory) {
// YouTube requires the playsinline in the URL
if (this.isYouTube) {
this.config.playsinline = truthy.includes(url.searchParams.get('playsinline'));
this.config.hl = url.searchParams.get('hl');
} else {
this.config.playsinline = true;
}
@@ -12801,6 +12818,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 +12830,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 +13106,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;
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+125 -62
View File
@@ -29,18 +29,12 @@ const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify-es').default;
const commonjs = require('rollup-plugin-commonjs');
const resolve = require('rollup-plugin-node-resolve');
const FastlyPurge = require('fastly-purge');
const through = require('through2');
const bundles = require('./bundles.json');
const pkg = require('./package.json');
// Get AWS config
let aws = {};
try {
aws = require('./aws.json'); //eslint-disable-line
} catch (e) {
// Do nothing
}
const minSuffix = '.min';
// Paths
@@ -95,16 +89,18 @@ const browsers = ['> 1%'];
// Babel config
const babelrc = {
presets: [[
'env',
{
targets: {
browsers,
presets: [
[
'env',
{
targets: {
browsers,
},
useBuiltIns: true,
modules: false,
},
useBuiltIns: true,
modules: false,
},
]],
],
],
plugins: ['external-helpers'],
babelrc: false,
exclude: 'node_modules/**',
@@ -112,10 +108,9 @@ const babelrc = {
// Clean out /dist
gulp.task('clean', () => {
const dirs = [
paths.plyr.output,
paths.demo.output,
].map(dir => path.join(dir, '**/*'));
const dirs = [paths.plyr.output, paths.demo.output].map(dir =>
path.join(dir, '**/*'),
);
// Don't delete the mp4
dirs.push(`!${path.join(paths.plyr.output, '**/*.mp4')}`);
@@ -187,9 +182,11 @@ const build = {
.src(paths[bundle].src.sprite)
.pipe(
svgmin({
plugins: [{
removeDesc: true,
}],
plugins: [
{
removeDesc: true,
},
],
}),
)
.pipe(svgstore())
@@ -238,9 +235,21 @@ gulp.task('default', () => {
// Publish a version to CDN and demo
// --------------------------------------------
// If aws is setup
if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
// Get deployment config
let credentials = {};
try {
credentials = require('./credentials.json'); //eslint-disable-line
} catch (e) {
// Do nothing
}
// If deployment is setup
if (
Object.keys(credentials).includes('aws') &&
Object.keys(credentials).includes('fastly')
) {
const { version } = pkg;
const { aws, fastly } = credentials;
// Get branch info
const branch = {
@@ -248,10 +257,6 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
master: 'master',
develop: 'develop',
};
const allowed = [
branch.master,
branch.develop,
];
const maxAge = 31536000; // 1 year
const options = {
@@ -264,7 +269,8 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
demo: {
uploadPath: branch.current === branch.develop ? 'beta/' : null,
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
'Cache-Control':
'no-cache, no-store, must-revalidate, max-age=0',
Vary: 'Accept-Encoding',
},
},
@@ -273,27 +279,51 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
headers: {
// http://stackoverflow.com/questions/2272835/amazon-s3-object-redirect
'x-amz-website-redirect-location': `/${ver}/${filename}`,
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
'Cache-Control':
'no-cache, no-store, must-revalidate, max-age=0',
},
};
},
};
const regex = '(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*).(?:0|[1-9][0-9]*)(?:-[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?';
const regex =
'(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*).(?:0|[1-9][0-9]*)(?:-[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:.[\\da-z\\-]+)*)?';
const semver = new RegExp(`v${regex}`, 'gi');
const localPath = new RegExp('(../)?dist', 'gi');
const versionPath = `https://${aws.cdn.domain}/${version}`;
const cdnpath = new RegExp(`${aws.cdn.domain}/${regex}/`, 'gi');
const renameFile = rename(p => {
p.basename = p.basename.replace(minSuffix, ''); // eslint-disable-line
p.dirname = p.dirname.replace('.', version); // eslint-disable-line
});
// Check we're on the correct branch to deploy
const canDeploy = () => {
const allowed = [branch.master, branch.develop];
if (!allowed.includes(branch.current)) {
console.error(
`Must be on ${allowed.join(', ')} to publish! (current: ${
branch.current
})`,
);
return false;
}
return true;
};
gulp.task('version', () => {
if (!canDeploy()) {
return null;
}
console.log(`Updating versions to '${version}'...`);
// Replace versioned URLs in source
const files = [
'plyr.js',
'plyr.polyfilled.js',
'defaults.js',
];
const files = ['plyr.js', 'plyr.polyfilled.js', 'defaults.js'];
return gulp
.src(files.map(file => path.join(root, `src/js/${file}`)))
@@ -304,8 +334,7 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
// Publish version to CDN bucket
gulp.task('cdn', () => {
if (!allowed.includes(branch.current)) {
console.error(`Must be on ${allowed.join(', ')} to publish! (current: ${branch.current})`);
if (!canDeploy()) {
return null;
}
@@ -315,14 +344,15 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
return (
gulp
.src(paths.upload)
.pipe(
rename(p => {
p.basename = p.basename.replace(minSuffix, ''); // eslint-disable-line
p.dirname = p.dirname.replace('.', version); // eslint-disable-line
}),
)
.pipe(renameFile)
// Remove min suffix from source map URL
.pipe(replace(/sourceMappingURL=([\w-?.]+)/, (match, p1) => `sourceMappingURL=${p1.replace(minSuffix, '')}`))
.pipe(
replace(
/sourceMappingURL=([\w-?.]+)/,
(match, p1) =>
`sourceMappingURL=${p1.replace(minSuffix, '')}`,
),
)
.pipe(
size({
showFiles: true,
@@ -334,10 +364,36 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
);
});
// Purge the fastly cache incase any 403/404 are cached
gulp.task('purge', () => {
const list = [];
return gulp.src(paths.upload).pipe(
through.obj((file, enc, cb) => {
const filename = file.path.split('/').pop();
list.push(`${versionPath}/${filename}`);
cb(null);
}),
).on('end', () => {
const purge = new FastlyPurge(fastly.token);
list.forEach(url => {
console.log(`Purging ${url}...`);
purge.url(url, (error, result) => {
if (error) {
console.log(error);
} else if (result) {
console.log(result);
}
});
});
});
});
// Publish to demo bucket
gulp.task('demo', () => {
if (!allowed.includes(branch.current)) {
console.error(`Must be on ${allowed.join(', ')} to publish! (current: ${branch.current})`);
if (!canDeploy()) {
return null;
}
@@ -399,22 +455,29 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
}));
}); */
// Open the demo site to check it's sweet
gulp.task('open', () => {
console.log(`Opening ${aws.demo.domain}...`);
// A file must be specified or gulp will skip the task
// Doesn't matter which file since we set the URL above
// Weird, I know...
return gulp.src([`${paths.demo.root}index.html`]).pipe(
open('', {
url: `http://${aws.demo.domain}`,
// Open the demo site to check it's ok
gulp.task('open', callback => {
gulp.src(__filename).pipe(
open({
uri: `https://${aws.demo.domain}`,
}),
);
callback();
});
// Do everything
gulp.task('publish', callback => {
run('version', tasks.clean, tasks.js, tasks.sass, tasks.sprite, 'cdn', 'demo', callback);
});
gulp.task('deploy', () =>
run(
'version',
tasks.clean,
tasks.js,
tasks.sass,
tasks.sprite,
'cdn',
'purge',
'demo',
'open',
),
);
}
+49 -34
View File
@@ -1,33 +1,63 @@
{
"name": "plyr",
"version": "3.3.18",
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
"version": "3.3.23",
"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.2.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",
"fastly-purge": "^1.0.1",
"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",
"gulp-header": "^2.0.5",
"gulp-open": "^3.0.1",
"gulp-postcss": "^7.0.1",
"gulp-rename": "^1.3.0",
"gulp-rename": "^1.4.0",
"gulp-replace": "^1.0.0",
"gulp-s3": "^0.11.0",
"gulp-sass": "^4.0.1",
@@ -38,43 +68,28 @@
"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",
"rollup-plugin-commonjs": "^9.1.3",
"remark-cli": "^5.0.0",
"remark-validate-links": "^7.0.0",
"rollup-plugin-babel": "^3.0.7",
"rollup-plugin-commonjs": "^9.1.4",
"rollup-plugin-node-resolve": "^3.3.0",
"run-sequence": "^2.2.1",
"stylelint": "^9.3.0",
"stylelint": "^9.4.0",
"stylelint-config-prettier": "^3.3.0",
"stylelint-config-recommended": "^2.1.0",
"stylelint-config-sass-guidelines": "^5.0.0",
"stylelint-order": "^0.8.1",
"stylelint-scss": "^3.1.3",
"stylelint-selector-bem-pattern": "^2.0.0"
"stylelint-scss": "^3.2.0",
"stylelint-selector-bem-pattern": "^2.0.0",
"through2": "^2.0.3"
},
"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",
"custom-event-polyfill": "^1.0.6",
"loadjs": "^3.5.4",
"raven-js": "^3.26.3",
"raven-js": "^3.26.4",
"url-polyfill": "^1.0.13"
}
}
+9 -7
View File
@@ -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
@@ -80,7 +80,7 @@ Plyr extends upon the standard [HTML5 media element](https://developer.mozilla.o
</audio>
```
For YouTube and Vimeo players, Plyr uses progressive enhancement to enhance the default `<iframe>` embeds. Below are some examples. The `plyr__video-embed` classname will make the embed responsive. You can add the `autoplay`, `loop` and `playsinline` (YouTube only) query parameters to the URL and they will be set as config options automatically. For YouTube, the `origin` should be updated to reflect the domain you're hosting the embed on, or you can opt to omit it.
For YouTube and Vimeo players, Plyr uses progressive enhancement to enhance the default `<iframe>` embeds. Below are some examples. The `plyr__video-embed` classname will make the embed responsive. You can add the `autoplay`, `loop`, `hl` (YouTube only) and `playsinline` (YouTube only) query parameters to the URL and they will be set as config options automatically. For YouTube, the `origin` should be updated to reflect the domain you're hosting the embed on, or you can opt to omit it.
#### YouTube embed
@@ -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.23/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.23/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.23/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.23/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`&sup1; | ✓ | ✓ | 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
View File
@@ -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);
+2
View File
@@ -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;
+15 -8
View File
@@ -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);
@@ -1445,12 +1455,9 @@ const controls = {
target = this.elements.container;
}
// Inject controls HTML
if (is.element(container)) {
target.appendChild(container);
} else if (container) {
target.insertAdjacentHTML('beforeend', container);
}
// Inject controls HTML (needs to be before captions, hence "afterbegin")
const insertMethod = is.element(container) ? 'insertAdjacentElement' : 'insertAdjacentHTML';
target[insertMethod]('afterbegin', container);
// Find the elements if need be
if (!is.element(this.elements.controls)) {
+6 -5
View File
@@ -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 -7
View File
@@ -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
View File
@@ -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) {
+15 -10
View File
@@ -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) {
@@ -188,6 +188,7 @@ const youtube = {
videoId,
playerVars: {
autoplay: player.config.autoplay ? 1 : 0, // Autoplay
hl: player.config.hl, // iframe interface language
controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported
rel: 0, // No related vids
showinfo: 0, // Hide info
@@ -239,6 +240,10 @@ const youtube = {
triggerEvent.call(player, player.media, 'ratechange');
},
onReady(event) {
// Bail if onReady has already been called. See issue #1108
if (is.function(player.media.play)) {
return;
}
// Get the instance
const instance = event.target;
+13 -4
View File
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr
// plyr.js v3.3.18
// plyr.js v3.3.23
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
@@ -171,7 +171,7 @@ class Plyr {
this.elements.container.className = '';
// Get attributes from URL and set config
if (url.searchParams.length) {
if (url.search.length) {
const truthy = ['1', 'true'];
if (truthy.includes(url.searchParams.get('autoplay'))) {
@@ -185,6 +185,7 @@ class Plyr {
// YouTube requires the playsinline in the URL
if (this.isYouTube) {
this.config.playsinline = truthy.includes(url.searchParams.get('playsinline'));
this.config.hl = url.searchParams.get('hl');
} else {
this.config.playsinline = true;
}
@@ -310,18 +311,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 +495,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 +951,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 +960,7 @@ class Plyr {
once(event, callback) {
once.call(this, this.elements.container, event, callback);
}
/**
* Remove event listeners
* @param {string} event - Event type
+1 -1
View File
@@ -1,6 +1,6 @@
// ==========================================================================
// Plyr Polyfilled Build
// plyr.js v3.3.18
// plyr.js v3.3.23
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
+1 -1
View File
@@ -2,7 +2,7 @@
// Sprite loader
// ==========================================================================
import Storage from './../storage';
import Storage from '../storage';
import fetch from './fetch';
import is from './is';
+16 -2
View File
@@ -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;
@@ -103,3 +109,11 @@
.plyr--fullscreen-enabled [data-plyr='fullscreen'] {
display: inline-block;
}
.plyr__controls:empty {
display: none;
~ .plyr__captions {
transform: translateY(0);
}
}
-5
View File
@@ -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);
+1 -1
View File
@@ -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;
}
-1
View File
@@ -28,7 +28,6 @@
border: 0;
border-radius: ($plyr-range-track-height / 2);
height: $plyr-range-track-height;
transition: all 0.3s ease;
user-select: none;
}
+730 -75
View File
File diff suppressed because it is too large Load Diff