Merge branch 'develop' of github.com:selz/plyr into develop
# Conflicts: # .gitignore
This commit is contained in:
commit
398815857f
45
changelog.md
45
changelog.md
@ -1,5 +1,50 @@
|
||||
# Changelog
|
||||
|
||||
## v1.1.5
|
||||
- Fix for incorrect `isFullscreen()` return value in Mozilla (Fixes #38)
|
||||
|
||||
## 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
|
||||
|
||||
## v1.0.31
|
||||
- Display duration on `metadataloaded`
|
||||
|
||||
## v1.0.30
|
||||
- Fixed bug with media longer than 60 minutes (Fixes #69)
|
||||
|
||||
## v1.0.29
|
||||
- Added option to hide controls on fullscreen (default `true`) while palying, after 1s. Pause, mouse hover on progress, or focus on a child control re-shows the controls. On touch a tap of the video (which plays/pauses the video by default) is required. (Fixes #47)
|
||||
- Fixed a bug with caption toggle in 1.0.28
|
||||
|
||||
## v1.0.28
|
||||
- Added API support for browsers that don't have full plyr support (pretty much <=IE9 and `<video>` on iPhone/iPod)
|
||||
|
||||
## v1.0.27
|
||||
- Keyboard accessibility improvements (Fixes #66)
|
||||
|
||||
## v1.0.26
|
||||
- Fixes for SASS (cheers @brunowego)
|
||||
- Indentation reset to 4 spaces
|
||||
|
||||
## 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)
|
||||
|
||||
|
18
controls.md
18
controls.md
@ -2,7 +2,7 @@
|
||||
|
||||
This is the markup that is rendered for the Plyr controls. You can use the default controls or provide a customized version of markup based on your needs.
|
||||
|
||||
The demo Plyr setup uses a Hogan template. This purely to allow for localization at a later date. Check out `controls.html` in `/src/templates` to get an idea of how the default html is structured. Alternatively check out the `plyr.js` source.
|
||||
The demo Plyr setup uses a Hogan template. This purely to allow for localization at a later date. Check out `controls.html` in `/src/templates` to get an idea of how the default html is structured.
|
||||
|
||||
## Requirements
|
||||
|
||||
@ -13,11 +13,11 @@ You need to add several placeholders to your html template that are replaced whe
|
||||
- `{id}` - the dynamically generated ID for the player (for form controls)
|
||||
- `{seektime}` - the seek time specified in options for fast forward and rewind
|
||||
|
||||
Currently all buttons and inputs need to be present for Plyr to work but later we'll make it more dynamic so if you omit a button or input, it'll still work.
|
||||
You can include only the controls you need when specifying custom html.
|
||||
|
||||
## Default
|
||||
## Example
|
||||
|
||||
This is the default `html` option from `plyr.js`.
|
||||
This is an example `html` option with all controls.
|
||||
|
||||
```javascript
|
||||
["<div class='player-controls'>",
|
||||
@ -31,7 +31,7 @@ This is the default `html` option from `plyr.js`.
|
||||
"<span>0</span>% buffered",
|
||||
"</progress>",
|
||||
"</div>",
|
||||
"<span class='player-controls-playback'>",
|
||||
"<span class='player-controls-left'>",
|
||||
"<button type='button' data-player='restart'>",
|
||||
"<svg><use xlink:href='#icon-restart'></use></svg>",
|
||||
"<span class='sr-only'>Restart</span>",
|
||||
@ -53,11 +53,15 @@ This is the default `html` option from `plyr.js`.
|
||||
"<span class='sr-only'>Forward {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<span class='player-time'>",
|
||||
"<span class='sr-only'>Time</span>",
|
||||
"<span class='sr-only'>Current time</span>",
|
||||
"<span class='player-current-time'>00:00</span>",
|
||||
"</span>",
|
||||
"<span class='player-time'>",
|
||||
"<span class='sr-only'>Duration</span>",
|
||||
"<span class='player-duration'>00:00</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'>",
|
||||
"<label id='mute{id}' for='mute{id}'>",
|
||||
"<svg class='icon-muted'><use xlink:href='#icon-muted'></use></svg>",
|
||||
|
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.css
vendored
2
docs/dist/docs.css
vendored
@ -1 +1 @@
|
||||
/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-medium.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-medium.woff) format("woff"),url(//cdn.plyr.io/fonts/avenir-medium.ttf) format("truetype");font-style:normal;font-weight:400}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-bold.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-bold.woff) format("woff"),url(//cdn.plyr.io/fonts/avenir-bold.ttf) format("truetype");font-style:normal;font-weight:600}*,::after,::before{box-sizing:border-box}body{font-family:Avenir,"Helvetica Neue",Helvetica,Arial,sans-serif;background:#fff;line-height:1.5;text-align:center;color:#6D797F}.error body,html.error{height:100%}.error body{width:100%;display:table;table-layout:fixed}.error main{display:table-cell;width:100%;vertical-align:middle}h1,h2{letter-spacing:-.025em;color:#2E3C44;margin:0 0 10px;line-height:1.2;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}h1{font-size:64px;font-size:4rem;color:#3498DB}p,small{margin:0 0 20px}small{display:block;padding:0 10px;font-size:14px;font-size:.9rem}header{padding:20px;margin-bottom:20px}header p{font-size:18px;font-size:1.1rem}@media (min-width:560px){header{padding-top:60px;padding-bottom:60px}}section{padding-bottom:20px}@media (min-width:560px){section{padding-bottom:40px}}a{text-decoration:none;color:#3498db;border-bottom:1px solid currentColor;transition:all .3s ease}a:focus,a:hover{color:#000}a:focus{outline:#343f4a dotted thin;outline-offset:1px}a.logo{border:0}.btn{display:inline-block;padding:10px 30px;background:#3498db;border:0;color:#fff;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-weight:600;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:hover{color:#fff;background:#258cd1}.example-audio .player{max-width:480px}.example-video .player{max-width:1200px}.example-audio .player,.example-video .player{margin:0 auto 20px}.example-audio .player-fullscreen,.example-audio .player.fullscreen-active,.example-video .player-fullscreen,.example-video .player.fullscreen-active{max-width:none}footer{margin-bottom:20px}footer p{margin-bottom:10px}
|
||||
/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-medium.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-medium.woff) format("woff"),url(//cdn.plyr.io/fonts/avenir-medium.ttf) format("truetype");font-style:normal;font-weight:400}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-bold.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-bold.woff) format("woff"),url(//cdn.plyr.io/fonts/avenir-bold.ttf) format("truetype");font-style:normal;font-weight:600}*,::after,::before{box-sizing:border-box}body{font-family:Avenir,"Helvetica Neue",Helvetica,Arial,sans-serif;background:#fff;line-height:1.5;text-align:center;color:#6D797F}.error body,html.error{height:100%}.error body{width:100%;display:table;table-layout:fixed}.error main{display:table-cell;width:100%;vertical-align:middle}h1,h2{letter-spacing:-.025em;color:#2E3C44;margin:0 0 10px;line-height:1.2;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}h1{font-size:64px;font-size:4rem;color:#3498DB}p,small{margin:0 0 20px}small{display:block;padding:0 10px;font-size:14px;font-size:.9rem}header{padding:20px;margin-bottom:20px}header p{font-size:18px;font-size:1.1rem}@media (min-width:560px){header{padding-top:60px;padding-bottom:60px}}section{padding-bottom:20px}@media (min-width:560px){section{padding-bottom:40px}}a{text-decoration:none;color:#3498db;border-bottom:1px solid currentColor;transition:all .3s ease}a:focus,a:hover{color:#000}a:focus{outline:#343f4a dotted thin;outline-offset:1px}a.logo{border:0}.btn{display:inline-block;padding:10px 30px;background:#3498db;border:0;color:#fff;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-weight:600;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:hover{color:#fff;background:#258cd1}.example-audio .player{max-width:520px}.example-video .player{max-width:1200px}.example-audio .player,.example-video .player{margin:0 auto 20px}.example-audio .player-fullscreen,.example-audio .player.fullscreen-active,.example-video .player-fullscreen,.example-video .player.fullscreen-active{max-width:none}footer{margin-bottom:20px}footer p{margin-bottom:10px}
|
2
docs/dist/docs.js
vendored
2
docs/dist/docs.js
vendored
File diff suppressed because one or more lines are too long
2
docs/dist/templates.js
vendored
2
docs/dist/templates.js
vendored
@ -1,2 +1,2 @@
|
||||
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} 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-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\">Current time</span>");t.b("\n" + i);t.b(" <span class=\"player-current-time\">00:00</span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" <span class=\"player-time\">");t.b("\n" + i);t.b(" <span class=\"sr-only\">Duration</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: { }});
|
@ -6,7 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Docs styles -->
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.0.24/docs.css">
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.5/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.0.24/plyr.css">
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.5/plyr.css">
|
||||
|
||||
<!-- Docs styles -->
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.0.24/docs.css">
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.5/docs.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
@ -67,13 +67,29 @@
|
||||
<!-- Load SVG defs -->
|
||||
<!-- You should bundle all SVG/Icons into one file using a build tool such as gulp and svg store -->
|
||||
<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.24/sprite.svg");
|
||||
(function(d, u){
|
||||
var a = new XMLHttpRequest(),
|
||||
b = d.body;
|
||||
|
||||
// Check for CORS support
|
||||
// If you're loading from same domain, you can remove the if statement
|
||||
if("withCredentials" in a) {
|
||||
a.open("GET", u, true);
|
||||
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, "https://cdn.plyr.io/1.1.5/sprite.svg");
|
||||
</script>
|
||||
|
||||
<!-- Plyr core script -->
|
||||
<script src="//cdn.plyr.io/1.0.24/plyr.js"></script>
|
||||
<script src="//cdn.plyr.io/1.1.5/plyr.js"></script>
|
||||
|
||||
<!-- Docs script -->
|
||||
<script src="//cdn.plyr.io/1.0.24/docs.js"></script>
|
||||
<script src="//cdn.plyr.io/1.1.5/docs.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -12,9 +12,20 @@ plyr.setup({
|
||||
captions: {
|
||||
defaultActive: true
|
||||
},
|
||||
tooltips: 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) {
|
||||
|
@ -139,7 +139,7 @@ a {
|
||||
|
||||
// Players
|
||||
.example-audio .player {
|
||||
max-width: 480px;
|
||||
max-width: 520px;
|
||||
}
|
||||
.example-video .player {
|
||||
max-width: 1200px;
|
||||
|
@ -9,7 +9,7 @@
|
||||
<span>0</span>% buffered
|
||||
</progress>
|
||||
</div>
|
||||
<span class="player-controls-playback">
|
||||
<span class="player-controls-left">
|
||||
<button type="button" data-player="restart">
|
||||
<svg><use xlink:href="#icon-restart"></use></svg>
|
||||
<span class="sr-only">Restart</span>
|
||||
@ -31,11 +31,15 @@
|
||||
<span class="sr-only">Forward {seektime} secs</span>
|
||||
</button>
|
||||
<span class="player-time">
|
||||
<span class="sr-only">Time</span>
|
||||
<span class="sr-only">Current time</span>
|
||||
<span class="player-current-time">00:00</span>
|
||||
</span>
|
||||
<span class="player-time">
|
||||
<span class="sr-only">Duration</span>
|
||||
<span class="player-duration">00:00</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">
|
||||
<label id="mute{id}" for="mute{id}">
|
||||
<svg class="icon-muted"><use xlink:href="#icon-muted"></use></svg>
|
||||
|
12
gulpfile.js
12
gulpfile.js
@ -22,7 +22,8 @@ var fs = require("fs"),
|
||||
s3 = require("gulp-s3"),
|
||||
gzip = require("gulp-gzip"),
|
||||
replace = require("gulp-replace"),
|
||||
open = require("gulp-open");
|
||||
open = require("gulp-open"),
|
||||
size = require("gulp-size");
|
||||
|
||||
var root = __dirname,
|
||||
paths = {
|
||||
@ -223,6 +224,10 @@ gulp.task("cdn", function () {
|
||||
|
||||
// Upload to CDN
|
||||
gulp.src(paths.upload)
|
||||
.pipe(size({
|
||||
showFiles: true,
|
||||
gzip: true
|
||||
}))
|
||||
.pipe(rename(function (path) {
|
||||
path.dirname = path.dirname.replace(".", version);
|
||||
}))
|
||||
@ -234,6 +239,11 @@ gulp.task("cdn", function () {
|
||||
gulp.task("docs", function () {
|
||||
console.log("Uploading " + version + " docs to " + aws.docs.bucket);
|
||||
|
||||
// Replace versioned files in readme.md
|
||||
gulp.src([root + "/readme.md"])
|
||||
.pipe(replace(cdnpath, aws.cdn.bucket + "/" + version))
|
||||
.pipe(gulp.dest(root));
|
||||
|
||||
// Replace versioned files in *.html
|
||||
gulp.src([paths.docs.root + "*.html"])
|
||||
.pipe(replace(cdnpath, aws.cdn.bucket + "/" + version))
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "1.0.24",
|
||||
"version": "1.1.5",
|
||||
"description": "A simple HTML5 media player using custom controls",
|
||||
"homepage": "http://plyr.io",
|
||||
"main": "gulpfile.js",
|
||||
@ -18,6 +18,7 @@
|
||||
"gulp-replace": "^0.5.3",
|
||||
"gulp-s3": "^0.3.0",
|
||||
"gulp-sass": "^1.3.3",
|
||||
"gulp-size": "^1.2.1",
|
||||
"gulp-svgmin": "^1.0.0",
|
||||
"gulp-svgstore": "^5.0.0",
|
||||
"gulp-uglify": "~0.3.1",
|
||||
|
82
readme.md
82
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 5.7KB 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.
|
||||
@ -25,11 +25,10 @@ Oh and yes, it works with Bootstrap.
|
||||
Check out [the changelog](changelog.md)
|
||||
|
||||
## Planned development
|
||||
- Accept a string selector, a node, or a nodelist for the `container` property of `selectors`.
|
||||
- Multiple language captions (with selection)
|
||||
- Playlists (audio and video)
|
||||
- Set source by API
|
||||
- Tooltip option (for seeking and controls)
|
||||
- YouTube and Vimeo support
|
||||
- Playback speed
|
||||
- Multiple language captions (with selection)
|
||||
... and whatever else has been raised in [issues](https://github.com/Selz/plyr/issues)
|
||||
|
||||
If you have any cool ideas or features, please let me know by [creating an issue](https://github.com/Selz/plyr/issues/new) or of course, forking and sending a pull request.
|
||||
@ -38,7 +37,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.0.24/plyr.js` to `https://cdn.plyr.io/1.0.24/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.5/plyr.js` to `https://cdn.plyr.io/1.1.5/plyr.js`
|
||||
|
||||
### Bower
|
||||
If bower is your thang, you can grab Plyr using:
|
||||
@ -47,15 +46,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.0.24/plyr.css">
|
||||
<script src="//cdn.plyr.io/1.0.24/plyr.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.plyr.io/1.1.5/plyr.css">
|
||||
<script src="//cdn.plyr.io/1.1.5/plyr.js"></script>
|
||||
```
|
||||
|
||||
You can also access the `sprite.svg` file at `//cdn.plyr.io/1.0.24/sprite.svg`.
|
||||
You can also access the `sprite.svg` file at `//cdn.plyr.io/1.1.5/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.
|
||||
@ -131,20 +137,16 @@ 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
|
||||
Much of the behaviour of the player is configurable when initialising the library. Below is an example of a default instance.
|
||||
Much of the behaviour of the player is configurable when initialising the library. Here's an example of a default setup:
|
||||
|
||||
```html
|
||||
<script src="dist/plyr.js"></script>
|
||||
<script>
|
||||
plyr.setup({
|
||||
*options*
|
||||
});
|
||||
</script>
|
||||
<script>plyr.setup();</script>
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
You can pass the following options to the setup method.
|
||||
You can pass the following options to the setup method using `plyr.setup({...})`.
|
||||
|
||||
<table class="table" width="100%">
|
||||
<thead>
|
||||
@ -168,6 +170,12 @@ You can pass the following options to the setup method.
|
||||
<td><code><a href="controls.md">See controls.md</a></code></td>
|
||||
<td>See <a href="controls.md">controls.md</a> for more info on how the html needs to be structured.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>controls</code></td>
|
||||
<td>Array</td>
|
||||
<td><code>["restart", "rewind", "play", "fast-forward", "current-time", "duration", "mute", "volume", "captions", "fullscreen"]</code></td>
|
||||
<td>Toggle which control elements you would like to display when using the default controls html. If you specify a <code>html</code> option, this is redundant. The default value is to display everything.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>debug</code></td>
|
||||
<td>Boolean</td>
|
||||
@ -197,6 +205,12 @@ You can pass the following options to the setup method.
|
||||
<td>Boolean</td>
|
||||
<td><code>false</code></td>
|
||||
<td>Display control labels as tooltips on :hover & :focus (by default, the labels are screen reader only).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>displayDuration</code></td>
|
||||
<td>Boolean</td>
|
||||
<td><code>true</code></td>
|
||||
<td>Displays the duration of the media on the "metadataloaded" event (on startup) in the current time display. This will only work if the `preload` attribute is not set to `none` (or is not set at all) and you choose not to display the duration (see <code>controls</code> option).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>selectors</code></td>
|
||||
@ -220,7 +234,7 @@ You can pass the following options to the setup method.
|
||||
<td><code>fullscreen</code></td>
|
||||
<td>Object</td>
|
||||
<td>—</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>
|
||||
<td>Three properties; <code>enabled</code> which toggles if fullscreen should be enabled (if the browser supports it). The default value is <code>true</code>. A <code>fallback</code> property which will enable a full window view for older browsers. The default value is <code>true</code>. A <code>hideControls</code> property which will hide the controls when fullscreen is active and the video is playing, after 1s. The controls reappear on hover of the progress bar (mouse), focusing a child control or pausing the video (by tap/click of video if `click` is `true`). The default value is <code>true</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>storage</code></td>
|
||||
@ -228,6 +242,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>
|
||||
|
||||
@ -295,6 +315,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>
|
||||
@ -338,11 +368,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>
|
||||
@ -359,15 +390,15 @@ Fullscreen in Plyr is supported for all browsers that [currently support it](htt
|
||||
<td>✔</td>
|
||||
<td>✔</td>
|
||||
<td>✔</td>
|
||||
<td>✖²</td>
|
||||
<td>API²</td>
|
||||
<td>✔³</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
¹ iPhone forces the native player for `<video>` so no customisation possible
|
||||
¹ Mobile Safari on the iPhone forces the native player for `<video>` so no useful customisation is possible. `<audio>` elements have volume controls disabled.
|
||||
|
||||
² Native player used (no support for `<progress>` or `<input type="range">`)
|
||||
² Native player used (no support for `<progress>` or `<input type="range">`) but the API is supported (v1.0.28+)
|
||||
|
||||
³ IE10 has no native fullscreen support, fallback can be used (see options)
|
||||
|
||||
@ -380,19 +411,24 @@ 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) with help from the awesome [contributors](https://github.com/Selz/plyr/graphs/contributors)
|
||||
|
||||
## Mentions
|
||||
- [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/)
|
||||
- [HTML5 Weekly #177](http://html5weekly.com/issues/177)
|
||||
- [Responsive Design #149](http://us4.campaign-archive2.com/?u=559bc631fe5294fc66f5f7f89&id=451a61490f)
|
||||
- [Web Design Weekly #174](https://web-design-weekly.com/2015/02/24/web-design-weekly-174/)
|
||||
- [Hacker News](https://news.ycombinator.com/item?id=9136774)
|
||||
- [Web Platform Daily](http://webplatformdaily.org/releases/2015-03-04)
|
||||
- [LayerVault Designer News](https://news.layervault.com/stories/45394-plyr--a-simple-html5-media-player)
|
||||
- [The Treehouse Show #131](https://teamtreehouse.com/library/episode-131-origami-react-responsive-hero-images)
|
||||
|
||||
## Used by
|
||||
- [Selz.com](https://selz.com)
|
||||
|
670
src/js/plyr.js
670
src/js/plyr.js
File diff suppressed because it is too large
Load Diff
32
src/js/plyr.youtube.js
Normal file
32
src/js/plyr.youtube.js
Normal file
@ -0,0 +1,32 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.youtube.js v1.1.4
|
||||
// https://github.com/selz/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
||||
(function (api) {
|
||||
"use strict";
|
||||
|
||||
api.youtube = {
|
||||
setup: function() {
|
||||
console.log("Setup youtube");
|
||||
console.log(this);
|
||||
|
||||
var player = this;
|
||||
|
||||
// Find child <source> elements
|
||||
var sources = player.media.querySelectorAll("source");
|
||||
|
||||
// Remove each
|
||||
for (var i = sources.length - 1; i >= 0; i--) {
|
||||
var source = sources[i];
|
||||
|
||||
if(source.type == "video/youtube") {
|
||||
console.log(source.src);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}(this.plyr.plugins = this.plyr.plugins || {}));
|
@ -9,6 +9,7 @@
|
||||
@gray-dark: #343f4a;
|
||||
@gray: #565d64;
|
||||
@gray-light: #cbd0d3;
|
||||
@off-white: #d6dadd;
|
||||
|
||||
// Font sizes
|
||||
@font-size-small: 14px;
|
||||
@ -31,9 +32,9 @@
|
||||
@tooltip-radius: 3px;
|
||||
|
||||
// Progress
|
||||
@progress-bg: lighten(@gray, 10%);
|
||||
@progress-bg: rgba(red(@gray), green(@gray), blue(@gray), .2);
|
||||
@progress-playing-bg: @blue;
|
||||
@progress-buffered-bg: @gray;
|
||||
@progress-buffered-bg: rgba(red(@gray), green(@gray), blue(@gray), .25);
|
||||
@progress-loading-size: 40px;
|
||||
@progress-loading-bg: rgba(0,0,0, .15);
|
||||
|
||||
@ -146,6 +147,21 @@
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// For embeds
|
||||
&-video-embed {
|
||||
padding-bottom: 56.25%; /* 16:9 */
|
||||
height: 0;
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Captions
|
||||
&-captions {
|
||||
display: none;
|
||||
@ -179,21 +195,21 @@
|
||||
.clearfix();
|
||||
.font-smoothing();
|
||||
position: relative;
|
||||
padding: (@control-spacing * 2) @control-spacing @control-spacing;
|
||||
padding: @control-spacing;
|
||||
background: @controls-bg;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
|
||||
// Layout
|
||||
&-sound {
|
||||
&-right {
|
||||
display: block;
|
||||
margin: @control-spacing auto 0;
|
||||
}
|
||||
@media (min-width: @bp-control-split) {
|
||||
&-playback {
|
||||
&-left {
|
||||
float: left;
|
||||
}
|
||||
&-sound {
|
||||
&-right {
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
}
|
||||
@ -259,6 +275,22 @@
|
||||
font-size: @font-size-small;
|
||||
.font-smoothing();
|
||||
}
|
||||
|
||||
// Media duration hidden on small screens
|
||||
.player-time + .player-time {
|
||||
display: none;
|
||||
|
||||
@media (min-width: @bp-control-split) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Add a slash in before
|
||||
&::before {
|
||||
content: "\2044";
|
||||
margin-right: @control-spacing;
|
||||
color: darken(@control-color, 30%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltips
|
||||
@ -313,7 +345,7 @@
|
||||
// <progress> element
|
||||
&-progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
@ -497,6 +529,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@ -510,13 +567,13 @@
|
||||
z-index: 10000000;
|
||||
background: #000;
|
||||
|
||||
video {
|
||||
height: 100%;
|
||||
}
|
||||
.player-video-wrapper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
video {
|
||||
height: 100%;
|
||||
}
|
||||
.player-captions {
|
||||
top: auto;
|
||||
bottom: 90px;
|
||||
@ -535,6 +592,17 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
// Hide controls when playing in full screen
|
||||
&.fullscreen-hide-controls.playing .player-controls {
|
||||
transform: translateY(100%) translateY(@control-spacing / 2);
|
||||
transition: transform .3s 1s ease;
|
||||
|
||||
&.hover {
|
||||
transform: translateY(0);
|
||||
transition-delay: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change icons on state change
|
||||
@ -561,10 +629,4 @@
|
||||
&.fullscreen-enabled [data-player='fullscreen'] + label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Full browser view hides toggle
|
||||
&-fullscreen [data-player='fullscreen'],
|
||||
&-fullscreen [data-player='fullscreen'] + label {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
@ -5,49 +5,50 @@
|
||||
// Variables
|
||||
// -------------------------------
|
||||
// Colors
|
||||
$blue: #3498DB;
|
||||
$gray-dark: #343f4a;
|
||||
$gray: #565d64;
|
||||
$gray-light: #cbd0d3;
|
||||
$blue: #3498DB !default;
|
||||
$gray-dark: #343f4a !default;
|
||||
$gray: #565d64 !default;
|
||||
$gray-light: #cbd0d3 !default;
|
||||
$off-white: #d6dadd !default;
|
||||
|
||||
// Font sizes
|
||||
$font-size-small: 14px;
|
||||
$font-size-base: 16px;
|
||||
$font-size-large: ceil(($font-size-base * 1.5));
|
||||
$font-size-small: 14px !default;
|
||||
$font-size-base: 16px !default;
|
||||
$font-size-large: ceil(($font-size-base * 1.5)) !default;
|
||||
|
||||
// Controls
|
||||
$control-spacing: 10px;
|
||||
$controls-bg: $gray-dark;
|
||||
$control-bg-hover: $blue;
|
||||
$control-color: $gray-light;
|
||||
$control-color-inactive: $gray;
|
||||
$control-color-hover: #fff;
|
||||
$control-spacing: 10px !default;
|
||||
$controls-bg: $gray-dark !default;
|
||||
$control-bg-hover: $blue !default;
|
||||
$control-color: $gray-light !default;
|
||||
$control-color-inactive: $gray !default;
|
||||
$control-color-hover: #fff !default;
|
||||
|
||||
// Tooltips
|
||||
$tooltip-bg: $controls-bg;
|
||||
$tooltip-color: #fff;
|
||||
$tooltip-padding: $control-spacing;
|
||||
$tooltip-arrow-size: 5px;
|
||||
$tooltip-radius: 3px;
|
||||
$tooltip-bg: $controls-bg !default;
|
||||
$tooltip-color: #fff !default;
|
||||
$tooltip-padding: $control-spacing !default;
|
||||
$tooltip-arrow-size: 5px !default;
|
||||
$tooltip-radius: 3px !default;
|
||||
|
||||
// Progress
|
||||
$progress-bg: lighten($gray, 10%);
|
||||
$progress-playing-bg: $blue;
|
||||
$progress-buffered-bg: $gray;
|
||||
$progress-loading-size: 40px;
|
||||
$progress-loading-bg: rgba(0,0,0, .15);
|
||||
$progress-bg: rgba(red($gray), green($gray), blue($gray), .2) !default;
|
||||
$progress-playing-bg: $blue !default;
|
||||
$progress-buffered-bg: rgba(red($gray), green($gray), blue($gray), .25) !default;
|
||||
$progress-loading-size: 40px !default;
|
||||
$progress-loading-bg: rgba(0,0,0, .15) !default;
|
||||
|
||||
// Range
|
||||
$volume-track-height: 6px;
|
||||
$volume-track-bg: $gray;
|
||||
$volume-thumb-height: ($volume-track-height * 2);
|
||||
$volume-thumb-width: ($volume-track-height * 2);
|
||||
$volume-thumb-bg: $control-color;
|
||||
$volume-thumb-bg-focus: $control-bg-hover;
|
||||
// Volume
|
||||
$volume-track-height: 6px !default;
|
||||
$volume-track-bg: $gray !default;
|
||||
$volume-thumb-height: ($volume-track-height * 2) !default;
|
||||
$volume-thumb-width: ($volume-track-height * 2) !default;
|
||||
$volume-thumb-bg: $control-color !default;
|
||||
$volume-thumb-bg-focus: $control-bg-hover !default;
|
||||
|
||||
// Breakpoints
|
||||
$bp-control-split: 560px; // When controls split into left/right
|
||||
$bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
$bp-control-split: 560px !default; // When controls split into left/right
|
||||
$bp-captions-large: 768px !default; // When captions jump to the larger font size
|
||||
|
||||
// Utility classes & mixins
|
||||
// -------------------------------
|
||||
@ -79,7 +80,7 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
// Animation
|
||||
// ---------------------------------------
|
||||
@keyframes progress {
|
||||
to { background-position: @progress-loading-size 0; }
|
||||
to { background-position: $progress-loading-size 0; }
|
||||
}
|
||||
|
||||
// <input type="range"> styling
|
||||
@ -101,29 +102,31 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
border: 0;
|
||||
border-radius: ($volume-track-height / 2);
|
||||
}
|
||||
@mixin seek-thumb() {
|
||||
@mixin seek-thumb()
|
||||
{
|
||||
background: transparent;
|
||||
border: 0;
|
||||
width: ($control-spacing * 2);
|
||||
height: $control-spacing;
|
||||
}
|
||||
@mixin seek-track() {
|
||||
@mixin seek-track()
|
||||
{
|
||||
background: none;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Font smoothing
|
||||
// ---------------------------------------
|
||||
@mixin font-smoothing($mode: on) when ($mode = on)
|
||||
@mixin font-smoothing($mode: on)
|
||||
{
|
||||
@if $mode == 'on' {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@mixin font-smoothing($mode: on) when ($mode = off)
|
||||
{
|
||||
} @else if $mode == 'off' {
|
||||
-moz-osx-font-smoothing: auto;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
}
|
||||
}
|
||||
|
||||
// Styles
|
||||
// -------------------------------
|
||||
@ -185,21 +188,21 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
@include clearfix();
|
||||
@include font-smoothing();
|
||||
position: relative;
|
||||
padding: ($control-spacing * 2) $control-spacing $control-spacing;
|
||||
padding: $control-spacing;
|
||||
background: $controls-bg;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
|
||||
// Layout
|
||||
&-sound {
|
||||
&-right {
|
||||
display: block;
|
||||
margin: $control-spacing auto 0;
|
||||
}
|
||||
@media (min-width: $bp-control-split) {
|
||||
&-playback {
|
||||
&-left {
|
||||
float: left;
|
||||
}
|
||||
&-sound {
|
||||
&-right {
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
}
|
||||
@ -238,16 +241,19 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
background: transparent;
|
||||
overflow: hidden;
|
||||
}
|
||||
input:focus + label,
|
||||
button:focus {
|
||||
@include tab-focus();
|
||||
color: $control-color-focus;
|
||||
}
|
||||
|
||||
// Specificity for overriding .inverted
|
||||
button:focus,
|
||||
button:hover,
|
||||
input + label:hover {
|
||||
[type="checkbox"]:focus + label,
|
||||
[type="checkbox"] + label:hover {
|
||||
background: $control-bg-hover;
|
||||
color: $control-color-hover;
|
||||
}
|
||||
button:focus,
|
||||
input:focus + label {
|
||||
outline: 0;
|
||||
}
|
||||
.icon-exit-fullscreen,
|
||||
.icon-muted,
|
||||
.icon-captions-on {
|
||||
@ -262,6 +268,22 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
font-size: $font-size-small;
|
||||
@include font-smoothing();
|
||||
}
|
||||
|
||||
// Media duration hidden on small screens
|
||||
.player-time + .player-time {
|
||||
display: none;
|
||||
|
||||
@media (min-width: $bp-control-split) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Add a slash in before
|
||||
&::before {
|
||||
content: "\2044";
|
||||
margin-right: $control-spacing;
|
||||
color: darken($control-color, 30%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltips
|
||||
@ -316,7 +338,7 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
// <progress> element
|
||||
&-progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
@ -330,8 +352,9 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: $control-spacing;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
|
||||
-webkit-appearance: none;
|
||||
@ -339,7 +362,6 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&-buffer[value],
|
||||
&-played[value] {
|
||||
&::-webkit-progress-bar {
|
||||
@ -366,7 +388,7 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
// <input[type='range']> element
|
||||
// Specificity is for bootstrap compatibility
|
||||
&-seek[type=range] {
|
||||
z-index: 3;
|
||||
z-index: 4;
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
|
||||
@ -441,6 +463,7 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
// <input[type='range']> element
|
||||
// Specificity is for bootstrap compatibility
|
||||
&-volume[type=range] {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
@ -452,20 +475,20 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
|
||||
// Webkit
|
||||
&::-webkit-slider-runnable-track {
|
||||
@include range-track();
|
||||
@include volume-track();
|
||||
}
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
margin-top: -(($volume-thumb-height - $volume-track-height) / 2);
|
||||
@include range-thumb();
|
||||
@include volume-thumb();
|
||||
}
|
||||
|
||||
// Mozilla
|
||||
&::-moz-range-track {
|
||||
@include range-track();
|
||||
@include volume-track();
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
@include range-thumb();
|
||||
@include volume-thumb();
|
||||
}
|
||||
|
||||
// Microsoft
|
||||
@ -478,10 +501,10 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
}
|
||||
&::-ms-fill-lower,
|
||||
&::-ms-fill-upper {
|
||||
@include range-track();
|
||||
@include volume-track();
|
||||
}
|
||||
&::-ms-thumb {
|
||||
@include range-thumb();
|
||||
@include volume-thumb();
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@ -499,6 +522,31 @@ $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;
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@ -512,13 +560,13 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
z-index: 10000000;
|
||||
background: #000;
|
||||
|
||||
video {
|
||||
height: 100%;
|
||||
}
|
||||
.player-video-wrapper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
video {
|
||||
height: 100%;
|
||||
}
|
||||
.player-captions {
|
||||
top: auto;
|
||||
bottom: 90px;
|
||||
@ -537,6 +585,17 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
// Hide controls when playing in full screen
|
||||
&.fullscreen-hide-controls.playing .player-controls {
|
||||
transform: translateY(100%) translateY($control-spacing / 2);
|
||||
transition: transform .3s 1s ease;
|
||||
|
||||
&.hover {
|
||||
transform: translateY(0);
|
||||
transition-delay: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change icons on state change
|
||||
@ -563,10 +622,4 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
|
||||
&.fullscreen-enabled [data-player='fullscreen'] + label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Full browser view hides toggle
|
||||
&-fullscreen [data-player='fullscreen'],
|
||||
&-fullscreen [data-player='fullscreen'] + label {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user