Compare commits

...

5 Commits

Author SHA1 Message Date
Sam Potts b677c3d7ad Merge branch 'master' of https://github.com/selz/plyr
Conflicts:
	dist/plyr.js
	src/js/plyr.js
2015-03-10 23:57:36 +11:00
Sam Potts aa6bc2df2f Fixes for volume control on iOS 2015-03-10 23:54:52 +11:00
Sam Potts a16579fd21 Fix for repo url 2015-03-09 11:53:26 +11:00
Sam Potts ae5a816df1 Fix for potential issue with .tagName 2015-03-09 11:51:01 +11:00
Sam Potts 1532f2ab23 Added tooltip option (Fixes #50) 2015-03-09 00:47:38 +11:00
14 changed files with 253 additions and 77 deletions
+12 -5
View File
@@ -1,17 +1,24 @@
# Changelog # Changelog
## v1.0.25
- Fixes for iOS volume controls (hidden)
- Classnames for left/right controls changed
## v1.0.24
- Added tooltip option to display labels as tooltips (Fixes #50)
## v1.0.23 ## v1.0.23
- Handling loading states in the UI - Handling loading states in the UI (Fixes #36)
## v1.0.22 ## v1.0.22
- Added support() API method for checking mimetype support - Added support() API method for checking mimetype support
- Added source() API method for setting media source(s) - Added source() API method for setting media source(s) (Fixes #44)
- Added poster() API method for setting poster source - Added poster() API method for setting poster source
- Refactored captions logic for manual captions - Refactored captions logic for manual captions
## v1.0.21 ## v1.0.21
- Added an <input type="range"> for seeking to improve experience (and support dragging) - Added an <input type="range"> for seeking to improve experience (and support dragging) (Fixes #40, #42)
- Icons for restart and captions improved (and some IDs changed) - Icons for restart and captions improved (and some IDs changed) (Fixes #49)
## v1.0.20 ## v1.0.20
- Default controls included (Fixes #45) - Default controls included (Fixes #45)
@@ -20,7 +27,7 @@
- License changed to MIT - License changed to MIT
## v1.0.19 ## v1.0.19
- Fixed firefox fullscreen issue (#38) - Fixed firefox fullscreen issue (Fixes #38)
## v1.0.18 ## v1.0.18
- Added CDN references - Added CDN references
+5 -5
View File
@@ -31,14 +31,14 @@ This is the default `html` option from `plyr.js`.
"<span>0</span>% buffered", "<span>0</span>% buffered",
"</progress>", "</progress>",
"</div>", "</div>",
"<span class='player-controls-playback'>", "<span class='player-controls-left'>",
"<button type='button' data-player='restart'>", "<button type='button' data-player='restart'>",
"<svg><use xlink:href='#icon-restart'></use></svg>", "<svg><use xlink:href='#icon-restart'></use></svg>",
"<span class='sr-only'>Restart</span>", "<span class='sr-only'>Restart</span>",
"</button>", "</button>",
"<button type='button' data-player='rewind'>", "<button type='button' data-player='rewind'>",
"<svg><use xlink:href='#icon-rewind'></use></svg>", "<svg><use xlink:href='#icon-rewind'></use></svg>",
"<span class='sr-only'>Rewind {seektime} seconds</span>", "<span class='sr-only'>Rewind {seektime} secs</span>",
"</button>", "</button>",
"<button type='button' data-player='play'>", "<button type='button' data-player='play'>",
"<svg><use xlink:href='#icon-play'></use></svg>", "<svg><use xlink:href='#icon-play'></use></svg>",
@@ -50,14 +50,14 @@ This is the default `html` option from `plyr.js`.
"</button>", "</button>",
"<button type='button' data-player='fast-forward'>", "<button type='button' data-player='fast-forward'>",
"<svg><use xlink:href='#icon-fast-forward'></use></svg>", "<svg><use xlink:href='#icon-fast-forward'></use></svg>",
"<span class='sr-only'>Fast forward {seektime} seconds</span>", "<span class='sr-only'>Forward {seektime} secs</span>",
"</button>", "</button>",
"<span class='player-time'>", "<span class='player-time'>",
"<span class='sr-only'>Time</span>", "<span class='sr-only'>Time</span>",
"<span class='player-duration'>00:00</span>", "<span class='player-duration'>00:00</span>",
"</span>", "</span>",
"</span>", "</span>",
"<span class='player-controls-sound'>", "<span class='player-controls-right'>",
"<input class='inverted sr-only' id='mute{id}' type='checkbox' data-player='mute'>", "<input class='inverted sr-only' id='mute{id}' type='checkbox' data-player='mute'>",
"<label id='mute{id}' for='mute{id}'>", "<label id='mute{id}' for='mute{id}'>",
"<svg class='icon-muted'><use xlink:href='#icon-muted'></use></svg>", "<svg class='icon-muted'><use xlink:href='#icon-muted'></use></svg>",
@@ -75,7 +75,7 @@ This is the default `html` option from `plyr.js`.
"<button type='button' data-player='fullscreen'>", "<button type='button' data-player='fullscreen'>",
"<svg class='icon-exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>", "<svg class='icon-exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>",
"<svg><use xlink:href='#icon-enter-fullscreen'></use></svg>", "<svg><use xlink:href='#icon-enter-fullscreen'></use></svg>",
"<span class='sr-only'>Toggle fullscreen</span>", "<span class='sr-only'>Toggle Fullscreen</span>",
"</button>", "</button>",
"</span>", "</span>",
"</div>"].join("\n"); "</div>"].join("\n");
+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 -1
View File
@@ -1,2 +1,2 @@
var templates = {}; var templates = {};
templates['controls'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"player-controls\">");t.b("\n" + i);t.b(" <div class=\"player-progress\">");t.b("\n" + i);t.b(" <label for=\"seek{id}\" class=\"sr-only\">Seek</label>");t.b("\n" + i);t.b(" <input id=\"seek{id}\" class=\"player-progress-seek\" type=\"range\" min=\"0\" max=\"100\" step=\"0.5\" value=\"0\" data-player=\"seek\">");t.b("\n" + i);t.b(" <progress class=\"player-progress-played\" max=\"100\" value=\"0\">");t.b("\n" + i);t.b(" <span>0</span>% played");t.b("\n" + i);t.b(" </progress>");t.b("\n" + i);t.b(" <progress class=\"player-progress-buffer\" max=\"100\" value=\"0\">");t.b("\n" + i);t.b(" <span>0</span>% buffered");t.b("\n" + i);t.b(" </progress>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" <span class=\"player-controls-playback\">");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"restart\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-restart\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Restart</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"rewind\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-rewind\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Rewind {seektime} seconds</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"play\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-play\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Play</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"pause\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-pause\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Pause</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"fast-forward\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-fast-forward\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Fast forward {seektime} seconds</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <span class=\"player-time\">");t.b("\n" + i);t.b(" <span class=\"sr-only\">Time</span>");t.b("\n" + i);t.b(" <span class=\"player-duration\">00:00</span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" <span class=\"player-controls-sound\">");t.b("\n" + i);t.b(" <input class=\"inverted sr-only\" id=\"mute{id}\" type=\"checkbox\" data-player=\"mute\">");t.b("\n" + i);t.b(" <label id=\"mute{id}\" for=\"mute{id}\">");t.b("\n" + i);t.b(" <svg class=\"icon-muted\"><use xlink:href=\"#icon-muted\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-volume\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Mute</span>");t.b("\n" + i);t.b(" </label>");t.b("\n");t.b("\n" + i);t.b(" <label for=\"volume{id}\" class=\"sr-only\">Volume</label>");t.b("\n" + i);t.b(" <input id=\"volume{id}\" class=\"player-volume\" type=\"range\" min=\"0\" max=\"10\" step=\"0.5\" value=\"0\" data-player=\"volume\">");t.b("\n");t.b("\n" + i);t.b(" <input class=\"sr-only\" id=\"captions{id}\" type=\"checkbox\" data-player=\"captions\">");t.b("\n" + i);t.b(" <label for=\"captions{id}\">");t.b("\n" + i);t.b(" <svg class=\"icon-captions-on\"><use xlink:href=\"#icon-captions-on\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-captions-off\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Captions</span>");t.b("\n" + i);t.b(" </label>");t.b("\n");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"fullscreen\">");t.b("\n" + i);t.b(" <svg class=\"icon-exit-fullscreen\"><use xlink:href=\"#icon-exit-fullscreen\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-enter-fullscreen\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle fullscreen</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }}); templates['controls'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"player-controls\">");t.b("\n" + i);t.b(" <div class=\"player-progress\">");t.b("\n" + i);t.b(" <label for=\"seek{id}\" class=\"sr-only\">Seek</label>");t.b("\n" + i);t.b(" <input id=\"seek{id}\" class=\"player-progress-seek\" type=\"range\" min=\"0\" max=\"100\" step=\"0.5\" value=\"0\" data-player=\"seek\">");t.b("\n" + i);t.b(" <progress class=\"player-progress-played\" max=\"100\" value=\"0\">");t.b("\n" + i);t.b(" <span>0</span>% played");t.b("\n" + i);t.b(" </progress>");t.b("\n" + i);t.b(" <progress class=\"player-progress-buffer\" max=\"100\" value=\"0\">");t.b("\n" + i);t.b(" <span>0</span>% buffered");t.b("\n" + i);t.b(" </progress>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" <span class=\"player-controls-left\">");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"restart\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-restart\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Restart</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"rewind\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-rewind\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Rewind {seektime} secs</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"play\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-play\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Play</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"pause\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-pause\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Pause</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"fast-forward\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-fast-forward\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Forward {seektime} secs</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <span class=\"player-time\">");t.b("\n" + i);t.b(" <span class=\"sr-only\">Time</span>");t.b("\n" + i);t.b(" <span class=\"player-duration\">00:00</span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" <span class=\"player-controls-right\">");t.b("\n" + i);t.b(" <input class=\"inverted sr-only\" id=\"mute{id}\" type=\"checkbox\" data-player=\"mute\">");t.b("\n" + i);t.b(" <label id=\"mute{id}\" for=\"mute{id}\">");t.b("\n" + i);t.b(" <svg class=\"icon-muted\"><use xlink:href=\"#icon-muted\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-volume\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Mute</span>");t.b("\n" + i);t.b(" </label>");t.b("\n");t.b("\n" + i);t.b(" <label for=\"volume{id}\" class=\"sr-only\">Volume</label>");t.b("\n" + i);t.b(" <input id=\"volume{id}\" class=\"player-volume\" type=\"range\" min=\"0\" max=\"10\" step=\"0.5\" value=\"0\" data-player=\"volume\">");t.b("\n");t.b("\n" + i);t.b(" <input class=\"sr-only\" id=\"captions{id}\" type=\"checkbox\" data-player=\"captions\">");t.b("\n" + i);t.b(" <label for=\"captions{id}\">");t.b("\n" + i);t.b(" <svg class=\"icon-captions-on\"><use xlink:href=\"#icon-captions-on\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-captions-off\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Captions</span>");t.b("\n" + i);t.b(" </label>");t.b("\n");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"fullscreen\">");t.b("\n" + i);t.b(" <svg class=\"icon-exit-fullscreen\"><use xlink:href=\"#icon-exit-fullscreen\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-enter-fullscreen\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Fullscreen</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }});
+1 -1
View File
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Docs styles --> <!-- Docs styles -->
<link rel="stylesheet" href="//cdn.plyr.io/1.0.23/docs.css"> <link rel="stylesheet" href="//cdn.plyr.io/1.0.25/docs.css">
</head> </head>
<body> <body>
<main> <main>
+5 -5
View File
@@ -8,10 +8,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Styles --> <!-- Styles -->
<link rel="stylesheet" href="//cdn.plyr.io/1.0.23/plyr.css"> <link rel="stylesheet" href="//cdn.plyr.io/1.0.25/plyr.css">
<!-- Docs styles --> <!-- Docs styles -->
<link rel="stylesheet" href="//cdn.plyr.io/1.0.23/docs.css"> <link rel="stylesheet" href="//cdn.plyr.io/1.0.25/docs.css">
</head> </head>
<body> <body>
<header> <header>
@@ -67,13 +67,13 @@
<!-- Load SVG defs --> <!-- Load SVG defs -->
<!-- You should bundle all SVG/Icons into one file using a build tool such as gulp and svg store --> <!-- You should bundle all SVG/Icons into one file using a build tool such as gulp and svg store -->
<script> <script>
(function(d,p){var a=new XMLHttpRequest(),b=d.body;a.open("GET",p,!0);a.send();a.onload=function(){var c=d.createElement("div");c.style.display="none";c.innerHTML=a.responseText;b.insertBefore(c,b.childNodes[0])}})(document,"//cdn.plyr.io/1.0.23/sprite.svg"); (function(d,p){var a=new XMLHttpRequest(),b=d.body;a.open("GET",p,!0);a.send();a.onload=function(){var c=d.createElement("div");c.style.display="none";c.innerHTML=a.responseText;b.insertBefore(c,b.childNodes[0])}})(document,"//cdn.plyr.io/1.0.25/sprite.svg");
</script> </script>
<!-- Plyr core script --> <!-- Plyr core script -->
<script src="//cdn.plyr.io/1.0.23/plyr.js"></script> <script src="//cdn.plyr.io/1.0.25/plyr.js"></script>
<!-- Docs script --> <!-- Docs script -->
<script src="//cdn.plyr.io/1.0.23/docs.js"></script> <script src="//cdn.plyr.io/1.0.25/docs.js"></script>
</body> </body>
</html> </html>
+5 -5
View File
@@ -9,14 +9,14 @@
<span>0</span>% buffered <span>0</span>% buffered
</progress> </progress>
</div> </div>
<span class="player-controls-playback"> <span class="player-controls-left">
<button type="button" data-player="restart"> <button type="button" data-player="restart">
<svg><use xlink:href="#icon-restart"></use></svg> <svg><use xlink:href="#icon-restart"></use></svg>
<span class="sr-only">Restart</span> <span class="sr-only">Restart</span>
</button> </button>
<button type="button" data-player="rewind"> <button type="button" data-player="rewind">
<svg><use xlink:href="#icon-rewind"></use></svg> <svg><use xlink:href="#icon-rewind"></use></svg>
<span class="sr-only">Rewind {seektime} seconds</span> <span class="sr-only">Rewind {seektime} secs</span>
</button> </button>
<button type="button" data-player="play"> <button type="button" data-player="play">
<svg><use xlink:href="#icon-play"></use></svg> <svg><use xlink:href="#icon-play"></use></svg>
@@ -28,14 +28,14 @@
</button> </button>
<button type="button" data-player="fast-forward"> <button type="button" data-player="fast-forward">
<svg><use xlink:href="#icon-fast-forward"></use></svg> <svg><use xlink:href="#icon-fast-forward"></use></svg>
<span class="sr-only">Fast forward {seektime} seconds</span> <span class="sr-only">Forward {seektime} secs</span>
</button> </button>
<span class="player-time"> <span class="player-time">
<span class="sr-only">Time</span> <span class="sr-only">Time</span>
<span class="player-duration">00:00</span> <span class="player-duration">00:00</span>
</span> </span>
</span> </span>
<span class="player-controls-sound"> <span class="player-controls-right">
<input class="inverted sr-only" id="mute{id}" type="checkbox" data-player="mute"> <input class="inverted sr-only" id="mute{id}" type="checkbox" data-player="mute">
<label id="mute{id}" for="mute{id}"> <label id="mute{id}" for="mute{id}">
<svg class="icon-muted"><use xlink:href="#icon-muted"></use></svg> <svg class="icon-muted"><use xlink:href="#icon-muted"></use></svg>
@@ -56,7 +56,7 @@
<button type="button" data-player="fullscreen"> <button type="button" data-player="fullscreen">
<svg class="icon-exit-fullscreen"><use xlink:href="#icon-exit-fullscreen"></use></svg> <svg class="icon-exit-fullscreen"><use xlink:href="#icon-exit-fullscreen"></use></svg>
<svg><use xlink:href="#icon-enter-fullscreen"></use></svg> <svg><use xlink:href="#icon-enter-fullscreen"></use></svg>
<span class="sr-only">Toggle fullscreen</span> <span class="sr-only">Toggle Fullscreen</span>
</button> </button>
</span> </span>
</div> </div>
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "plyr", "name": "plyr",
"version": "1.0.23", "version": "1.0.25",
"description": "A simple HTML5 media player using custom controls", "description": "A simple HTML5 media player using custom controls",
"homepage": "http://plyr.io", "homepage": "http://plyr.io",
"main": "gulpfile.js", "main": "gulpfile.js",
+14 -8
View File
@@ -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. 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.0.23/plyr.js` to `https://cdn.plyr.io/1.0.23/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.0.25/plyr.js` to `https://cdn.plyr.io/1.0.25/plyr.js`
### Bower ### Bower
If bower is your thang, you can grab Plyr using: If bower is your thang, you can grab Plyr using:
@@ -51,11 +51,11 @@ More info on setting up dependencies can be found in the [Bower Docs](http://bow
If you want to use our CDN, you can use the following. HTTPS (SSL) is supported. If you want to use our CDN, you can use the following. HTTPS (SSL) is supported.
```html ```html
<link rel="stylesheet" href="//cdn.plyr.io/1.0.23/plyr.css"> <link rel="stylesheet" href="//cdn.plyr.io/1.0.25/plyr.css">
<script src="//cdn.plyr.io/1.0.23/plyr.js"></script> <script src="//cdn.plyr.io/1.0.25/plyr.js"></script>
``` ```
You can also access the `sprite.svg` file at `//cdn.plyr.io/1.0.23/sprite.svg`. You can also access the `sprite.svg` file at `//cdn.plyr.io/1.0.25/sprite.svg`.
### CSS ### 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. 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.
@@ -192,6 +192,12 @@ You can pass the following options to the setup method.
<td><code>true</code></td> <td><code>true</code></td>
<td>Click (or tap) will toggle pause/play of a <code>&lt;video&gt;</code>.</td> <td>Click (or tap) will toggle pause/play of a <code>&lt;video&gt;</code>.</td>
</tr> </tr>
<tr>
<td><code>tooltips</code></td>
<td>Boolean</td>
<td><code>false</code></td>
<td>Display control labels as tooltips on :hover &amp; :focus (by default, the labels are screen reader only).</td>
</tr>
<tr> <tr>
<td><code>selectors</code></td> <td><code>selectors</code></td>
<td>Object</td> <td>Object</td>
@@ -208,19 +214,19 @@ You can pass the following options to the setup method.
<td><code>captions</code></td> <td><code>captions</code></td>
<td>Object</td> <td>Object</td>
<td>&mdash;</td> <td>&mdash;</td>
<td>This currently contains one property `defaultActive` which toggles if captions should be on by default. The default value is <code>false</code>.</td> <td>One property <code>defaultActive</code> which toggles if captions should be on by default. The default value is <code>false</code>.</td>
</tr> </tr>
<tr> <tr>
<td><code>fullscreen</code></td> <td><code>fullscreen</code></td>
<td>Object</td> <td>Object</td>
<td>&mdash;</td> <td>&mdash;</td>
<td>This currently contains two properties;<code>enabled</code> which toggles if fullscreen should be enabled (if the browser supports it). The default value is <code>true</code>. Also an extra property called <code>fallback</code> which will enable a full window view for older browsers. The default value is <code>true</code>.</td> <td>Two properties; <code>enabled</code> which toggles if fullscreen should be enabled (if the browser supports it). The default value is <code>true</code>. Also an extra property called <code>fallback</code> which will enable a full window view for older browsers. The default value is <code>true</code>.</td>
</tr> </tr>
<tr> <tr>
<td><code>storage</code></td> <td><code>storage</code></td>
<td>Object</td> <td>Object</td>
<td>&mdash;</td> <td>&mdash;</td>
<td>This currently contains one property `enabled` 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.</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>
</tbody> </tbody>
</table> </table>
@@ -359,7 +365,7 @@ Fullscreen in Plyr is supported for all browsers that [currently support it](htt
</tbody> </tbody>
</table> </table>
&sup1; iPhone forces the native player for `<video>` so no customisation possible &sup1; iPhone forces the native player for `<video>` so no customisation possible. `<audio>` elements have volume controls disabled.
&sup2; Native player used (no support for `<progress>` or `<input type="range">`) &sup2; Native player used (no support for `<progress>` or `<input type="range">`)
+59 -33
View File
@@ -1,7 +1,7 @@
// ========================================================================== // ==========================================================================
// Plyr // Plyr
// plyr.js v1.0.23 // plyr.js v1.0.25
// https://github.com/sampotts/plyr // https://github.com/selz/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
// Credits: http://paypal.github.io/accessible-html5-video-player/ // Credits: http://paypal.github.io/accessible-html5-video-player/
@@ -20,9 +20,11 @@
seekTime: 10, seekTime: 10,
volume: 5, volume: 5,
click: true, click: true,
tooltips: false,
selectors: { selectors: {
container: ".player", container: ".player",
controls: ".player-controls", controls: ".player-controls",
labels: "[data-player] .sr-only, label .sr-only",
buttons: { buttons: {
seek: "[data-player='seek']", seek: "[data-player='seek']",
play: "[data-player='play']", play: "[data-player='play']",
@@ -51,6 +53,8 @@
playing: "playing", playing: "playing",
muted: "muted", muted: "muted",
loading: "loading", loading: "loading",
tooltip: "player-tooltip",
hidden: "sr-only",
captions: { captions: {
enabled: "captions-enabled", enabled: "captions-enabled",
active: "captions-active" active: "captions-active"
@@ -68,7 +72,8 @@
fallback: true fallback: true
}, },
storage: { storage: {
enabled: true enabled: true,
key: "plyr_volume"
}, },
html: (function() { html: (function() {
return [ return [
@@ -83,14 +88,14 @@
"<span>0</span>% buffered", "<span>0</span>% buffered",
"</progress>", "</progress>",
"</div>", "</div>",
"<span class='player-controls-playback'>", "<span class='player-controls-left'>",
"<button type='button' data-player='restart'>", "<button type='button' data-player='restart'>",
"<svg><use xlink:href='#icon-restart'></use></svg>", "<svg><use xlink:href='#icon-restart'></use></svg>",
"<span class='sr-only'>Restart</span>", "<span class='sr-only'>Restart</span>",
"</button>", "</button>",
"<button type='button' data-player='rewind'>", "<button type='button' data-player='rewind'>",
"<svg><use xlink:href='#icon-rewind'></use></svg>", "<svg><use xlink:href='#icon-rewind'></use></svg>",
"<span class='sr-only'>Rewind {seektime} seconds</span>", "<span class='sr-only'>Rewind {seektime} secs</span>",
"</button>", "</button>",
"<button type='button' data-player='play'>", "<button type='button' data-player='play'>",
"<svg><use xlink:href='#icon-play'></use></svg>", "<svg><use xlink:href='#icon-play'></use></svg>",
@@ -102,14 +107,14 @@
"</button>", "</button>",
"<button type='button' data-player='fast-forward'>", "<button type='button' data-player='fast-forward'>",
"<svg><use xlink:href='#icon-fast-forward'></use></svg>", "<svg><use xlink:href='#icon-fast-forward'></use></svg>",
"<span class='sr-only'>Fast forward {seektime} seconds</span>", "<span class='sr-only'>Forward {seektime} secs</span>",
"</button>", "</button>",
"<span class='player-time'>", "<span class='player-time'>",
"<span class='sr-only'>Time</span>", "<span class='sr-only'>Time</span>",
"<span class='player-duration'>00:00</span>", "<span class='player-duration'>00:00</span>",
"</span>", "</span>",
"</span>", "</span>",
"<span class='player-controls-sound'>", "<span class='player-controls-right'>",
"<input class='inverted sr-only' id='mute{id}' type='checkbox' data-player='mute'>", "<input class='inverted sr-only' id='mute{id}' type='checkbox' data-player='mute'>",
"<label id='mute{id}' for='mute{id}'>", "<label id='mute{id}' for='mute{id}'>",
"<svg class='icon-muted'><use xlink:href='#icon-muted'></use></svg>", "<svg class='icon-muted'><use xlink:href='#icon-muted'></use></svg>",
@@ -127,12 +132,12 @@
"<button type='button' data-player='fullscreen'>", "<button type='button' data-player='fullscreen'>",
"<svg class='icon-exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>", "<svg class='icon-exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>",
"<svg><use xlink:href='#icon-enter-fullscreen'></use></svg>", "<svg><use xlink:href='#icon-enter-fullscreen'></use></svg>",
"<span class='sr-only'>Toggle fullscreen</span>", "<span class='sr-only'>Toggle Fullscreen</span>",
"</button>", "</button>",
"</span>", "</span>",
"</div>" "</div>"
].join("\n"); ].join("\n");
})() })()
}; };
// Debugging // Debugging
@@ -146,7 +151,7 @@
// Unfortunately, due to mixed support, UA sniffing is required // Unfortunately, due to mixed support, UA sniffing is required
function _browserSniff() { function _browserSniff() {
var nAgt = navigator.userAgent, var nAgt = navigator.userAgent,
browserName = navigator.appName, name = navigator.appName,
fullVersion = ""+parseFloat(navigator.appVersion), fullVersion = ""+parseFloat(navigator.appVersion),
majorVersion = parseInt(navigator.appVersion,10), majorVersion = parseInt(navigator.appVersion,10),
nameOffset, nameOffset,
@@ -155,22 +160,22 @@
// MSIE 11 // MSIE 11
if ((navigator.appVersion.indexOf("Windows NT") !== -1) && (navigator.appVersion.indexOf("rv:11") !== -1)) { if ((navigator.appVersion.indexOf("Windows NT") !== -1) && (navigator.appVersion.indexOf("rv:11") !== -1)) {
browserName = "IE"; name = "IE";
fullVersion = "11;"; fullVersion = "11;";
} }
// MSIE // MSIE
else if ((verOffset=nAgt.indexOf("MSIE")) !== -1) { else if ((verOffset=nAgt.indexOf("MSIE")) !== -1) {
browserName = "IE"; name = "IE";
fullVersion = nAgt.substring(verOffset+5); fullVersion = nAgt.substring(verOffset+5);
} }
// Chrome // Chrome
else if ((verOffset=nAgt.indexOf("Chrome")) !== -1) { else if ((verOffset=nAgt.indexOf("Chrome")) !== -1) {
browserName = "Chrome"; name = "Chrome";
fullVersion = nAgt.substring(verOffset+7); fullVersion = nAgt.substring(verOffset+7);
} }
// Safari // Safari
else if ((verOffset=nAgt.indexOf("Safari")) !== -1) { else if ((verOffset=nAgt.indexOf("Safari")) !== -1) {
browserName = "Safari"; name = "Safari";
fullVersion = nAgt.substring(verOffset+7); fullVersion = nAgt.substring(verOffset+7);
if ((verOffset=nAgt.indexOf("Version")) !== -1) { if ((verOffset=nAgt.indexOf("Version")) !== -1) {
fullVersion = nAgt.substring(verOffset+8); fullVersion = nAgt.substring(verOffset+8);
@@ -178,15 +183,15 @@
} }
// Firefox // Firefox
else if ((verOffset=nAgt.indexOf("Firefox")) !== -1) { else if ((verOffset=nAgt.indexOf("Firefox")) !== -1) {
browserName = "Firefox"; name = "Firefox";
fullVersion = nAgt.substring(verOffset+8); fullVersion = nAgt.substring(verOffset+8);
} }
// In most other browsers, "name/version" is at the end of userAgent // 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("/")) ) {
browserName = nAgt.substring(nameOffset,verOffset); name = nAgt.substring(nameOffset,verOffset);
fullVersion = nAgt.substring(verOffset+1); fullVersion = nAgt.substring(verOffset+1);
if (browserName.toLowerCase()==browserName.toUpperCase()) { if (name.toLowerCase()==name.toUpperCase()) {
browserName = navigator.appName; name = navigator.appName;
} }
} }
// Trim the fullVersion string at semicolon/space if present // Trim the fullVersion string at semicolon/space if present
@@ -202,8 +207,13 @@
fullVersion = ""+parseFloat(navigator.appVersion); fullVersion = ""+parseFloat(navigator.appVersion);
majorVersion = parseInt(navigator.appVersion,10); majorVersion = parseInt(navigator.appVersion,10);
} }
// Return data // Return data
return [browserName, majorVersion]; return {
name: name,
version: majorVersion,
ios: /(iPad|iPhone|iPod)/g.test(navigator.platform)
};
} }
// Check for mime type support against a player instance // Check for mime type support against a player instance
@@ -553,6 +563,18 @@
// Inject into the container // Inject into the container
player.container.insertAdjacentHTML("beforeend", html); player.container.insertAdjacentHTML("beforeend", html);
// Setup tooltips
if(config.tooltips) {
var labels = _getElements(config.selectors.labels);
for (var i = labels.length - 1; i >= 0; i--) {
var label = labels[i];
_toggleClass(label, config.classes.hidden, false);
_toggleClass(label, config.classes.tooltip, true);
}
}
} }
// Find the UI controls and store references // Find the UI controls and store references
@@ -597,6 +619,7 @@
} }
catch(e) { catch(e) {
_log("It looks like there's a problem with your controls html. Bailing.", true); _log("It looks like there's a problem with your controls html. Bailing.", true);
return false; return false;
} }
} }
@@ -627,7 +650,7 @@
player.media.removeAttribute("controls"); player.media.removeAttribute("controls");
// Set media type // Set media type
player.type = (player.media.tagName == "VIDEO" ? "video" : "audio"); player.type = player.media.tagName.toLowerCase();
// Add type class // Add type class
_toggleClass(player.container, config.classes[player.type], true); _toggleClass(player.container, config.classes[player.type], true);
@@ -635,6 +658,11 @@
// If there's no autoplay attribute, assume the video is stopped and add state class // If there's no autoplay attribute, assume the video is stopped and add state class
_toggleClass(player.container, config.classes.stopped, (player.media.getAttribute("autoplay") === null)); _toggleClass(player.container, config.classes.stopped, (player.media.getAttribute("autoplay") === null));
// Add iOS class
if(player.browser.ios) {
_toggleClass(player.container, "ios", true);
}
// Inject the player wrapper // Inject the player wrapper
if(player.type === "video") { if(player.type === "video") {
// Create the wrapper div // Create the wrapper div
@@ -710,10 +738,10 @@
_showCaptions(player); _showCaptions(player);
// If IE 10/11 or Firefox 31+ or Safari 7+, don"t use native captioning (still doesn"t work although they claim it"s now supported) // If IE 10/11 or Firefox 31+ or Safari 7+, don"t use native captioning (still doesn"t work although they claim it"s now supported)
if ((player.browserName === "IE" && player.browserMajorVersion === 10) || if ((player.browser.name === "IE" && player.browser.version === 10) ||
(player.browserName === "IE" && player.browserMajorVersion === 11) || (player.browser.name === "IE" && player.browser.version === 11) ||
(player.browserName === "Firefox" && player.browserMajorVersion >= 31) || (player.browser.name === "Firefox" && player.browser.version >= 31) ||
(player.browserName === "Safari" && player.browserMajorVersion >= 7)) { (player.browser.name === "Safari" && player.browser.version >= 7)) {
// Debugging // Debugging
_log("Detected IE 10/11 or Firefox 31+ or Safari 7+."); _log("Detected IE 10/11 or Firefox 31+ or Safari 7+.");
@@ -785,7 +813,7 @@
} }
// If Safari 7+, removing track from DOM [see "turn off native caption rendering" above] // If Safari 7+, removing track from DOM [see "turn off native caption rendering" above]
if (player.browserName === "Safari" && player.browserMajorVersion >= 7) { if (player.browser.name === "Safari" && player.browser.version >= 7) {
_log("Safari 7+ detected; removing track from DOM."); _log("Safari 7+ detected; removing track from DOM.");
// Find all <track> elements // Find all <track> elements
@@ -941,7 +969,7 @@
// Use default if needed // Use default if needed
if(typeof volume === "undefined") { if(typeof volume === "undefined") {
if(config.storage.enabled && _storage().supported) { if(config.storage.enabled && _storage().supported) {
volume = window.localStorage.plyr_volume || config.volume; volume = window.localStorage[config.storage.key] || config.volume;
} }
else { else {
volume = config.volume; volume = config.volume;
@@ -1256,16 +1284,14 @@
fullscreen = _fullscreen(); fullscreen = _fullscreen();
// Sniff // Sniff
player.browserInfo = _browserSniff(); player.browser = _browserSniff();
player.browserName = player.browserInfo[0];
player.browserMajorVersion = player.browserInfo[1];
// Debug info // Debug info
_log(player.browserName + " " + player.browserMajorVersion); _log(player.browser.name + " " + player.browser.version);
// If IE8, stop customization (use fallback) // If IE8, stop customization (use fallback)
// If IE9, stop customization (use native controls) // If IE9, stop customization (use native controls)
if (player.browserName === "IE" && (player.browserMajorVersion === 8 || player.browserMajorVersion === 9) ) { if (player.browser.name === "IE" && (player.browser.version === 8 || player.browser.version === 9) ) {
_log("Browser not suppported.", true); _log("Browser not suppported.", true);
return false; return false;
} }
@@ -1340,7 +1366,7 @@
// Disabled for <video> for iPhone // Disabled for <video> for iPhone
// Since it doesn't allow customisation // Since it doesn't allow customisation
if (element.querySelectorAll("audio, video")[0].tagName === "VIDEO" if (element.querySelectorAll("audio, video")[0].tagName.toLowerCase() === "video"
&& /iPhone/i.test(navigator.userAgent)) { && /iPhone/i.test(navigator.userAgent)) {
continue; continue;
} }
@@ -1356,4 +1382,4 @@
return players; return players;
} }
}(this.plyr = this.plyr || {})); }(this.plyr = this.plyr || {}));
+76 -7
View File
@@ -23,6 +23,13 @@
@control-color-inactive: @gray; @control-color-inactive: @gray;
@control-color-hover: #fff; @control-color-hover: #fff;
// Tooltips
@tooltip-bg: @controls-bg;
@tooltip-color: #fff;
@tooltip-padding: @control-spacing;
@tooltip-arrow-size: 5px;
@tooltip-radius: 3px;
// Progress // Progress
@progress-bg: lighten(@gray, 10%); @progress-bg: lighten(@gray, 10%);
@progress-playing-bg: @blue; @progress-playing-bg: @blue;
@@ -119,7 +126,6 @@
position: relative; position: relative;
max-width: 100%; max-width: 100%;
min-width: 290px; min-width: 290px;
overflow: hidden; // For the controls
// border-box everything // border-box everything
// http://paulirish.com/2012/box-sizing-border-box-ftw/ // http://paulirish.com/2012/box-sizing-border-box-ftw/
@@ -179,15 +185,15 @@
text-align: center; text-align: center;
// Layout // Layout
&-sound { &-right {
display: block; display: block;
margin: @control-spacing auto 0; margin: @control-spacing auto 0;
} }
@media (min-width: @bp-control-split) { @media (min-width: @bp-control-split) {
&-playback { &-left {
float: left; float: left;
} }
&-sound { &-right {
float: right; float: right;
margin-top: 0; margin-top: 0;
} }
@@ -227,10 +233,11 @@
overflow: hidden; overflow: hidden;
} }
// Specificity for overriding .inverted
button:focus, button:focus,
button:hover, button:hover,
input:focus + label, [type="checkbox"]:focus + label,
input + label:hover { [type="checkbox"] + label:hover {
background: @control-bg-hover; background: @control-bg-hover;
color: @control-color-hover; color: @control-color-hover;
} }
@@ -254,6 +261,54 @@
} }
} }
// Tooltips
&-tooltip {
visibility: hidden;
position: absolute;
z-index: 2;
bottom: 100%;
margin-bottom: @tooltip-padding;
padding: @tooltip-padding (@tooltip-padding * 1.5);
opacity: 0;
background: @tooltip-bg;
border-radius: @tooltip-radius;
color: @tooltip-color;
font-size: @font-size-small;
line-height: 1.5;
font-weight: 600;
transform: translate(-50%, (@tooltip-padding * 3));
transition: transform .2s .2s ease, opacity .2s .2s ease;
&::after {
content: "";
display: block;
position: absolute;
left: 50%;
bottom: -@tooltip-arrow-size;
margin-left: -@tooltip-arrow-size;
width: 0;
height: 0;
transition: inherit;
border-style: solid;
border-width: @tooltip-arrow-size @tooltip-arrow-size 0 @tooltip-arrow-size;
border-color: @controls-bg transparent transparent;
}
}
label:hover .player-tooltip,
input:focus + label .player-tooltip,
button:hover .player-tooltip,
button:focus .player-tooltip {
visibility: visible;
opacity: 1;
transform: translate(-50%, 0);
}
label:hover .player-tooltip,
button:hover .player-tooltip {
z-index: 3;
}
// Player progress // Player progress
// <progress> element // <progress> element
&-progress { &-progress {
@@ -308,7 +363,7 @@
// <input[type='range']> element // <input[type='range']> element
// Specificity is for bootstrap compatibility // Specificity is for bootstrap compatibility
&-seek[type=range] { &-seek[type=range] {
z-index: 3; z-index: 4;
cursor: pointer; cursor: pointer;
outline: 0; outline: 0;
@@ -442,6 +497,20 @@
} }
} }
// Hide sound controls on iOS
// It's not supported to change volume using JavaScript:
// https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
&.ios &-volume,
&.ios [data-player='mute'],
&.ios [data-player='mute'] + label,
&-audio.ios &-controls-right {
display: none;
}
// Center buttons so it looks less odd
&-audio.ios &-controls-left {
float: none;
}
// Full screen mode // Full screen mode
&-fullscreen, &-fullscreen,
&.fullscreen-active { &.fullscreen-active {
+71 -3
View File
@@ -23,6 +23,13 @@ $control-color: $gray-light;
$control-color-inactive: $gray; $control-color-inactive: $gray;
$control-color-hover: #fff; $control-color-hover: #fff;
// Tooltips
$tooltip-bg: $controls-bg;
$tooltip-color: #fff;
$tooltip-padding: $control-spacing;
$tooltip-arrow-size: 5px;
$tooltip-radius: 3px;
// Progress // Progress
$progress-bg: lighten($gray, 10%); $progress-bg: lighten($gray, 10%);
$progress-playing-bg: $blue; $progress-playing-bg: $blue;
@@ -125,7 +132,6 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
position: relative; position: relative;
max-width: 100%; max-width: 100%;
min-width: 290px; min-width: 290px;
overflow: hidden; // For the controls
// border-box everything // border-box everything
// http://paulirish.com/2012/box-sizing-border-box-ftw/ // http://paulirish.com/2012/box-sizing-border-box-ftw/
@@ -190,10 +196,10 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
margin: $control-spacing auto 0; margin: $control-spacing auto 0;
} }
@media (min-width: $bp-control-split) { @media (min-width: $bp-control-split) {
&-playback { &-left {
float: left; float: left;
} }
&-sound { &-right {
float: right; float: right;
margin-top: 0; margin-top: 0;
} }
@@ -258,6 +264,54 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
} }
} }
// Tooltips
&-tooltip {
visibility: hidden;
position: absolute;
z-index: 2;
bottom: 100%;
margin-bottom: $tooltip-padding;
padding: $tooltip-padding ($tooltip-padding * 1.5);
opacity: 0;
background: $tooltip-bg;
border-radius: $tooltip-radius;
color: $tooltip-color;
font-size: $font-size-small;
line-height: 1.5;
font-weight: 600;
transform: translate(-50%, ($tooltip-padding * 3));
transition: transform .2s .2s ease, opacity .2s .2s ease;
&::after {
content: "";
display: block;
position: absolute;
left: 50%;
bottom: -$tooltip-arrow-size;
margin-left: -$tooltip-arrow-size;
width: 0;
height: 0;
transition: inherit;
border-style: solid;
border-width: $tooltip-arrow-size $tooltip-arrow-size 0 $tooltip-arrow-size;
border-color: $controls-bg transparent transparent;
}
}
label:hover .player-tooltip,
input:focus + label .player-tooltip,
button:hover .player-tooltip,
button:focus .player-tooltip {
visibility: visible;
opacity: 1;
transform: translate(-50%, 0);
}
label:hover .player-tooltip,
button:hover .player-tooltip {
z-index: 3;
}
// Player progress // Player progress
// <progress> element // <progress> element
&-progress { &-progress {
@@ -445,6 +499,20 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
} }
} }
// Hide sound controls on iOS
// It's not supported to change volume using JavaScript:
// https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
&.ios &-volume,
&.ios [data-player='mute'],
&.ios [data-player='mute'] + label,
&-audio.ios &-controls-right {
display: none;
}
// Center buttons so it looks less odd
&-audio.ios &-controls-left {
float: none;
}
// Full screen mode // Full screen mode
&-fullscreen, &-fullscreen,
&.fullscreen-active { &.fullscreen-active {