Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
3526e322ef | |||
99cabd545d | |||
1f7f7b10de | |||
b2421b592a | |||
5322f4c62f | |||
7ab8647fc8 | |||
50c76f3d7e | |||
2f4c56176d | |||
7c5f38311b |
15
changelog.md
15
changelog.md
@ -1,5 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
## v1.1.4
|
||||
- Minor bug fixes
|
||||
|
||||
## v1.1.3
|
||||
- Fixes for random id used in controls with multiple instances and one call to setup
|
||||
- Audio player UI improvements
|
||||
|
||||
## v1.1.2
|
||||
- Added an onSetup callback option
|
||||
- Added fullscreen API methods toggleFullscreen() (must be user iniated), and isFullscreen()
|
||||
|
||||
## v1.1.1
|
||||
- Fix for unsupported browser handling
|
||||
- Fix for config.controls having no effect
|
||||
|
||||
## v1.1.0
|
||||
- Added config option to set which controls are shown (if using the default controls html) and better handling of missing controls
|
||||
|
||||
|
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.js
vendored
2
dist/plyr.js
vendored
File diff suppressed because one or more lines are too long
2
docs/dist/docs.js
vendored
2
docs/dist/docs.js
vendored
File diff suppressed because one or more lines are too long
@ -6,7 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Docs styles -->
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.0/docs.css">
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.4/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
|
@ -8,10 +8,10 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Styles -->
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.0/plyr.css">
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.4/plyr.css">
|
||||
|
||||
<!-- Docs styles -->
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.0/docs.css">
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.4/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
@ -83,13 +83,13 @@
|
||||
b.insertBefore(c, b.childNodes[0]);
|
||||
}
|
||||
}
|
||||
})(document, "https://cdn.plyr.io/1.1.0/sprite.svg");
|
||||
})(document, "https://cdn.plyr.io/1.1.4/sprite.svg");
|
||||
</script>
|
||||
|
||||
<!-- Plyr core script -->
|
||||
<script src="//cdn.plyr.io/1.1.0/plyr.js"></script>
|
||||
<script src="//cdn.plyr.io/1.1.4/plyr.js"></script>
|
||||
|
||||
<!-- Docs script -->
|
||||
<script src="//cdn.plyr.io/1.1.0/docs.js"></script>
|
||||
<script src="//cdn.plyr.io/1.1.4/docs.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -11,9 +11,21 @@ plyr.setup({
|
||||
html: templates.controls.render({}),
|
||||
captions: {
|
||||
defaultActive: true
|
||||
},
|
||||
onSetup: function() {
|
||||
var player = this,
|
||||
type = player.media.tagName.toLowerCase(),
|
||||
toggle = document.querySelector("[data-toggle='fullscreen']");
|
||||
|
||||
console.log("✓ Setup done for <" + type + ">");
|
||||
|
||||
if(type === "video" && toggle) {
|
||||
toggle.addEventListener("click", player.toggleFullscreen, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Google analytics
|
||||
// For demo site (http://[www.]plyr.io) only
|
||||
if(document.domain.indexOf("plyr.io") > -1) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.4",
|
||||
"description": "A simple HTML5 media player using custom controls",
|
||||
"homepage": "http://plyr.io",
|
||||
"main": "gulpfile.js",
|
||||
|
47
readme.md
47
readme.md
@ -3,14 +3,14 @@ A simple, accessible HTML5 media player.
|
||||
|
||||
[Checkout the demo](http://plyr.io)
|
||||
|
||||
[](http://plyr.io)
|
||||
[](http://plyr.io)
|
||||
|
||||
## Why?
|
||||
We wanted a lightweight, accessible and customisable media player that just supports *modern* browsers. Sure, there are many other players out there but we wanted to keep things simple, using the right elements for the job.
|
||||
|
||||
## Features
|
||||
- **Accessible** - full support for captions and screen readers.
|
||||
- **Lightweight** - just 6KB minified and gzipped.
|
||||
- **Lightweight** - just 6.4KB minified and gzipped.
|
||||
- **Customisable** - make the player look how you want with the markup you want.
|
||||
- **Semantic** - uses the *right* elements. `<input type="range">` for volume and `<progress>` for progress and well, `<button>`s for buttons. There's no `<span>` or `<a href="#">` button hacks.
|
||||
- **Responsive** - as you'd expect these days.
|
||||
@ -38,7 +38,7 @@ If you have any cool ideas or features, please let me know by [creating an issue
|
||||
|
||||
Check `docs/index.html` and `docs/dist/docs.js` for an example setup.
|
||||
|
||||
**Heads up**, the example `index.html` file needs to be served from a webserver (such as Apache, Nginx, IIS or similar) unless you change the file sources to include http or https. e.g. change `//cdn.plyr.io/1.1.0/plyr.js` to `https://cdn.plyr.io/1.1.0/plyr.js`
|
||||
**Heads up**, the example `index.html` file needs to be served from a webserver (such as Apache, Nginx, IIS or similar) unless you change the file sources to include http or https. e.g. change `//cdn.plyr.io/1.1.4/plyr.js` to `https://cdn.plyr.io/1.1.4/plyr.js`
|
||||
|
||||
### Bower
|
||||
If bower is your thang, you can grab Plyr using:
|
||||
@ -47,15 +47,22 @@ bower install plyr
|
||||
```
|
||||
More info on setting up dependencies can be found in the [Bower Docs](http://bower.io/docs/creating-packages/#maintaining-dependencies)
|
||||
|
||||
### Ember
|
||||
The awesome [@louisrudner](https://twitter.com/louisrudner) has created an ember component, available by running:
|
||||
```
|
||||
ember addon:install ember-cli-plyr
|
||||
```
|
||||
More info is on [npm](https://www.npmjs.com/package/ember-cli-plyr) and [GitHub](https://github.com/louisrudner/ember-cli-plyr)
|
||||
|
||||
### CDN
|
||||
If you want to use our CDN, you can use the following. HTTPS (SSL) is supported.
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.0/plyr.css">
|
||||
<script src="//cdn.plyr.io/1.1.0/plyr.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.4/plyr.css">
|
||||
<script src="//cdn.plyr.io/1.1.4/plyr.js"></script>
|
||||
```
|
||||
|
||||
You can also access the `sprite.svg` file at `//cdn.plyr.io/1.1.0/sprite.svg`.
|
||||
You can also access the `sprite.svg` file at `//cdn.plyr.io/1.1.4/sprite.svg`.
|
||||
|
||||
### CSS
|
||||
If you want to use the default css, add the `plyr.css` file from /dist into your head, or even better use `plyr.less` or `plyr.sass` file included in `/src` in your build to save a request.
|
||||
@ -130,7 +137,7 @@ You'll notice the `crossorigin` attribute on the example `<video>` and `<audio>`
|
||||
More info on CORS here:
|
||||
[https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
|
||||
|
||||
###JavaScript
|
||||
### JavaScript
|
||||
Much of the behaviour of the player is configurable when initialising the library. Below is an example of a default instance.
|
||||
|
||||
```html
|
||||
@ -240,6 +247,12 @@ You can pass the following options to the setup method.
|
||||
<td>—</td>
|
||||
<td>Two properties; <code>enabled</code> which toggles if local storage should be enabled (if the browser supports it). The default value is `true`. This enables storing user settings, currently it only stores volume but more will be added later. The second property <code>key</code> is the key used for the local storage. The default is <code>plyr_volume</code> until more settings are stored.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>onSetup</code></td>
|
||||
<td>Function</td>
|
||||
<td>—</td>
|
||||
<td>This callback function is called on every new plyr instance created. The context (<code>this</code>) is the plyr instance itself.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -307,6 +320,16 @@ Here's a list of the methods supported:
|
||||
<td>—</td>
|
||||
<td>Toggles whether captions are enabled.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>toggleFullscreen()</code></td>
|
||||
<td>Event</td>
|
||||
<td>Toggles fullscreen. This can only be initiated by a user gesture due to browser security, i.e. a user event such as click.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>isFullscreen()</code></td>
|
||||
<td>—</td>
|
||||
<td>Boolean returned if the player is in fullscreen.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>support(...)</code></td>
|
||||
<td>String</td>
|
||||
@ -327,7 +350,7 @@ Here's a list of the methods supported:
|
||||
This will inject a child `source` element for every element in the array with the specified attributes. `src` is the only required attribute although adding `type` is recommended as it helps the browser decide which file to download and play.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><code>poster(...)</code></td>
|
||||
<td>String</td>
|
||||
<td>Set the poster url. This is supported for the <code>video</code> element only.</td>
|
||||
@ -350,11 +373,12 @@ A complete list of events can be found here:
|
||||
[Media Events - W3.org](http://www.w3.org/2010/05/video/mediaevents.html)
|
||||
|
||||
## Fullscreen
|
||||
|
||||
Fullscreen in Plyr is supported for all browsers that [currently support it](http://caniuse.com/#feat=fullscreen). If you're using the default CSS, you can also use a "full browser" mode which will use the full browser window by adding the `player-fullscreen` class to your container.
|
||||
|
||||
## Browser support
|
||||
|
||||
<table width="100%" style="text-align: center;">
|
||||
<table width="100%" style="text-align: center">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Safari</td>
|
||||
@ -392,11 +416,14 @@ If a User Agent is disabled but supports `<video>` and `<audio>` natively, it wi
|
||||
|
||||
Any unsupported browsers will display links to download the media if the correct html is used.
|
||||
|
||||
### Checking for support
|
||||
There's an API method for checking support. You can call `plyr.supported()` and optionally pass a type to it, e.g. `plyr.supported("video")`. It will return an object with two keys; `basic` meaning there's basic support for that media type (or both if no type is passed) and `full` meaning there's full support for plyr.
|
||||
|
||||
## Issues
|
||||
If you find anything weird with Plyr, please let us know using the GitHub issues tracker.
|
||||
|
||||
## Author
|
||||
Plyr is developed by Sam Potts ([@sam_potts](https://twitter.com/sam_potts)) ([sampotts.me](http://sampotts.me))
|
||||
Plyr is developed by [@sam_potts](https://twitter.com/sam_potts) / [sampotts.me](http://sampotts.me)
|
||||
|
||||
## Mentions
|
||||
- [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/)
|
||||
|
177
src/js/plyr.js
177
src/js/plyr.js
@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v1.1.0
|
||||
// plyr.js v1.1.2
|
||||
// https://github.com/selz/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
@ -80,11 +80,12 @@
|
||||
enabled: true,
|
||||
key: "plyr_volume"
|
||||
},
|
||||
controls: ["restart", "rewind", "play", "fast-forward", "current-time", "duration", "mute", "volume", "captions", "fullscreen"]
|
||||
controls: ["restart", "rewind", "play", "fast-forward", "current-time", "duration", "mute", "volume", "captions", "fullscreen"],
|
||||
onSetup: function() {},
|
||||
};
|
||||
|
||||
// Build the default HTML
|
||||
defaults.html = (function() {
|
||||
function _buildControls() {
|
||||
// Open and add the progress and seek elements
|
||||
var html = [
|
||||
"<div class='player-controls'>",
|
||||
@ -101,7 +102,7 @@
|
||||
"<span class='player-controls-left'>"];
|
||||
|
||||
// Restart button
|
||||
if(_inArray(defaults.controls, "restart")) {
|
||||
if(_inArray(config.controls, "restart")) {
|
||||
html.push(
|
||||
"<button type='button' data-player='restart'>",
|
||||
"<svg><use xlink:href='#icon-restart'></use></svg>",
|
||||
@ -111,7 +112,7 @@
|
||||
}
|
||||
|
||||
// Rewind button
|
||||
if(_inArray(defaults.controls, "rewind")) {
|
||||
if(_inArray(config.controls, "rewind")) {
|
||||
html.push(
|
||||
"<button type='button' data-player='rewind'>",
|
||||
"<svg><use xlink:href='#icon-rewind'></use></svg>",
|
||||
@ -121,7 +122,7 @@
|
||||
}
|
||||
|
||||
// Play/pause button
|
||||
if(_inArray(defaults.controls, "play")) {
|
||||
if(_inArray(config.controls, "play")) {
|
||||
html.push(
|
||||
"<button type='button' data-player='play'>",
|
||||
"<svg><use xlink:href='#icon-play'></use></svg>",
|
||||
@ -135,7 +136,7 @@
|
||||
}
|
||||
|
||||
// Fast forward button
|
||||
if(_inArray(defaults.controls, "fast-forward")) {
|
||||
if(_inArray(config.controls, "fast-forward")) {
|
||||
html.push(
|
||||
"<button type='button' data-player='fast-forward'>",
|
||||
"<svg><use xlink:href='#icon-fast-forward'></use></svg>",
|
||||
@ -145,7 +146,7 @@
|
||||
}
|
||||
|
||||
// Media current time display
|
||||
if(_inArray(defaults.controls, "current-time")) {
|
||||
if(_inArray(config.controls, "current-time")) {
|
||||
html.push(
|
||||
"<span class='player-time'>",
|
||||
"<span class='sr-only'>Current time</span>",
|
||||
@ -155,7 +156,7 @@
|
||||
}
|
||||
|
||||
// Media duration display
|
||||
if(_inArray(defaults.controls, "duration")) {
|
||||
if(_inArray(config.controls, "duration")) {
|
||||
html.push(
|
||||
"<span class='player-time'>",
|
||||
"<span class='sr-only'>Duration</span>",
|
||||
@ -171,7 +172,7 @@
|
||||
);
|
||||
|
||||
// Toggle mute button
|
||||
if(_inArray(defaults.controls, "mute")) {
|
||||
if(_inArray(config.controls, "mute")) {
|
||||
html.push(
|
||||
"<input class='inverted sr-only' id='mute{id}' type='checkbox' data-player='mute'>",
|
||||
"<label id='mute{id}' for='mute{id}'>",
|
||||
@ -183,7 +184,7 @@
|
||||
}
|
||||
|
||||
// Volume range control
|
||||
if(_inArray(defaults.controls, "volume")) {
|
||||
if(_inArray(config.controls, "volume")) {
|
||||
html.push(
|
||||
"<label for='volume{id}' class='sr-only'>Volume</label>",
|
||||
"<input id='volume{id}' class='player-volume' type='range' min='0' max='10' value='5' data-player='volume'>"
|
||||
@ -191,7 +192,7 @@
|
||||
}
|
||||
|
||||
// Toggle captions button
|
||||
if(_inArray(defaults.controls, "captions")) {
|
||||
if(_inArray(config.controls, "captions")) {
|
||||
html.push(
|
||||
"<input class='sr-only' id='captions{id}' type='checkbox' data-player='captions'>",
|
||||
"<label for='captions{id}'>",
|
||||
@ -203,7 +204,7 @@
|
||||
}
|
||||
|
||||
// Toggle fullscreen button
|
||||
if(_inArray(defaults.controls, "fullscreen")) {
|
||||
if(_inArray(config.controls, "fullscreen")) {
|
||||
html.push(
|
||||
"<button type='button' data-player='fullscreen'>",
|
||||
"<svg class='icon-exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>",
|
||||
@ -220,7 +221,7 @@
|
||||
);
|
||||
|
||||
return html.join("");
|
||||
})();
|
||||
}
|
||||
|
||||
// Debugging
|
||||
function _log(text, error) {
|
||||
@ -234,8 +235,8 @@
|
||||
function _browserSniff() {
|
||||
var nAgt = navigator.userAgent,
|
||||
name = navigator.appName,
|
||||
fullVersion = ""+parseFloat(navigator.appVersion),
|
||||
majorVersion = parseInt(navigator.appVersion,10),
|
||||
fullVersion = "" + parseFloat(navigator.appVersion),
|
||||
majorVersion = parseInt(navigator.appVersion, 10),
|
||||
nameOffset,
|
||||
verOffset,
|
||||
ix;
|
||||
@ -248,46 +249,47 @@
|
||||
// MSIE
|
||||
else if ((verOffset=nAgt.indexOf("MSIE")) !== -1) {
|
||||
name = "IE";
|
||||
fullVersion = nAgt.substring(verOffset+5);
|
||||
fullVersion = nAgt.substring(verOffset + 5);
|
||||
}
|
||||
// Chrome
|
||||
else if ((verOffset=nAgt.indexOf("Chrome")) !== -1) {
|
||||
name = "Chrome";
|
||||
fullVersion = nAgt.substring(verOffset+7);
|
||||
fullVersion = nAgt.substring(verOffset + 7);
|
||||
}
|
||||
// Safari
|
||||
else if ((verOffset=nAgt.indexOf("Safari")) !== -1) {
|
||||
name = "Safari";
|
||||
fullVersion = nAgt.substring(verOffset+7);
|
||||
fullVersion = nAgt.substring(verOffset + 7);
|
||||
if ((verOffset=nAgt.indexOf("Version")) !== -1) {
|
||||
fullVersion = nAgt.substring(verOffset+8);
|
||||
fullVersion = nAgt.substring(verOffset + 8);
|
||||
}
|
||||
}
|
||||
// Firefox
|
||||
else if ((verOffset=nAgt.indexOf("Firefox")) !== -1) {
|
||||
name = "Firefox";
|
||||
fullVersion = nAgt.substring(verOffset+8);
|
||||
fullVersion = nAgt.substring(verOffset + 8);
|
||||
}
|
||||
// In most other browsers, "name/version" is at the end of userAgent
|
||||
else if ( (nameOffset=nAgt.lastIndexOf(" ")+1) < (verOffset=nAgt.lastIndexOf("/")) ) {
|
||||
else if ((nameOffset=nAgt.lastIndexOf(" ") + 1) < (verOffset=nAgt.lastIndexOf("/"))) {
|
||||
name = nAgt.substring(nameOffset,verOffset);
|
||||
fullVersion = nAgt.substring(verOffset+1);
|
||||
if (name.toLowerCase()==name.toUpperCase()) {
|
||||
fullVersion = nAgt.substring(verOffset + 1);
|
||||
|
||||
if (name.toLowerCase() == name.toUpperCase()) {
|
||||
name = navigator.appName;
|
||||
}
|
||||
}
|
||||
// Trim the fullVersion string at semicolon/space if present
|
||||
if ((ix=fullVersion.indexOf(";")) !== -1) {
|
||||
fullVersion=fullVersion.substring(0,ix);
|
||||
if ((ix = fullVersion.indexOf(";")) !== -1) {
|
||||
fullVersion = fullVersion.substring(0, ix);
|
||||
}
|
||||
if ((ix=fullVersion.indexOf(" ")) !== -1) {
|
||||
fullVersion=fullVersion.substring(0,ix);
|
||||
if ((ix = fullVersion.indexOf(" ")) !== -1) {
|
||||
fullVersion = fullVersion.substring(0, ix);
|
||||
}
|
||||
// Get major version
|
||||
majorVersion = parseInt(""+fullVersion,10);
|
||||
majorVersion = parseInt("" + fullVersion, 10);
|
||||
if (isNaN(majorVersion)) {
|
||||
fullVersion = ""+parseFloat(navigator.appVersion);
|
||||
majorVersion = parseInt(navigator.appVersion,10);
|
||||
fullVersion = "" + parseFloat(navigator.appVersion);
|
||||
majorVersion = parseInt(navigator.appVersion, 10);
|
||||
}
|
||||
|
||||
// Return data
|
||||
@ -330,7 +332,7 @@
|
||||
|
||||
// Element exists in an array
|
||||
function _inArray(haystack, needle) {
|
||||
return (haystack.indexOf(needle) != -1);
|
||||
return Array.prototype.indexOf && (haystack.indexOf(needle) != -1);
|
||||
}
|
||||
|
||||
// Replace all
|
||||
@ -340,7 +342,7 @@
|
||||
|
||||
// Wrap an element
|
||||
function _wrap(elements, wrapper) {
|
||||
// Convert `elms` to an array, if necessary.
|
||||
// Convert `elements` to an array, if necessary.
|
||||
if (!elements.length) {
|
||||
elements = [elements];
|
||||
}
|
||||
@ -348,16 +350,16 @@
|
||||
// Loops backwards to prevent having to clone the wrapper on the
|
||||
// first element (see `child` below).
|
||||
for (var i = elements.length - 1; i >= 0; i--) {
|
||||
var child = (i > 0) ? wrapper.cloneNode(true) : wrapper;
|
||||
var el = elements[i];
|
||||
var child = (i > 0) ? wrapper.cloneNode(true) : wrapper;
|
||||
var element = elements[i];
|
||||
|
||||
// Cache the current parent and sibling.
|
||||
var parent = el.parentNode;
|
||||
var sibling = el.nextSibling;
|
||||
var parent = element.parentNode;
|
||||
var sibling = element.nextSibling;
|
||||
|
||||
// Wrap the element (is automatically removed from its current
|
||||
// parent).
|
||||
child.appendChild(el);
|
||||
child.appendChild(element);
|
||||
|
||||
// If the element had a sibling, insert the wrapper before
|
||||
// the sibling to maintain the HTML structure; otherwise, just
|
||||
@ -519,7 +521,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Safari doesn't support the ALLOW_KEYBOARD_INPUT flag so set it to not supported
|
||||
// Safari doesn't support the ALLOW_KEYBOARD_INPUT flag (for security) so set it to not supported
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=121496
|
||||
if(fullscreen.prefix === "webkit" && !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/)) {
|
||||
fullscreen.supportsFullScreen = false;
|
||||
@ -531,19 +533,16 @@
|
||||
// Sometimes the prefix is "ms", sometimes "MS" to keep you on your toes
|
||||
fullscreen.fullScreenEventName = (fullscreen.prefix == "ms" ? "MSFullscreenChange" : fullscreen.prefix + "fullscreenchange");
|
||||
|
||||
fullscreen.isFullScreen = function() {
|
||||
fullscreen.isFullScreen = function(element) {
|
||||
if(typeof element == "undefined") {
|
||||
element = document;
|
||||
}
|
||||
|
||||
switch (this.prefix) {
|
||||
case "":
|
||||
return document.fullScreen;
|
||||
case "webkit":
|
||||
return document.webkitIsFullScreen;
|
||||
case "ms":
|
||||
// Docs say document.msFullScreenElement returns undefined
|
||||
// if no element is full screem but it returns null, cheers
|
||||
// https://msdn.microsoft.com/en-us/library/ie/dn265028%28v=vs.85%29.aspx
|
||||
return (document.msFullscreenElement !== null);
|
||||
return document.fullscreenElement == element;
|
||||
default:
|
||||
return document[this.prefix + "FullScreen"];
|
||||
return document[this.prefix + "FullscreenElement"] == element;
|
||||
}
|
||||
};
|
||||
fullscreen.requestFullScreen = function(element) {
|
||||
@ -681,22 +680,25 @@
|
||||
|
||||
// Insert controls
|
||||
function _injectControls() {
|
||||
// Make a copy of the html
|
||||
var html = config.html;
|
||||
|
||||
// Insert custom video controls
|
||||
_log("Injecting custom controls.");
|
||||
|
||||
// If no controls are specified, bail
|
||||
if(!config.html) {
|
||||
return;
|
||||
// If no controls are specified, create default
|
||||
if(!html) {
|
||||
html = _buildControls();
|
||||
}
|
||||
|
||||
// Replace seek time instances
|
||||
config.html = _replaceAll(config.html, "{seektime}", config.seekTime);
|
||||
html = _replaceAll(html, "{seektime}", config.seekTime);
|
||||
|
||||
// Replace all id references
|
||||
config.html = _replaceAll(config.html, "{id}", player.random);
|
||||
// Replace all id references with random numbers
|
||||
html = _replaceAll(html, "{id}", Math.floor(Math.random() * (10000)));
|
||||
|
||||
// Inject into the container
|
||||
player.container.insertAdjacentHTML("beforeend", config.html);
|
||||
player.container.insertAdjacentHTML("beforeend", html);
|
||||
|
||||
// Setup tooltips
|
||||
if(config.tooltips) {
|
||||
@ -1035,7 +1037,7 @@
|
||||
targetTime = input;
|
||||
}
|
||||
// Event
|
||||
else if (typeof input === "object" && (input.type === "change" || input.type === "input")) {
|
||||
else if (typeof input === "object" && (input.type === "input" || input.type === "change")) {
|
||||
// It's the seek slider
|
||||
// Seek to the selected time
|
||||
targetTime = ((input.target.value / input.target.max) * player.media.duration);
|
||||
@ -1076,12 +1078,12 @@
|
||||
|
||||
// If it's a fullscreen change event, it's probably a native close
|
||||
if(event && event.type === fullscreen.fullScreenEventName) {
|
||||
config.fullscreen.active = fullscreen.isFullScreen();
|
||||
player.isFullscreen = fullscreen.isFullScreen(player.container);
|
||||
}
|
||||
// If there's native support, use it
|
||||
else if(nativeSupport) {
|
||||
// Request fullscreen
|
||||
if(!fullscreen.isFullScreen()) {
|
||||
if(!fullscreen.isFullScreen(player.container)) {
|
||||
fullscreen.requestFullScreen(player.container);
|
||||
}
|
||||
// Bail from fullscreen
|
||||
@ -1090,14 +1092,14 @@
|
||||
}
|
||||
|
||||
// Check if we're actually full screen (it could fail)
|
||||
config.fullscreen.active = fullscreen.isFullScreen();
|
||||
player.isFullscreen = fullscreen.isFullScreen(player.container);
|
||||
}
|
||||
else {
|
||||
// Otherwise, it's a simple toggle
|
||||
config.fullscreen.active = !config.fullscreen.active;
|
||||
player.isFullscreen = !player.isFullscreen;
|
||||
|
||||
// Bind/unbind escape key
|
||||
if(config.fullscreen.active) {
|
||||
if(player.isFullscreen) {
|
||||
_on(document, "keyup", _handleEscapeFullscreen);
|
||||
document.body.style.overflow = "hidden";
|
||||
}
|
||||
@ -1108,13 +1110,18 @@
|
||||
}
|
||||
|
||||
// Set class hook
|
||||
_toggleClass(player.container, config.classes.fullscreen.active, config.fullscreen.active);
|
||||
_toggleClass(player.container, config.classes.fullscreen.active, player.isFullscreen);
|
||||
|
||||
// Remove hover class because mouseleave doesn't occur
|
||||
if (player.isFullscreen) {
|
||||
_toggleClass(player.controls, config.classes.hover, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Bail from faux-fullscreen
|
||||
function _handleEscapeFullscreen(event) {
|
||||
// If it's a keypress and not escape, bail
|
||||
if((event.which || event.charCode || event.keyCode) === 27 && config.fullscreen.active) {
|
||||
if((event.which || event.charCode || event.keyCode) === 27 && player.isFullscreen) {
|
||||
_toggleFullscreen();
|
||||
}
|
||||
}
|
||||
@ -1153,7 +1160,7 @@
|
||||
|
||||
// Store the volume in storage
|
||||
if(config.storage.enabled && _storage().supported) {
|
||||
window.localStorage.plyr_volume = volume;
|
||||
window.localStorage.setItem(config.storage.key, volume);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1391,6 +1398,9 @@
|
||||
|
||||
// Listen for events
|
||||
function _listeners() {
|
||||
// IE doesn't support input event, so we fallback to change
|
||||
var inputEvent = (player.browser.name == "IE" ? "change" : "input");
|
||||
|
||||
// Play
|
||||
_on(player.buttons.play, "click", function() {
|
||||
_play();
|
||||
@ -1412,9 +1422,11 @@
|
||||
// Fast forward
|
||||
_on(player.buttons.forward, "click", _forward);
|
||||
|
||||
// Get the HTML5 range input element and append audio volume adjustment on change/input
|
||||
// IE10 doesn't support the "input" event so they have to wait for change
|
||||
_on(player.volume, "change input", function() {
|
||||
// Seek
|
||||
_on(player.buttons.seek, inputEvent, _seek);
|
||||
|
||||
// Set volume
|
||||
_on(player.volume, inputEvent, function() {
|
||||
_setVolume(this.value);
|
||||
});
|
||||
|
||||
@ -1440,9 +1452,6 @@
|
||||
// Display duration
|
||||
_on(player.media, "loadedmetadata", _displayDuration);
|
||||
|
||||
// Seek
|
||||
_on(player.buttons.seek, "change input", _seek);
|
||||
|
||||
// Captions
|
||||
_on(player.buttons.captions, "change", function() {
|
||||
_toggleCaptions(this.checked);
|
||||
@ -1481,14 +1490,14 @@
|
||||
if(player.type === "video" && config.click) {
|
||||
_on(player.videoContainer, "click", function() {
|
||||
if(player.media.paused) {
|
||||
_play();
|
||||
_triggerEvent(player.buttons.play, "click");
|
||||
}
|
||||
else if(player.media.ended) {
|
||||
_seek();
|
||||
_play();
|
||||
_triggerEvent(player.buttons.play, "click");
|
||||
}
|
||||
else {
|
||||
_pause();
|
||||
_triggerEvent(player.buttons.pause, "click");
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1497,7 +1506,7 @@
|
||||
if(config.fullscreen.hideControls) {
|
||||
_on(player.controls, "mouseenter mouseleave", function(event) {
|
||||
_toggleClass(player.controls, config.classes.hover, (event.type === "mouseenter"));
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1528,9 +1537,6 @@
|
||||
// Setup media
|
||||
_setupMedia();
|
||||
|
||||
// Generate random number for id/for attribute values for controls
|
||||
player.random = Math.floor(Math.random() * (10000));
|
||||
|
||||
// If there's full support
|
||||
if(player.supported.full) {
|
||||
// Inject custom controls
|
||||
@ -1578,11 +1584,13 @@
|
||||
rewind: _rewind,
|
||||
forward: _forward,
|
||||
seek: _seek,
|
||||
source: _parseSource,
|
||||
poster: _updatePoster,
|
||||
setVolume: _setVolume,
|
||||
toggleMute: _toggleMute,
|
||||
toggleCaptions: _toggleCaptions,
|
||||
source: _parseSource,
|
||||
poster: _updatePoster,
|
||||
toggleFullscreen: _toggleFullscreen,
|
||||
isFullscreen: function() { return player.isFullscreen || false; },
|
||||
support: function(mimeType) { return _supportMime(player, mimeType); }
|
||||
}
|
||||
}
|
||||
@ -1624,7 +1632,7 @@
|
||||
// Extend the default options with user specified
|
||||
config = _extend(defaults, options);
|
||||
|
||||
// If enabled carry on
|
||||
// Bail if disabled or no basic support
|
||||
// You may want to disable certain UAs etc
|
||||
if(!config.enabled || !api.supported().basic) {
|
||||
return false;
|
||||
@ -1646,13 +1654,16 @@
|
||||
|
||||
// Set plyr to false if setup failed
|
||||
element.plyr = (Object.keys(instance).length ? instance : false);
|
||||
|
||||
// Callback
|
||||
config.onSetup.apply(element.plyr);
|
||||
}
|
||||
|
||||
// Add to return array
|
||||
// Add to return array even if it's already setup
|
||||
players.push(element.plyr);
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
}(this.plyr = this.plyr || {}));
|
||||
}(this.plyr = this.plyr || {}));
|
||||
|
@ -9,6 +9,7 @@
|
||||
@gray-dark: #343f4a;
|
||||
@gray: #565d64;
|
||||
@gray-light: #cbd0d3;
|
||||
@off-white: #d6dadd;
|
||||
|
||||
// Font sizes
|
||||
@font-size-small: 14px;
|
||||
@ -527,6 +528,17 @@
|
||||
float: none;
|
||||
}
|
||||
|
||||
// Audio specific styles
|
||||
// Position the progress within the container
|
||||
&-audio .player-controls {
|
||||
padding-top: (@control-spacing * 2);
|
||||
}
|
||||
&-audio .player-progress {
|
||||
bottom: auto;
|
||||
top: 0;
|
||||
background: @off-white;
|
||||
}
|
||||
|
||||
// Full screen mode
|
||||
&-fullscreen,
|
||||
&.fullscreen-active {
|
||||
|
@ -9,6 +9,7 @@ $blue: #3498DB;
|
||||
$gray-dark: #343f4a;
|
||||
$gray: #565d64;
|
||||
$gray-light: #cbd0d3;
|
||||
$off-white: #d6dadd;
|
||||
|
||||
// Font sizes
|
||||
$font-size-small: 14px;
|
||||
@ -535,6 +536,17 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
float: none;
|
||||
}
|
||||
|
||||
// Audio specific styles
|
||||
// Position the progress within the container
|
||||
&-audio .player-controls {
|
||||
padding-top: ($control-spacing * 2);
|
||||
}
|
||||
&-audio .player-progress {
|
||||
bottom: auto;
|
||||
top: 0;
|
||||
background: $off-white;
|
||||
}
|
||||
|
||||
// Full screen mode
|
||||
&-fullscreen,
|
||||
&.fullscreen-active {
|
||||
|
Reference in New Issue
Block a user