Compare commits

..

36 Commits

Author SHA1 Message Date
a327056789 Seek fixes for touch 2016-01-25 11:25:32 +11:00
b006b73c69 Fix for control tooltips always showing 2016-01-25 11:02:35 +11:00
3127cea1b2 SASS fix (fixes #149) 2016-01-25 08:36:53 +11:00
a965d8a893 Seek tooltip, bug fixes for SASS, fullscreen and icons 2016-01-24 11:25:31 +11:00
173e651e3f Comment 2016-01-23 12:24:58 +11:00
fa5cb828c0 Update controls.md 2016-01-21 09:49:00 +11:00
5978810b7f Update controls.md 2016-01-21 09:48:46 +11:00
6c251794c8 Merge branch 'master' of github.com:selz/plyr 2016-01-21 09:43:40 +11:00
76917751e3 Small bug fixes 2016-01-21 09:43:27 +11:00
e75a9b89b0 Merge pull request #147 from christianpv/patch-3
Update bundles.json - Fix path to sass dir.
2016-01-21 09:06:08 +11:00
a0fe61011f Update bundles.json - Fix path to sass dir. 2016-01-20 12:40:04 -05:00
84a1b03d7d Docs update 2016-01-19 17:15:50 +11:00
b9177e7892 Minor bug fix for clicking video to play/pause after source change 2016-01-19 11:36:30 +11:00
fd12247a62 Fix for video click 2016-01-19 11:34:04 +11:00
20a71300a5 Controls 2016-01-19 09:54:23 +11:00
70c5b24678 Added reference 2016-01-19 09:35:10 +11:00
a87e87f93c Version bump 2016-01-19 09:32:04 +11:00
1b54ff0ad3 Listen for durationchange 2016-01-19 09:30:37 +11:00
3075e1eda2 Docs 2016-01-19 09:22:39 +11:00
8d1e014a40 Docs 2016-01-19 00:46:00 +11:00
0c52fe0c7c Added events line 2016-01-19 00:43:22 +11:00
bb25f8d02a Removed broken links 2016-01-19 00:41:30 +11:00
42c955c5eb Removed onSetup from docs code 2016-01-19 00:33:22 +11:00
268223ac52 Version bump 2016-01-19 00:31:28 +11:00
b81b8c1d31 Event listeners 2016-01-19 00:30:25 +11:00
5b2a016241 Merge branch 'master' of github.com:selz/plyr 2016-01-18 19:48:20 +11:00
a665121b52 Types enum 2016-01-18 19:48:14 +11:00
02d312f2d2 Style tweaks 2016-01-18 18:27:01 +11:00
c23c150fe9 Merge branch 'master' of https://github.com/Selz/plyr 2016-01-18 17:35:32 +11:00
2e5bdb338e Tidying up, Vimeo fix 2016-01-18 17:35:18 +11:00
c51ef05067 Update readme.md 2016-01-18 11:24:31 +11:00
Sam
dbe152a4c1 LESS/SASS variable name spacing and clean up 2016-01-17 19:22:43 +11:00
3f42e53d95 Don't add video hash 2016-01-17 10:48:26 +11:00
54b0dc5273 Docs tweak 2016-01-17 10:41:13 +11:00
d6b67c3388 Docs pushstate for tabs 2016-01-17 10:39:05 +11:00
Sam
a277224ef4 Reverted docs.js changes 2016-01-17 01:29:34 +11:00
30 changed files with 899 additions and 553 deletions

View File

@ -4,7 +4,7 @@
"plyr.css": ["src/less/plyr.less"] "plyr.css": ["src/less/plyr.less"]
}, },
"sass": { "sass": {
"plyr.css": ["src/less/plyr.sass"] "plyr.css": ["src/sass/plyr.sass"]
}, },
"js": { "js": {
"plyr.js": ["src/js/plyr.js"] "plyr.js": ["src/js/plyr.js"]

View File

@ -1,5 +1,37 @@
# Changelog # Changelog
## v1.5.8
- Fix for touch device seek tooltip
- Seek improvements
## v1.5.7
- Fix for control tooltips always showing
## v1.5.6
- Seek tooltip (option for tooltips changed, please check docs)
- SASS compile error fixes (fixes #148)
- Fullscreen fixes for controls not always hiding/showing (fixes #149)
- Screen reader icon fixes (title was being read twice due to the tooltip/hidden label)
## v1.5.5
- Fixed controls.md example
- Bug fix for docs error page
- Bug fix for controls tooltips
## v1.5.4
- Minor bug fix for clicking video to play/pause after source change
## v1.5.3
- Minor bug fix for occasional display of 0:00 as the media duration
## v1.5.2
- `handlers` option renamed to `listeners`
- Added event listeners for all types to the plyr container (playback, fullscreen, captions etc - see docs)
- Removed onSetup config option (use the 'setup' event instead, plyr element is event.plyr)
- Style bug fixes
- Vimeo seek bug fix (requires whole seconds when seeking)
- Fix for fullscreen player (using class hook, not browser fullscreen)
## v1.5.1 ## v1.5.1
- Fix for event listeners being duplicated on source change - Fix for event listeners being duplicated on source change

View File

@ -46,65 +46,70 @@ You can include only the controls you need when specifying custom html.
This is an example `html` option with all controls. This is an example `html` option with all controls.
```javascript ```javascript
["<div class='player-controls'>", var controls = ["<div class='plyr__controls'>",
"<div class='player-progress'>", "<div class='plyr__progress'>",
"<label for='seek{id}' class='sr-only'>Seek</label>", "<label for='seek{id}' class='plyr__sr-only'>Seek</label>",
"<input id='seek{id}' class='player-progress-seek' type='range' min='0' max='100' step='0.5' value='0' data-player='seek'>", "<input id='seek{id}' class='plyr__progress--seek' type='range' min='0' max='100' step='0.1' value='0' data-plyr='seek'>",
"<progress class='player-progress-played' max='100' value='0'>", "<progress class='plyr__progress--played' max='100' value='0'>",
"<span>0</span>% played", "<span>0</span>% played",
"</progress>", "</progress>",
"<progress class='player-progress-buffer' max='100' value='0'>", "<progress class='plyr__progress--buffer' max='100' value='0'>",
"<span>0</span>% buffered", "<span>0</span>% buffered",
"</progress>", "</progress>",
"</div>", "</div>",
"<span class='player-controls-left'>", "<span class='plyr__controls--left'>",
"<button type='button' data-player='restart'>", "<button type='button' data-plyr='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='plyr__sr-only'>Restart</span>",
"</button>", "</button>",
"<button type='button' data-player='rewind'>", "<button type='button' data-plyr='rewind'>",
"<svg><use xlink:href='#icon-rewind'></use></svg>", "<svg><use xlink:href='#icon-rewind'></use></svg>",
"<span class='sr-only'>Rewind {seektime} secs</span>", "<span class='plyr__sr-only'>Rewind {seektime} secs</span>",
"</button>", "</button>",
"<button type='button' data-player='play'>", "<button type='button' data-plyr='play'>",
"<svg><use xlink:href='#icon-play'></use></svg>", "<svg><use xlink:href='#icon-play'></use></svg>",
"<span class='sr-only'>Play</span>", "<span class='plyr__sr-only'>Play</span>",
"</button>", "</button>",
"<button type='button' data-player='pause'>", "<button type='button' data-plyr='pause'>",
"<svg><use xlink:href='#icon-pause'></use></svg>", "<svg><use xlink:href='#icon-pause'></use></svg>",
"<span class='sr-only'>Pause</span>", "<span class='plyr__sr-only'>Pause</span>",
"</button>", "</button>",
"<button type='button' data-player='fast-forward'>", "<button type='button' data-plyr='fast-forward'>",
"<svg><use xlink:href='#icon-fast-forward'></use></svg>", "<svg><use xlink:href='#icon-fast-forward'></use></svg>",
"<span class='sr-only'>Forward {seektime} secs</span>", "<span class='plyr__sr-only'>Forward {seektime} secs</span>",
"</button>", "</button>",
"<span class='player-time'>", "<span class='plyr__time'>",
"<span class='sr-only'>Current time</span>", "<span class='plyr__sr-only'>Current time</span>",
"<span class='player-current-time'>00:00</span>", "<span class='plyr__current-time'>00:00</span>",
"</span>", "</span>",
"<span class='player-time'>", "<span class='plyr__time'>",
"<span class='sr-only'>Duration</span>", "<span class='plyr__sr-only'>Duration</span>",
"<span class='player-duration'>00:00</span>", "<span class='plyr__duration'>00:00</span>",
"</span>", "</span>",
"</span>", "</span>",
"<span class='player-controls-right'>", "<span class='plyr__controls--right'>",
"<button type='button' data-player='mute'>", "<button type='button' data-plyr='mute'>",
"<svg class='icon-muted'><use xlink:href='#icon-muted'></use></svg>", "<svg class='icon--muted'><use xlink:href='#icon-muted'></use></svg>",
"<svg><use xlink:href='#icon-volume'></use></svg>", "<svg><use xlink:href='#icon-volume'></use></svg>",
"<span class='sr-only'>Toggle Mute</span>", "<span class='plyr__sr-only'>Toggle Mute</span>",
"</button>", "</button>",
"<label for='volume{id}' class='sr-only'>Volume</label>", "<label for='volume{id}' class='plyr__sr-only'>Volume</label>",
"<input id='volume{id}' class='player-volume' type='range' min='0' max='10' value='5' data-player='volume'>", "<input id='volume{id}' class='plyr__volume' type='range' min='0' max='10' value='5' data-plyr='volume'>",
"<button type='button' data-player='captions'>", "<button type='button' data-plyr='captions'>",
"<svg class='icon-captions-on'><use xlink:href='#icon-captions-on'></use></svg>", "<svg class='icon--captions-on'><use xlink:href='#icon-captions-on'></use></svg>",
"<svg><use xlink:href='#icon-captions-off'></use></svg>", "<svg><use xlink:href='#icon-captions-off'></use></svg>",
"<span class='sr-only'>Toggle Captions</span>", "<span class='plyr__sr-only'>Toggle Captions</span>",
"</button>", "</button>",
"<button type='button' data-player='fullscreen'>", "<button type='button' data-plyr='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='plyr__sr-only'>Toggle Fullscreen</span>",
"</button>", "</button>",
"</span>", "</span>",
"</div>"].join("\n"); "</div>"].join("\n");
// Setup the player
plyr.setup('.js-player', {
html: controls
});
``` ```

2
dist/plyr.css vendored

File diff suppressed because one or more lines are too long

3
dist/plyr.js vendored

File diff suppressed because one or more lines are too long

2
dist/sprite.svg vendored
View File

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="icon-captions-off" viewBox="0 0 18 18"><title>Captions Off</title><path d="M1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1h16c.552 0 1-.448 1-1V3c0-.552-.448-1-1-1H1zm1 12V4h14v10H2z"/></symbol><symbol id="icon-captions-on" viewBox="0 0 18 18"><title>Captions On</title><path d="M1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1h16c.552 0 1-.448 1-1V3c0-.552-.448-1-1-1H1zm1 12V4h14v10H2z"/><path d="M3 11h3v2H3zM12 11h3v2h-3zM7 11h4v2H7z"/></symbol><symbol id="icon-enter-fullscreen" viewBox="0 0 18 18"><title>Enter Fullscreen</title><path d="M10.3 9.7c.7.677 1.4 0 1.4 0L16 5.4V10h2V3c0-.6-.4-1-1-1h-7v2h4.6l-4.3 4.3s-.7.723 0 1.4z"/><path d="M7 2v2H2v10h14v-1h2v2c0 .6-.4 1-1 1H1c-.6 0-1-.4-1-1V3c0-.6.4-1 1-1h6z"/></symbol><symbol id="icon-exit-fullscreen" viewBox="0 0 18 18"><title>Exit Fullscreen</title><path d="M7.7 8.3c-.7-.677-1.4 0-1.4 0L2 12.6V8H0v7c0 .6.4 1 1 1h7v-2H3.4l4.3-4.3s.7-.723 0-1.4z"/><path d="M11 16v-2h5V4H2v1H0V3c0-.6.4-1 1-1h16c.6 0 1 .4 1 1v12c0 .6-.4 1-1 1h-6z"/></symbol><symbol id="icon-fast-forward" viewBox="0 0 18 18"><title>Fast Forward</title><path d="M17.57 8.246L7 2c-.552 0-1 .448-1 1v1.954L1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1l5-2.955V15c0 .552.448 1 1 1l10.57-6.246c.266-.158.43-.444.43-.754s-.164-.597-.43-.754zM6 10.722l-4 2.364V4.914l4 2.364v3.444zm2 2.364V4.914L14.915 9 8 13.086z"/></symbol><symbol id="icon-muted" viewBox="0 0 18 18"><title>Muted</title><path d="M9.214 2c-.11 0-.225.032-.334.1L4.832 4.91C4.75 4.97 4.65 5 4.55 5H.995C.446 5 0 5.448 0 6v6c0 .552.446 1 .996 1H4.55c.1 0 .2.03.282.09L8.88 15.9c.11.068.223.1.334.1.392 0 .747-.4.747-.95V2.95c0-.55-.354-.95-.746-.95zM7.97 12.834L5.58 11.177c-.166-.115-.364-.178-.566-.178H2.49c-.274 0-.497-.225-.497-.5v-3c0-.277.223-.5.498-.5h2.526c.202 0 .4-.063.566-.18L7.97 5.165v7.67zM14.934 8.8c-.086-1.75-1.514-2.992-2.507-3.65-.47-.312-1.094-.122-1.325.408l-.038.086c-.188.43-.045.94.336 1.194.706.473 1.586 1.247 1.624 2.065.032.676-.553 1.468-1.663 2.27-.397.288-.528.84-.284 1.275l.042.075c.266.475.866.624 1.3.312 1.74-1.25 2.586-2.606 2.516-4.037z"/><path d="M13.957 9.2c.086 1.747 1.514 2.99 2.507 3.648.47.312 1.094.122 1.325-.408l.037-.086c.188-.43.045-.94-.336-1.194-.705-.473-1.585-1.247-1.623-2.065-.032-.676.553-1.468 1.663-2.27.398-.288.53-.84.285-1.275l-.042-.075c-.266-.475-.866-.624-1.3-.312-1.74 1.25-2.586 2.606-2.516 4.037z"/></symbol><symbol id="icon-pause" viewBox="0 0 18 18"><title>Pause</title><path d="M2 4v10c0 2 2 2 2 2h2s2 0 2-2V4c0-2-2-2-2-2H4S2 2 2 4zm2 0h2v10H4V4zM10 4v10c0 2 2 2 2 2h2s2 0 2-2V4c0-2-2-2-2-2h-2s-2 0-2 2zm2 0h2v10h-2V4z"/></symbol><symbol id="icon-play" viewBox="0 0 18 18"><title>Play</title><path d="M5 4.914L11.915 9 5 13.086V4.914zM4 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1l10.57-6.246c.266-.158.43-.444.43-.754s-.164-.597-.43-.754L4 2z"/></symbol><symbol id="icon-restart" viewBox="0 0 16 16"><path d="M7.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C4 2.6 2.9 3.2 2 4.1-.7 6.8-.7 11.2 2 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L14 1.9l-6.3-.7z"/></symbol><symbol id="icon-rewind" viewBox="0 0 18 21"><title>Rewind</title><path d="M.43 10.754L11 17c.552 0 1-.448 1-1v-1.954L17 17c.552 0 1-.448 1-1V4c0-.552-.448-1-1-1l-5 2.955V4c0-.552-.448-1-1-1L.43 9.246C.165 9.404 0 9.69 0 10s.164.597.43.754zM12 8.278l4-2.364v8.172l-4-2.364V8.278zm-2-2.364v8.172L3.085 10 10 5.914z"/></symbol><symbol id="icon-volume" viewBox="0 0 18 18"><title>Volume</title><path d="M10.214 2c-.11 0-.225.032-.334.1L5.832 4.91C5.75 4.97 5.65 5 5.55 5H1.995C1.446 5 1 5.448 1 6v6c0 .552.446 1 .996 1H5.55c.1 0 .2.03.282.09L9.88 15.9c.11.068.223.1.334.1.392 0 .747-.4.747-.95V2.95c0-.55-.354-.95-.746-.95zM8.97 12.834L6.58 11.177c-.166-.115-.364-.178-.566-.178H3.49c-.274 0-.497-.225-.497-.5v-3c0-.277.223-.5.498-.5h2.526c.202 0 .4-.063.566-.18L8.97 5.165v7.67zM16.934 8.8c-.086-1.75-1.514-2.992-2.507-3.65-.47-.312-1.094-.122-1.325.408l-.038.086c-.188.43-.045.94.336 1.194.706.473 1.586 1.247 1.624 2.065.032.676-.553 1.468-1.663 2.27-.397.288-.528.84-.284 1.275l.042.075c.266.475.866.624 1.3.312 1.74-1.25 2.586-2.606 2.516-4.037z"/></symbol></svg> <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="icon-captions-off" viewBox="0 0 18 18"><path d="M1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1h16c.552 0 1-.448 1-1V3c0-.552-.448-1-1-1H1zm1 12V4h14v10H2z"/></symbol><symbol id="icon-captions-on" viewBox="0 0 18 18"><path d="M1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1h16c.552 0 1-.448 1-1V3c0-.552-.448-1-1-1H1zm1 12V4h14v10H2z"/><path d="M3 11h3v2H3zM12 11h3v2h-3zM7 11h4v2H7z"/></symbol><symbol id="icon-enter-fullscreen" viewBox="0 0 18 18"><path d="M10.3 9.7c.7.677 1.4 0 1.4 0L16 5.4V10h2V3c0-.6-.4-1-1-1h-7v2h4.6l-4.3 4.3s-.7.723 0 1.4z"/><path d="M7 2v2H2v10h14v-1h2v2c0 .6-.4 1-1 1H1c-.6 0-1-.4-1-1V3c0-.6.4-1 1-1h6z"/></symbol><symbol id="icon-exit-fullscreen" viewBox="0 0 18 18"><path d="M7.7 8.3c-.7-.677-1.4 0-1.4 0L2 12.6V8H0v7c0 .6.4 1 1 1h7v-2H3.4l4.3-4.3s.7-.723 0-1.4z"/><path d="M11 16v-2h5V4H2v1H0V3c0-.6.4-1 1-1h16c.6 0 1 .4 1 1v12c0 .6-.4 1-1 1h-6z"/></symbol><symbol id="icon-fast-forward" viewBox="0 0 18 18"><path d="M17.57 8.246L7 2c-.552 0-1 .448-1 1v1.954L1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1l5-2.955V15c0 .552.448 1 1 1l10.57-6.246c.266-.158.43-.444.43-.754s-.164-.597-.43-.754zM6 10.722l-4 2.364V4.914l4 2.364v3.444zm2 2.364V4.914L14.915 9 8 13.086z"/></symbol><symbol id="icon-muted" viewBox="0 0 18 18"><path d="M9.214 2c-.11 0-.225.032-.334.1L4.832 4.91C4.75 4.97 4.65 5 4.55 5H.995C.446 5 0 5.448 0 6v6c0 .552.446 1 .996 1H4.55c.1 0 .2.03.282.09L8.88 15.9c.11.068.223.1.334.1.392 0 .747-.4.747-.95V2.95c0-.55-.354-.95-.746-.95zM7.97 12.834L5.58 11.177c-.166-.115-.364-.178-.566-.178H2.49c-.274 0-.497-.225-.497-.5v-3c0-.277.223-.5.498-.5h2.526c.202 0 .4-.063.566-.18L7.97 5.165v7.67zM14.934 8.8c-.086-1.75-1.514-2.992-2.507-3.65-.47-.312-1.094-.122-1.325.408l-.038.086c-.188.43-.045.94.336 1.194.706.473 1.586 1.247 1.624 2.065.032.676-.553 1.468-1.663 2.27-.397.288-.528.84-.284 1.275l.042.075c.266.475.866.624 1.3.312 1.74-1.25 2.586-2.606 2.516-4.037z"/><path d="M13.957 9.2c.086 1.747 1.514 2.99 2.507 3.648.47.312 1.094.122 1.325-.408l.037-.086c.188-.43.045-.94-.336-1.194-.705-.473-1.585-1.247-1.623-2.065-.032-.676.553-1.468 1.663-2.27.398-.288.53-.84.285-1.275l-.042-.075c-.266-.475-.866-.624-1.3-.312-1.74 1.25-2.586 2.606-2.516 4.037z"/></symbol><symbol id="icon-pause" viewBox="0 0 18 18"><path d="M2 4v10c0 2 2 2 2 2h2s2 0 2-2V4c0-2-2-2-2-2H4S2 2 2 4zm2 0h2v10H4V4zM10 4v10c0 2 2 2 2 2h2s2 0 2-2V4c0-2-2-2-2-2h-2s-2 0-2 2zm2 0h2v10h-2V4z"/></symbol><symbol id="icon-play" viewBox="0 0 18 18"><path d="M5 4.914L11.915 9 5 13.086V4.914zM4 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1l10.57-6.246c.266-.158.43-.444.43-.754s-.164-.597-.43-.754L4 2z"/></symbol><symbol id="icon-restart" viewBox="0 0 16 16"><path d="M7.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C4 2.6 2.9 3.2 2 4.1-.7 6.8-.7 11.2 2 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L14 1.9l-6.3-.7z"/></symbol><symbol id="icon-rewind" viewBox="0 0 18 21"><path d="M.43 10.754L11 17c.552 0 1-.448 1-1v-1.954L17 17c.552 0 1-.448 1-1V4c0-.552-.448-1-1-1l-5 2.955V4c0-.552-.448-1-1-1L.43 9.246C.165 9.404 0 9.69 0 10s.164.597.43.754zM12 8.278l4-2.364v8.172l-4-2.364V8.278zm-2-2.364v8.172L3.085 10 10 5.914z"/></symbol><symbol id="icon-volume" viewBox="0 0 18 18"><path d="M10.214 2c-.11 0-.225.032-.334.1L5.832 4.91C5.75 4.97 5.65 5 5.55 5H1.995C1.446 5 1 5.448 1 6v6c0 .552.446 1 .996 1H5.55c.1 0 .2.03.282.09L9.88 15.9c.11.068.223.1.334.1.392 0 .747-.4.747-.95V2.95c0-.55-.354-.95-.746-.95zM8.97 12.834L6.58 11.177c-.166-.115-.364-.178-.566-.178H3.49c-.274 0-.497-.225-.497-.5v-3c0-.277.223-.5.498-.5h2.526c.202 0 .4-.063.566-.18L8.97 5.165v7.67zM16.934 8.8c-.086-1.75-1.514-2.992-2.507-3.65-.47-.312-1.094-.122-1.325.408l-.038.086c-.188.43-.045.94.336 1.194.706.473 1.586 1.247 1.624 2.065.032.676-.553 1.468-1.663 2.27-.397.288-.528.84-.284 1.275l.042.075c.266.475.866.624 1.3.312 1.74-1.25 2.586-2.606 2.516-4.037z"/></symbol></svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

2
docs/dist/docs.css vendored

File diff suppressed because one or more lines are too long

2
docs/dist/docs.js vendored
View File

@ -1 +1 @@
"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var n,s=arguments.length;for(n=0;s>n;n++)e=arguments[n],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:n.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",n="prototype",s=e.Element[n],i=Object,o=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[n].indexOf||function(e){for(var t=0,n=this.length;n>t;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return r.call(e,t)},l=function(e){for(var t=o.call(e.getAttribute("class")||""),n=t?t.split(/\s+/):[],s=0,i=n.length;i>s;s++)this.push(n[s]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[n]=[],p=function(){return new l(this)};if(a[n]=Error[n],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",-1!==c(this,e)},u.add=function(){var e,t=arguments,n=0,s=t.length,i=!1;do e=t[n]+"",-1===c(this,e)&&(this.push(e),i=!0);while(++n<s);i&&this._updateClassName()},u.remove=function(){var e,t,n=arguments,s=0,i=n.length,o=!1;do for(e=n[s]+"",t=c(this,e);-1!==t;)this.splice(t,1),o=!0,t=c(this,e);while(++s<i);o&&this._updateClassName()},u.toggle=function(e,t){e+="";var n=this.contains(e),s=n?t!==!0&&"remove":t!==!1&&"add";return s&&this[s](e),t===!0||t===!1?t:!n},u.toString=function(){return this.join(" ")},i.defineProperty){var d={get:p,enumerable:!0,configurable:!0};try{i.defineProperty(s,t,d)}catch(h){-2146823252===h.number&&(d.enumerable=!1,i.defineProperty(s,t,d))}}else i[n].__defineGetter__&&s.__defineGetter__(t,p)}}(self)),plyr.setup(".js-media-player",{debug:!0,title:"Video demo",tooltips:!0,captions:{defaultActive:!0},onSetup:function(){console.log("✓ Setup done")}}),shr.setup({count:{classname:"btn__count"}}),function(){function e(e,t,n){if(e)if(e.classList)e.classList[n?"add":"remove"](t);else{var s=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=s+(n?" "+t:"")}}function t(){var t=this,s=t.getAttribute("data-source"),i=document.querySelector(".js-media-player").plyr;switch(s){case"video":i.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"},{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm",type:"video/webm"}],poster:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.0/example_captions_en.vtt","default":!0}]});break;case"audio":i.source({type:"audio",title:"Kishi Bashi &ndash; &ldquo;It All Began With A Burst&rdquo;",sources:[{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]});break;case"youtube":i.source({type:"video",title:"View From A Blue Moon",sources:[{src:"bTqVqk7FSmY",type:"youtube"}]});break;case"vimeo":i.source({type:"video",title:"View From A Blue Moon",sources:[{src:"143418951",type:"vimeo"}]})}window.history&&window.history.pushState&&history.pushState({type:s},"","#"+s);for(var o=n.length-1;o>=0;o--)e(n[o].parentElement,"active",!1);e((event.target||event.srcElement).parentElement,"active",!0)}for(var n=document.querySelectorAll("[data-source]"),s=n.length-1;s>=0;s--)n[s].addEventListener("click",t);window.addEventListener("popstate",function(e){console.log(e)})}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,n,s,i,o,r){e.GoogleAnalyticsObject=i,e[i]=e[i]||function(){(e[i].q=e[i].q||[]).push(arguments)},e[i].l=1*new Date,o=t.createElement(n),r=t.getElementsByTagName(n)[0],o.async=1,o.src=s,r.parentNode.insertBefore(o,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview")); "document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,n=arguments.length;for(i=0;n>i;i++)e=arguments[i],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var i=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:i.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",i="prototype",n=e.Element[i],s=Object,o=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[i].indexOf||function(e){for(var t=0,i=this.length;i>t;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return r.call(e,t)},l=function(e){for(var t=o.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],n=0,s=i.length;s>n;n++)this.push(i[n]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[i]=[],d=function(){return new l(this)};if(a[i]=Error[i],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",-1!==c(this,e)},u.add=function(){var e,t=arguments,i=0,n=t.length,s=!1;do e=t[i]+"",-1===c(this,e)&&(this.push(e),s=!0);while(++i<n);s&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,n=0,s=i.length,o=!1;do for(e=i[n]+"",t=c(this,e);-1!==t;)this.splice(t,1),o=!0,t=c(this,e);while(++n<s);o&&this._updateClassName()},u.toggle=function(e,t){e+="";var i=this.contains(e),n=i?t!==!0&&"remove":t!==!1&&"add";return n&&this[n](e),t===!0||t===!1?t:!i},u.toString=function(){return this.join(" ")},s.defineProperty){var p={get:d,enumerable:!0,configurable:!0};try{s.defineProperty(n,t,p)}catch(h){-2146823252===h.number&&(p.enumerable=!1,s.defineProperty(n,t,p))}}else s[i].__defineGetter__&&n.__defineGetter__(t,d)}}(self)),plyr.setup(".js-media-player",{debug:!0,title:"Video demo",tooltips:{controls:!0},captions:{defaultActive:!0}}),shr.setup({count:{classname:"btn__count"}}),function(){function e(e,t,i){if(e)if(e.classList)e.classList[i?"add":"remove"](t);else{var n=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=n+(i?" "+t:"")}}function t(t,o){if(!(t in n)||!o&&t==s||!s.length&&t==n.video)return void console.warn("Unregonized type.");var r=document.querySelector(".js-media-player").plyr;switch(t){case n.video:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"},{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm",type:"video/webm"}],poster:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.vtt","default":!0}]});break;case n.audio:r.source({type:"audio",title:"Kishi Bashi &ndash; &ldquo;It All Began With A Burst&rdquo;",sources:[{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]});break;case n.youtube:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"bTqVqk7FSmY",type:"youtube"}]});break;case n.vimeo:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"143418951",type:"vimeo"}]})}s=t;for(var a=i.length-1;a>=0;a--)e(i[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}for(var i=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},s=window.location.hash.replace("#",""),o=window.history&&window.history.pushState,r=i.length-1;r>=0;r--)i[r].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),o&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),o){var a=!s.length;a&&(s=n.video),s in n&&history.replaceState({type:s},"",a?"":"#"+s),a||t(s,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,n,s,o,r){e.GoogleAnalyticsObject=s,e[s]=e[s]||function(){(e[s].q=e[s].q||[]).push(arguments)},e[s].l=1*new Date,o=t.createElement(i),r=t.getElementsByTagName(i)[0],o.async=1,o.src=n,r.parentNode.insertBefore(o,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview"));

View File

@ -12,7 +12,7 @@
<main> <main>
<h1>Doh.</h1> <h1>Doh.</h1>
<p>Looks like something went wrong.</p> <p>Looks like something went wrong.</p>
<a href="http://plyr.io" class="btn">Back to plyr.io</a> <a href="http://plyr.io" class="btn btn--primary">Back to plyr.io</a>
</main> </main>
</body> </body>
</html> </html>

View File

@ -58,7 +58,7 @@
<source src="https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm" type="video/webm"> <source src="https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm" type="video/webm">
<!-- Text track file --> <!-- Text track file -->
<track kind="captions" label="English" srclang="en" src="https://cdn.selz.com/plyr/1.0/example_captions_en.vtt" default> <track kind="captions" label="English" srclang="en" src="https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.vtt" default>
<!-- Fallback for browsers that don't support the <video> element --> <!-- Fallback for browsers that don't support the <video> element -->
<a href="https://cdn.selz.com/plyr/1.0/movie.mp4">Download</a> <a href="https://cdn.selz.com/plyr/1.0/movie.mp4">Download</a>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 KiB

View File

@ -6,14 +6,13 @@
// Setup the player // Setup the player
plyr.setup('.js-media-player', { plyr.setup('.js-media-player', {
debug: true, debug: true,
title: 'Video demo', title: 'Video demo',
tooltips: true, tooltips: {
captions: { controls: true
defaultActive: true
}, },
onSetup: function() { captions: {
console.log('✓ Setup done'); defaultActive: true
} }
}); });
@ -26,17 +25,51 @@ shr.setup({
// General functions // General functions
(function() { (function() {
var buttons = document.querySelectorAll('[data-source]'); var buttons = document.querySelectorAll('[data-source]'),
types = {
video: 'video',
audio: 'audio',
youtube: 'youtube',
vimeo: 'vimeo'
},
currentType = window.location.hash.replace('#', ''),
historySupport = (window.history && window.history.pushState);
// Bind to each button // Bind to each button
for (var i = buttons.length - 1; i >= 0; i--) { for (var i = buttons.length - 1; i >= 0; i--) {
buttons[i].addEventListener('click', newSource); buttons[i].addEventListener('click', function() {
var type = this.getAttribute('data-source');
newSource(type);
if (historySupport) {
history.pushState({ 'type': type }, '', '#' + type);
}
});
} }
// List for backwards/forwards
window.addEventListener('popstate', function(event) { window.addEventListener('popstate', function(event) {
console.log(event); if(event.state && 'type' in event.state) {
newSource(event.state.type);
}
}); });
// On load
if(historySupport) {
var video = !currentType.length;
if(video) {
currentType = types.video;
}
if(currentType in types) {
history.replaceState({ 'type': currentType }, '', (video ? '' : '#' + currentType));
}
if(!video) {
newSource(currentType, true);
}
}
// Toggle class on an element
function toggleClass(element, className, state) { function toggleClass(element, className, state) {
if (element) { if (element) {
if (element.classList) { if (element.classList) {
@ -50,13 +83,18 @@ shr.setup({
} }
// Set a new source // Set a new source
function newSource() { function newSource(type, init) {
var trigger = this, // Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
type = trigger.getAttribute('data-source'), if(!(type in types) || (!init && type == currentType) || (!currentType.length && type == types.video)) {
player = document.querySelector('.js-media-player').plyr; console.warn('Unregonized type.');
return;
}
// Get plyr instance
var player = document.querySelector('.js-media-player').plyr;
switch(type) { switch(type) {
case 'video': case types.video:
player.source({ player.source({
type: 'video', type: 'video',
title: 'View From A Blue Moon', title: 'View From A Blue Moon',
@ -73,13 +111,13 @@ shr.setup({
kind: 'captions', kind: 'captions',
label: 'English', label: 'English',
srclang:'en', srclang:'en',
src: 'https://cdn.selz.com/plyr/1.0/example_captions_en.vtt', src: 'https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.vtt',
default: true default: true
}] }]
}); });
break; break;
case 'audio': case types.audio:
player.source({ player.source({
type: 'audio', type: 'audio',
title: 'Kishi Bashi &ndash; &ldquo;It All Began With A Burst&rdquo;', title: 'Kishi Bashi &ndash; &ldquo;It All Began With A Burst&rdquo;',
@ -94,7 +132,7 @@ shr.setup({
}); });
break; break;
case 'youtube': case types.youtube:
player.source({ player.source({
type: 'video', type: 'video',
title: 'View From A Blue Moon', title: 'View From A Blue Moon',
@ -105,7 +143,7 @@ shr.setup({
}); });
break; break;
case 'vimeo': case types.vimeo:
player.source({ player.source({
type: 'video', type: 'video',
title: 'View From A Blue Moon', title: 'View From A Blue Moon',
@ -117,15 +155,16 @@ shr.setup({
break; break;
} }
if (window.history && window.history.pushState) { // Set the current type for next time
history.pushState({ 'type': type }, '', '#' + type); currentType = type;
}
// Remove active classes
for (var x = buttons.length - 1; x >= 0; x--) { for (var x = buttons.length - 1; x >= 0; x--) {
toggleClass(buttons[x].parentElement, 'active', false); toggleClass(buttons[x].parentElement, 'active', false);
} }
toggleClass((event.target || event.srcElement).parentElement, 'active', true); // Set active on parent
toggleClass(document.querySelector('[data-source="'+ type +'"]').parentElement, 'active', true);
} }
})(); })();

View File

@ -50,7 +50,12 @@ video,
} }
.plyr__progress { .plyr__progress {
border-radius: @border-radius-base @border-radius-base 0 0; border-radius: @border-radius-base @border-radius-base 0 0;
overflow: hidden;
progress,
[type='range'] {
border-radius: @border-radius-base @border-radius-base 0 0;
overflow: hidden;
}
} }
} }

View File

@ -253,6 +253,7 @@ gulp.task("docs", function () {
// Upload error.html to cdn (as well as docs site) // Upload error.html to cdn (as well as docs site)
gulp.src([paths.docs.root + "error.html"]) gulp.src([paths.docs.root + "error.html"])
.pipe(replace(localpath, "https://" + aws.cdn.bucket + "/" + version))
.pipe(gzip()) .pipe(gzip())
.pipe(s3(aws.cdn, options.docs)); .pipe(s3(aws.cdn, options.docs));
}); });

View File

@ -1,6 +1,6 @@
{ {
"name": "plyr", "name": "plyr",
"version": "1.5.1", "version": "1.5.8",
"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",

222
readme.md
View File

@ -6,20 +6,21 @@ A simple, accessible and customizable HTML5, YouTube and Vimeo media player.
[![Image of Plyr](https://cdn.plyr.io/static/plyr-v1.5.jpg)](http://plyr.io) [![Image of Plyr](https://cdn.plyr.io/static/plyr-v1.5.jpg)](http://plyr.io)
## Why? ## Why?
We wanted a lightweight, accessible and customizable media player that just supports [*modern*](#browser-support) browsers. Sure, there are many other players out there but we wanted to keep things simple, using the right elements for the job. We wanted a lightweight, accessible and customizable media player that supports [*modern*](#browser-support) browsers. Sure, there are many other players out there but we wanted to keep things simple, using the right elements for the job.
## Features ## Features
- **Accessible** - full support for VTT captions and screen readers. - **Accessible** - full support for VTT captions and screen readers
- **Lightweight** - just 8KB minified and gzipped. - **Lightweight** - under 10KB minified and gzipped
- **[Customisable](#html)** - make the player look how you want with the markup you want. - **[Customisable](#html)** - 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. - **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. - **Responsive** - as you'd expect these days
- **Audio & Video** - support for both formats. - **HTML Video & Audio** - support for both formats
- **[Embedded Video](#embeds)** - support for YouTube and Vimeo (beta). - **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback
- **[API](#api)** - toggle playback, volume, seeking, and more. - **[API](#api)** - toggle playback, volume, seeking, and more
- **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes. - **[Universal events](#events)** - no messing around with Vimeo and YouTube APIs, all events are universal across formats
- **i18n support** - support for internationalization of controls. - **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes
- **No dependencies** - written in vanilla JavaScript, no jQuery required. - **i18n support** - support for internationalization of controls
- **No dependencies** - written in "vanilla" JavaScript, no jQuery required
Oh and yes, it works with Bootstrap. Oh and yes, it works with Bootstrap.
@ -39,7 +40,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.5.1/plyr.js` to `https://cdn.plyr.io/1.5.1/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.5.8/plyr.js` to `https://cdn.plyr.io/1.5.8/plyr.js`
### Bower ### Bower
If bower is your thang, you can grab Plyr using: If bower is your thang, you can grab Plyr using:
@ -59,11 +60,11 @@ More info is on [npm](https://www.npmjs.com/package/ember-cli-plyr) and [GitHub]
If you want to use our CDN, you can use the following: If you want to use our CDN, you can use the following:
```html ```html
<link rel="stylesheet" href="https://cdn.plyr.io/1.5.1/plyr.css"> <link rel="stylesheet" href="https://cdn.plyr.io/1.5.8/plyr.css">
<script src="https://cdn.plyr.io/1.5.1/plyr.js"></script> <script src="https://cdn.plyr.io/1.5.8/plyr.js"></script>
``` ```
You can also access the `sprite.svg` file at `https://cdn.plyr.io/1.5.1/sprite.svg`. You can also access the `sprite.svg` file at `https://cdn.plyr.io/1.5.8/sprite.svg`.
### CSS & Styling ### CSS & Styling
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.
@ -134,11 +135,16 @@ And the same for `<audio>`
</div> </div>
``` ```
For YouTube, Plyr uses the standard YouTube API markup (an empty `<div>`): For YouTube and Vimeo, Plyr uses the standard YouTube API markup (an empty `<div>`):
```html ```html
<div class="plyr"> <div class="plyr">
<div data-video-id="L1h9xxCU20g" data-type="youtube"></div> <div data-video-id="bTqVqk7FSmY" data-type="youtube"></div>
</div>
```
```html
<div class="plyr">
<div data-video-id="143418951" data-type="vimeo"></div>
</div> </div>
``` ```
@ -155,7 +161,7 @@ More info on CORS here:
Here's an example of a default setup: Here's an example of a default setup:
```html ```html
<script src="https://cdn.plyr.io/1.5.1/plyr.js"></script> <script src="https://cdn.plyr.io/1.5.8/plyr.js"></script>
<script>plyr.setup();</script> <script>plyr.setup();</script>
``` ```
@ -253,9 +259,13 @@ Options must be passed as an object to the `setup()` method as above.
</tr> </tr>
<tr> <tr>
<td><code>tooltips</code></td> <td><code>tooltips</code></td>
<td>Boolean</td> <td>Object</td>
<td><code>false</code></td> <td><code>{ controls: false, seek: true }</code></td>
<td>Display control labels as tooltips on :hover &amp; :focus (by default, the labels are screen reader only).</td> <td>
<strong>controls</strong>: Display control labels as tooltips on :hover &amp; :focus (by default, the labels are screen reader only).
<br><br>
<strong>seek</strong>: Display a seek tooltip to indicate on click where the media would seek to.
</td>
</tr> </tr>
<tr> <tr>
<td><code>displayDuration</code></td> <td><code>displayDuration</code></td>
@ -270,10 +280,10 @@ Options must be passed as an object to the `setup()` method as above.
<td>See <code>plyr.js</code> in <code>/src</code> for more info. You probably don't need to change any of these.</td> <td>See <code>plyr.js</code> in <code>/src</code> for more info. You probably don't need to change any of these.</td>
</tr> </tr>
<tr> <tr>
<td><code>handlers</code></td> <td><code>listeners</code></td>
<td>Object</td> <td>Object</td>
<td>&mdash;</td> <td>&mdash;</td>
<td>Allows early binding of handlers to Plyr's controls. See <code>controls</code> above for list of controls and see <code>plyr.js</code> in <code>/src</code> for more info.</td> <td>Allows early binding of event listeners to the controls. See <code>controls</code> above for list of controls and see <code>plyr.js</code> in <code>/src</code> for more info.</td>
</tr> </tr>
<tr> <tr>
<td><code>classes</code></td> <td><code>classes</code></td>
@ -299,12 +309,6 @@ Options must be passed as an object to the `setup()` method as above.
<td>&mdash;</td> <td>&mdash;</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> <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>
<tr>
<td><code>onSetup</code></td>
<td>Function</td>
<td>&mdash;</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> </tbody>
</table> </table>
@ -364,7 +368,7 @@ Or you can use the returned object from your call to the setup method:
var player = plyr.setup('.js-plyr')[0]; var player = plyr.setup('.js-plyr')[0];
``` ```
This will return an array of plyr instances setup, so you need to specify the index of the instance you want. This is less useful if you are setting up mutliple instances. You can also use the `onSetup` callback documented below which will return each instance one by one, as they are setup. This will return an array of plyr instances setup, so you need to specify the index of the instance you want. This is less useful if you are setting up mutliple instances. You can listen for the `setup` [event](#events) documented below which will return each instance one by one, as they are setup (in the `plyr` key of the event object).
Once you have your instance, you can use the API methods below on it. For example to pause it: Once you have your instance, you can use the API methods below on it. For example to pause it:
@ -599,39 +603,145 @@ Some more details on the object parameters
</table> </table>
## Events/Callbacks ## Events
The `plyr` object on the player element also contains a `media` property which is a reference to the `<audio>` or `<video>` element within the player which you can use to listen for events. Here's an example: You can listen for events on the element you setup Plyr on. Some events only apply to HTML5 audio and video.
<table class="table" width="100%">
<thead>
<tr>
<th width="20%">Event name</th>
<th width="20%">HTML5 only</th>
<th width="60%">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>canplay</code></td>
<td>✔</td>
<td>Sent when enough data is available that the media can be played, at least for a couple of frames. This corresponds to the <code>HAVE_ENOUGH_DATA</code> <code>readyState</code>.</td>
</tr>
<tr>
<td><code>canplaythrough</code></td>
<td></td>
<td>Sent when the ready state changes to <code>CAN_PLAY_THROUGH</code>, indicating that the entire media can be played without interruption, assuming the download rate remains at least at the current level. <strong>Note</strong>: Manually setting the <code>currentTime</code> will eventually fire a <code>canplaythrough</code> event in firefox. Other browsers might not fire this event.</td>
</tr>
<tr>
<td><code>emptied</code></td>
<td>✔</td>
<td>The media has become empty; for example, this event is sent if the media has already been loaded (or partially loaded), and the <code>load()</code> method is called to reload it.</td>
</tr>
<tr>
<td><code>ended</code></td>
<td></td>
<td>Sent when playback completes.</td>
</tr>
<tr>
<td><code>error</code></td>
<td>✔</td>
<td>Sent when an error occurs.&nbsp; The element's <code>error</code> attribute contains more information.</td>
</tr>
<tr>
<td><code>loadeddata/code></td>
<td>✔</td>
<td>The first frame of the media has finished loading.</td>
</tr>
<tr>
<td><code>loadedmetadata</code></td>
<td>✔</td>
<td>The media's metadata has finished loading; all attributes now contain as much useful information as they're going to.</td>
</tr>
<tr>
<td><code>loadstart</code></td>
<td>✔</td>
<td>Sent when loading of the media begins.</td>
</tr>
<tr>
<td><code>pause</code></td>
<td></td>
<td>Sent when playback is paused.</td>
</tr>
<tr>
<td><code>play</code></td>
<td></td>
<td>Sent when playback of the media starts after having been paused; that is, when playback is resumed after a prior <code>pause</code> event.</td>
</tr>
<tr>
<td><code>playing</code></td>
<td></td>
<td>Sent when the media begins to play (either for the first time, after having been paused, or after ending and then restarting).</td>
</tr>
<tr>
<td><code>progress</code></td>
<td></td>
<td>Sent periodically to inform interested parties of progress downloading the media. Information about the current amount of the media that has been downloaded is available in the media element's <code>buffered</code> attribute.</td>
</tr>
<tr>
<td><code>seeked</code></td>
<td>✔</td>
<td>Sent when a seek operation completes.</td>
</tr>
<tr>
<td><code>seeking</code></td>
<td>✔</td>
<td>Sent when a seek operation begins.</td>
</tr>
<tr>
<td><code>stalled</code></td>
<td>✔</td>
<td>Sent when the user agent is trying to fetch media data, but data is unexpectedly not forthcoming.</td>
</tr>
<tr>
<td><code>timeupdate</code></td>
<td></td>
<td>The time indicated by the element's <code>currentTime</code> attribute has changed.</td>
</tr>
<tr>
<td><code>volumechange</code></td>
<td></td>
<td>Sent when the audio volume changes (both when the volume is set and when the <code>muted</code> attribute is changed).</td>
</tr>
<tr>
<td><code>waiting</code></td>
<td>✔</td>
<td>Sent when the requested operation (such as playback) is delayed pending the completion of another operation (such as a seek).</td>
</tr>
<tr>
<td><code>enterfullscreen</code></td>
<td></td>
<td>User enters fullscreen (either the proper fullscreen or full-window fallback for older browsers)</td>
</tr>
<tr>
<td><code>exitfullscreen</code></td>
<td></td>
<td>User exits fullscreen</td>
</tr>
<tr>
<td><code>captionsenabled</code></td>
<td></td>
<td>Captions toggled on</td>
</tr>
<tr>
<td><code>captionsdisabled</code></td>
<td></td>
<td>Captions toggled off</td>
</tr>
</tbody>
</table>
Details borrowed from: [https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events)
Here's an example of binding an event listener:
```javascript ```javascript
var media = document.querySelector(".js-plyr").plyr.media; document.querySelector(".js-plyr").addEventListener("playing", function() {
/* Magic happens */
media.addEventListener("playing", function() {
console.log("playing");
}); });
``` ```
A complete list of events can be found here:
[Media Events - W3.org](http://www.w3.org/2010/05/video/mediaevents.html)
## Embeds ## Embeds
Currently only YouTube is supported. Vimeo will be coming soon. Some HTML5 media events are triggered on the `media` property of the `plyr` object: YouTube and Vimeo are currently supported and function much like a HTML5 video. Check the relevant documentation sections for any differences.
- `play`
- `pause`
- `timeupdate`
- `progress`
Due to the way the YouTube API works, the `timeupdate` and `progress` events are triggered by polling every 200ms so the event may trigger without an actual value change. Buffering progress is `media.buffered` in the `plyr` object. It is a a number between 0 and 1 that specifies the percentage of the video that the player shows as buffered.
```javascript
document.querySelector(".js-plyr").plyr.media.addEventListener("play", function() {
console.log("play");
});
```
The `.source()` API method can also be used but the video id must be passed as the argument.
Currently caption control is not supported but I will work on this.
## Fullscreen ## Fullscreen

View File

@ -1,6 +1,6 @@
// ========================================================================== // ==========================================================================
// Plyr // Plyr
// plyr.js v1.5.0 // plyr.js v1.5.3
// https://github.com/selz/plyr // https://github.com/selz/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
@ -37,7 +37,10 @@
seekTime: 10, seekTime: 10,
volume: 5, volume: 5,
click: true, click: true,
tooltips: false, tooltips: {
controls: false,
seek: true
},
displayDuration: true, displayDuration: true,
iconPrefix: 'icon', iconPrefix: 'icon',
selectors: { selectors: {
@ -46,7 +49,7 @@
container: null, container: null,
wrapper: '.plyr__controls' wrapper: '.plyr__controls'
}, },
labels: '[data-plyr] .sr-only, label .sr-only', labels: '[data-plyr]',
buttons: { buttons: {
seek: '[data-plyr="seek"]', seek: '[data-plyr="seek"]',
play: '[data-plyr="play"]', play: '[data-plyr="play"]',
@ -92,18 +95,6 @@
}, },
tabFocus: 'tab-focus' tabFocus: 'tab-focus'
}, },
handlers: {
seek: null,
play: null,
pause: null,
restart: null,
rewind: null,
forward: null,
mute: null,
volume: null,
captions: null,
fullscreen: null
},
captions: { captions: {
defaultActive: false defaultActive: false
}, },
@ -138,6 +129,7 @@
embed: ['youtube', 'vimeo'], embed: ['youtube', 'vimeo'],
html5: ['video', 'audio'] html5: ['video', 'audio']
}, },
// URLs
urls: { urls: {
vimeo: { vimeo: {
api: 'https://cdn.plyr.io/froogaloop/1.0.0/plyr.froogaloop.js', api: 'https://cdn.plyr.io/froogaloop/1.0.0/plyr.froogaloop.js',
@ -145,7 +137,22 @@
youtube: { youtube: {
api: 'https://www.youtube.com/iframe_api' api: 'https://www.youtube.com/iframe_api'
} }
} },
// Custom control listeners
listeners: {
seek: null,
play: null,
pause: null,
restart: null,
rewind: null,
forward: null,
mute: null,
volume: null,
captions: null,
fullscreen: null
},
// Events to watch on HTML5 media elements
events: ['ended', 'progress', 'stalled', 'playing', 'waiting', 'canplay', 'canplaythrough', 'loadstart', 'loadeddata', 'loadedmetadata', 'timeupdate', 'volumechange', 'play', 'pause', 'error', 'seeking', 'emptied']
}; };
// Build the default HTML // Build the default HTML
@ -155,15 +162,22 @@
'<div class="plyr__controls">', '<div class="plyr__controls">',
'<div class="plyr__progress">', '<div class="plyr__progress">',
'<label for="seek{id}" class="plyr__sr-only">Seek</label>', '<label for="seek{id}" class="plyr__sr-only">Seek</label>',
'<input id="seek{id}" class="plyr__progress--seek" type="range" min="0" max="100" step="0.5" value="0" data-plyr="seek">', '<input id="seek{id}" class="plyr__progress--seek" type="range" min="0" max="100" step="0.1" value="0" data-plyr="seek">',
'<progress class="plyr__progress--played" max="100" value="0">', '<progress class="plyr__progress--played" max="100" value="0">',
'<span>0</span>% ' + config.i18n.played, '<span>0</span>% ' + config.i18n.played,
'</progress>', '</progress>',
'<progress class="plyr__progress--buffer" max="100" value="0">', '<progress class="plyr__progress--buffer" max="100" value="0">',
'<span>0</span>% ' + config.i18n.buffered, '<span>0</span>% ' + config.i18n.buffered,
'</progress>', '</progress>'];
'</div>',
'<span class="plyr__controls--left">']; // Seek tooltip
if (config.tooltips.seek) {
html.push('<span class="plyr__tooltip">0:00</span>');
}
// Close progress
html.push('</div>',
'<span class="plyr__controls--left">');
// Restart button // Restart button
if (_inArray(config.controls, 'restart')) { if (_inArray(config.controls, 'restart')) {
@ -529,36 +543,36 @@
// Bind event // Bind event
function _on(element, events, callback) { function _on(element, events, callback) {
if (element) { if (element) {
_toggleHandler(element, events, callback, true); _toggleListener(element, events, callback, true);
} }
} }
// Unbind event // Unbind event
function _off(element, events, callback) { function _off(element, events, callback) {
if (element) { if (element) {
_toggleHandler(element, events, callback, false); _toggleListener(element, events, callback, false);
} }
} }
// Bind along with custom handler // Bind along with custom handler
function _proxyHandler(element, eventName, userHandler, defaultHandler) { function _proxyListener(element, eventName, userListener, defaultListener) {
_on(element, eventName, function(event) { _on(element, eventName, function(event) {
if(userHandler) { if(userListener) {
userHandler.apply(element, [event]); userListener.apply(element, [event]);
} }
defaultHandler.apply(element, [event]); defaultListener.apply(element, [event]);
}); });
} }
// Toggle event handler // Toggle event listener
function _toggleHandler(element, events, callback, toggle) { function _toggleListener(element, events, callback, toggle) {
var eventList = events.split(' '); var eventList = events.split(' ');
// If a nodelist is passed, call itself on each node // If a nodelist is passed, call itself on each node
if (element instanceof NodeList) { if (element instanceof NodeList) {
for (var x = 0; x < element.length; x++) { for (var x = 0; x < element.length; x++) {
if (element[x] instanceof Node) { if (element[x] instanceof Node) {
_toggleHandler(element[x], arguments[1], arguments[2], arguments[3]); _toggleListener(element[x], arguments[1], arguments[2], arguments[3]);
} }
} }
return; return;
@ -571,23 +585,21 @@
} }
// Trigger event // Trigger event
function _triggerEvent(element, event) { function _triggerEvent(element, eventName, properties) {
// Bail if no element // Bail if no element
if(!element || !event) { if(!element || !eventName) {
return; return;
} }
// Create faux event // create and dispatch the event
var fauxEvent = document.createEvent('MouseEvents'); var event = new CustomEvent(eventName, properties);
// Set the event type
fauxEvent.initEvent(event, true, true);
// Dispatch the event // Dispatch the event
element.dispatchEvent(fauxEvent); element.dispatchEvent(event);
} }
// Toggle aria-pressed state on a toggle button // Toggle aria-pressed state on a toggle button
// http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles
function _toggleState(target, state) { function _toggleState(target, state) {
// Bail if no target // Bail if no target
if(!target) { if(!target) {
@ -734,7 +746,8 @@
// Player instance // Player instance
function Plyr(container) { function Plyr(container) {
var plyr = this; var plyr = this;
plyr.container = container; plyr.container = container,
plyr.timers = {};
// Captions functions // Captions functions
// Seek the manual caption time and update UI // Seek the manual caption time and update UI
@ -786,6 +799,9 @@
else { else {
plyr.captionsContainer.innerHTML = ''; plyr.captionsContainer.innerHTML = '';
} }
// Force redraw
// var redraw = plyr.captionsContainer.offsetHeight;
} }
// Display captions container and button (for initialization) // Display captions container and button (for initialization)
@ -927,8 +943,8 @@
container.insertAdjacentHTML('beforeend', html); container.insertAdjacentHTML('beforeend', html);
// Setup tooltips // Setup tooltips
if (config.tooltips) { if (config.tooltips.controls) {
var labels = _getElements(config.selectors.labels); var labels = _getElements(config.selectors.labels + ' .' + config.classes.hidden);
for (var i = labels.length - 1; i >= 0; i--) { for (var i = labels.length - 1; i >= 0; i--) {
var label = labels[i]; var label = labels[i];
@ -974,6 +990,9 @@
plyr.progress.played.bar = _getElement(config.selectors.progress.played); plyr.progress.played.bar = _getElement(config.selectors.progress.played);
plyr.progress.played.text = plyr.progress.played.bar && plyr.progress.played.bar.getElementsByTagName('span')[0]; plyr.progress.played.text = plyr.progress.played.bar && plyr.progress.played.bar.getElementsByTagName('span')[0];
// Seek tooltip
plyr.progress.tooltip = plyr.progress.container && plyr.progress.container.querySelector('.' + config.classes.tooltip);
// Volume // Volume
plyr.volume = _getElement(config.selectors.buttons.volume); plyr.volume = _getElement(config.selectors.buttons.volume);
@ -1241,6 +1260,9 @@
// Bail if we're at 100% // Bail if we're at 100%
if (plyr.media.buffered === 1) { if (plyr.media.buffered === 1) {
window.clearInterval(plyr.timer.buffering); window.clearInterval(plyr.timer.buffering);
// Trigger event
_triggerEvent(plyr.media, 'canplaythrough');
} }
}, 200); }, 200);
@ -1274,6 +1296,7 @@
plyr.media.paused = false; plyr.media.paused = false;
plyr.media.seeking = false; plyr.media.seeking = false;
_triggerEvent(plyr.media, 'play'); _triggerEvent(plyr.media, 'play');
_triggerEvent(plyr.media, 'playing');
// Poll to get playback progress // Poll to get playback progress
plyr.timer.playing = window.setInterval(function() { plyr.timer.playing = window.setInterval(function() {
@ -1289,6 +1312,7 @@
case 2: case 2:
plyr.media.paused = true; plyr.media.paused = true;
_triggerEvent(plyr.media, 'pause'); _triggerEvent(plyr.media, 'pause');
break;
} }
} }
} }
@ -1339,6 +1363,7 @@
plyr.embed.addEvent('play', function() { plyr.embed.addEvent('play', function() {
plyr.media.paused = false; plyr.media.paused = false;
_triggerEvent(plyr.media, 'play'); _triggerEvent(plyr.media, 'play');
_triggerEvent(plyr.media, 'playing');
}); });
plyr.embed.addEvent('pause', function() { plyr.embed.addEvent('pause', function() {
@ -1355,6 +1380,11 @@
plyr.embed.addEvent('loadProgress', function(data) { plyr.embed.addEvent('loadProgress', function(data) {
plyr.media.buffered = data.percent; plyr.media.buffered = data.percent;
_triggerEvent(plyr.media, 'progress'); _triggerEvent(plyr.media, 'progress');
if(parseInt(data.percent) === 1) {
// Trigger event
_triggerEvent(plyr.media, 'canplaythrough');
}
}); });
plyr.embed.addEvent('finish', function() { plyr.embed.addEvent('finish', function() {
@ -1460,6 +1490,9 @@
// Display a cue, if there is one // Display a cue, if there is one
if (this.activeCues[0] && this.activeCues[0].hasOwnProperty('text')) { if (this.activeCues[0] && this.activeCues[0].hasOwnProperty('text')) {
plyr.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim()); plyr.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim());
// Force redraw
// var redraw = plyr.captionsContainer.offsetHeight;
} }
}); });
} }
@ -1646,7 +1679,8 @@
break; break;
case 'vimeo': case 'vimeo':
plyr.embed.api('seekTo', targetTime); // Round to nearest second for vimeo
plyr.embed.api('seekTo', targetTime.toFixed(0));
break; break;
} }
@ -1729,40 +1763,14 @@
// Set button state // Set button state
_toggleState(plyr.buttons.fullscreen, plyr.isFullscreen); _toggleState(plyr.buttons.fullscreen, plyr.isFullscreen);
// Toggle controls visibility based on mouse movement and location // Hide on entering full screen
var hoverTimer, isMouseOver = false;
// Show the player controls
function _showControls() {
// Set shown class
_toggleClass(plyr.container, config.classes.hover, true);
// Clear timer every movement
window.clearTimeout(hoverTimer);
// If the mouse is not over the controls, set a timeout to hide them
if (!isMouseOver) {
hoverTimer = window.setTimeout(function() {
_toggleClass(plyr.container, config.classes.hover, false);
}, 2000);
}
}
// Check mouse is over the controls
function _setMouseOver (event) {
isMouseOver = (event.type === 'mouseenter');
}
if (config.fullscreen.hideControls) { if (config.fullscreen.hideControls) {
// Hide on entering full screen //_toggleClass(plyr.controls, config.classes.hover, false);
_toggleClass(plyr.controls, config.classes.hover, false); _showControls(true);
// Keep an eye on the mouse location in relation to controls
_toggleHandler(plyr.controls, 'mouseenter mouseleave', _setMouseOver, plyr.isFullscreen);
// Show the controls on mouse move
_toggleHandler(plyr.container, 'mousemove', _showControls, plyr.isFullscreen);
} }
// Trigger an event
_triggerEvent(plyr.container, plyr.isFullscreen ? 'enterfullscreen' : 'exitfullscreen');
} }
// Bail from faux-fullscreen // Bail from faux-fullscreen
@ -1898,6 +1906,9 @@
// Add class hook // Add class hook
_toggleClass(plyr.container, config.classes.captions.active, plyr.captionsEnabled); _toggleClass(plyr.container, config.classes.captions.active, plyr.captionsEnabled);
// Trigger an event
_triggerEvent(plyr.container, plyr.captionsEnabled ? 'captionsenabled' : 'captionsdisabled');
} }
// Check if media is loading // Check if media is loading
@ -1905,10 +1916,10 @@
var loading = (event.type === 'waiting'); var loading = (event.type === 'waiting');
// Clear timer // Clear timer
clearTimeout(plyr.loadingTimer); clearTimeout(plyr.timers.loading);
// Timer to prevent flicker when seeking // Timer to prevent flicker when seeking
plyr.loadingTimer = setTimeout(function() { plyr.timers.loading = setTimeout(function() {
_toggleClass(plyr.container, config.classes.loading, loading); _toggleClass(plyr.container, config.classes.loading, loading);
}, (loading ? 250 : 0)); }, (loading ? 250 : 0));
} }
@ -2015,6 +2026,9 @@
if (plyr.duration) { if (plyr.duration) {
_updateTimeDisplay(duration, plyr.duration); _updateTimeDisplay(duration, plyr.duration);
} }
// Update the tooltip (if visible)
_updateSeekTooltip();
} }
// Handle time change event // Handle time change event
@ -2031,6 +2045,73 @@
_updateProgress(event); _updateProgress(event);
} }
// Update hover tooltip for seeking
function _updateSeekTooltip(event) {
// Bail if setting not true
if (!config.tooltips.seek || plyr.browser.touch) {
return;
}
// Calculate percentage
var clientRect = plyr.progress.container.getBoundingClientRect(),
percent = 0,
visible = config.classes.tooltip + '--visible';
// Determine percentage, if already visible
if (!event) {
if(_hasClass(plyr.progress.tooltip, visible)) {
percent = plyr.progress.tooltip.style.left.replace('%', '');
}
else {
return;
}
}
else {
percent = ((100 / clientRect.width) * (event.pageX - clientRect.left));
}
// Set bounds
if (percent < 0) {
percent = 0;
}
else if (percent > 100) {
percent = 100;
}
// Display the time a click would seek to
_updateTimeDisplay(((plyr.media.duration / 100) * percent), plyr.progress.tooltip);
// Set position
plyr.progress.tooltip.style.left = percent + "%";
// Show/hide the tooltip
// If the event is a moues in/out and percentage is inside bounds
if(_inArray(['mouseenter', 'mouseleave'], event.type)) {
_toggleClass(plyr.progress.tooltip, visible, (event.type === 'mouseenter'));
}
}
// Show the player controls in fullscreen mode
function _showControls(force) {
// We're only worried about fullscreen
if (!plyr.isFullscreen) {
return;
}
// Set shown class
_toggleClass(plyr.container, config.classes.hover, true);
// Clear timer every movement
window.clearTimeout(plyr.timers.hover);
// If the mouse is not over the controls, set a timeout to hide them
plyr.timers.hover = window.setTimeout(function() {
if (!plyr.controls.mouseover || (force === true)) {
_toggleClass(plyr.container, config.classes.hover, false);
}
}, 2000);
}
// Add common function to retrieve media source // Add common function to retrieve media source
function _source(source) { function _source(source) {
// If not null or undefined, parse it // If not null or undefined, parse it
@ -2170,11 +2251,11 @@
// Load HTML5 sources // Load HTML5 sources
plyr.media.load(); plyr.media.load();
// Display duration if available
_displayDuration();
// Setup interface // Setup interface
_setupInterface(); _setupInterface();
// Display duration if available
_displayDuration();
} }
// Play if autoplay attribute is present // Play if autoplay attribute is present
@ -2214,8 +2295,8 @@
} }
// Determine which buttons // Determine which buttons
var trigger = plyr.buttons[play ? "play" : "pause"], var trigger = plyr.buttons[play ? 'play' : 'pause'],
target = plyr.buttons[play ? "pause" : "play"]; target = plyr.buttons[play ? 'pause' : 'play'];
// Setup focus and tab focus // Setup focus and tab focus
if(target) { if(target) {
@ -2266,33 +2347,33 @@
} }
// Play // Play
_proxyHandler(plyr.buttons.play, 'click', config.handlers.play, _togglePlay); _proxyListener(plyr.buttons.play, 'click', config.listeners.play, _togglePlay);
// Pause // Pause
_proxyHandler(plyr.buttons.pause, 'click', config.handlers.pause, _togglePlay); _proxyListener(plyr.buttons.pause, 'click', config.listeners.pause, _togglePlay);
// Restart // Restart
_proxyHandler(plyr.buttons.restart, 'click', config.handlers.restart, _seek); _proxyListener(plyr.buttons.restart, 'click', config.listeners.restart, _seek);
// Rewind // Rewind
_proxyHandler(plyr.buttons.rewind, 'click', config.handlers.rewind, _rewind); _proxyListener(plyr.buttons.rewind, 'click', config.listeners.rewind, _rewind);
// Fast forward // Fast forward
_proxyHandler(plyr.buttons.forward, 'click', config.handlers.forward, _forward); _proxyListener(plyr.buttons.forward, 'click', config.listeners.forward, _forward);
// Seek // Seek
_proxyHandler(plyr.buttons.seek, inputEvent, config.handlers.seek, _seek); _proxyListener(plyr.buttons.seek, inputEvent, config.listeners.seek, _seek);
// Set volume // Set volume
_proxyHandler(plyr.volume, inputEvent, config.handlers.volume, function() { _proxyListener(plyr.volume, inputEvent, config.listeners.volume, function() {
_setVolume(plyr.volume.value); _setVolume(plyr.volume.value);
}); });
// Mute // Mute
_proxyHandler(plyr.buttons.mute, 'click', config.handlers.mute, _toggleMute); _proxyListener(plyr.buttons.mute, 'click', config.listeners.mute, _toggleMute);
// Fullscreen // Fullscreen
_proxyHandler(plyr.buttons.fullscreen, 'click', config.handlers.fullscreen, _toggleFullscreen); _proxyListener(plyr.buttons.fullscreen, 'click', config.listeners.fullscreen, _toggleFullscreen);
// Handle user exiting fullscreen by escaping etc // Handle user exiting fullscreen by escaping etc
if (fullscreen.supportsFullScreen) { if (fullscreen.supportsFullScreen) {
@ -2302,19 +2383,16 @@
// Captions // Captions
_on(plyr.buttons.captions, 'click', _toggleCaptions); _on(plyr.buttons.captions, 'click', _toggleCaptions);
// Click video // Seek tooltip
if (plyr.type === 'video' && config.click) { _on(plyr.progress.container, 'mouseenter mouseleave mousemove', _updateSeekTooltip);
_on(plyr.videoContainer, 'click', function() {
if (plyr.media.paused) { // Toggle controls visibility based on mouse movement and location
_play(); var hoverTimer, isMouseOver = false;
}
else if (plyr.media.ended) { if (config.fullscreen.hideControls) {
_seek(); // Keep an eye on the mouse location in relation to controls
_play(); _on(plyr.controls, 'mouseenter mouseleave', function() {
} plyr.controls.mouseover = (event.type === 'mouseenter');
else {
_pause();
}
}); });
} }
} }
@ -2328,7 +2406,7 @@
_on(plyr.media, 'timeupdate', _seekManualCaptions); _on(plyr.media, 'timeupdate', _seekManualCaptions);
// Display duration // Display duration
_on(plyr.media, 'loadedmetadata', _displayDuration); _on(plyr.media, 'durationchange loadedmetadata', _displayDuration);
// Handle the media finishing // Handle the media finishing
_on(plyr.media, 'ended', function() { _on(plyr.media, 'ended', function() {
@ -2352,6 +2430,33 @@
// Loading // Loading
_on(plyr.media, 'waiting canplay seeked', _checkLoading); _on(plyr.media, 'waiting canplay seeked', _checkLoading);
// Click video
if (config.click) {
_on(plyr.media, 'click', function() {
if (plyr.media.paused) {
_play();
}
else if (plyr.media.ended) {
_seek();
_play();
}
else {
_pause();
}
});
}
// Listen for mouse move to show controls
if (config.fullscreen.hideControls) {
// Show the controls on mouse move
_on(plyr.media, 'mousemove', _showControls);
}
// Proxy events to container
_on(plyr.media, config.events.join(' '), function(event) {
_triggerEvent(plyr.container, event.type);
});
} }
// Destroy an instance // Destroy an instance
@ -2475,7 +2580,7 @@
function _setupInterface() { function _setupInterface() {
// Don't setup interface if no support // Don't setup interface if no support
if (!plyr.supported.full) { if (!plyr.supported.full) {
_log("No full support for this media type (" + plyr.type + ")", true); _log('No full support for this media type (' + plyr.type + ')', true);
// Remove controls // Remove controls
_remove(_getElement(config.selectors.controls.wrapper)); _remove(_getElement(config.selectors.controls.wrapper));
@ -2642,9 +2747,7 @@
element.plyr = (Object.keys(instance).length ? instance : false); element.plyr = (Object.keys(instance).length ? instance : false);
// Callback // Callback
if (typeof config.onSetup === 'function') { _triggerEvent(element, 'setup', { plyr: element.plyr });
config.onSetup.apply(element.plyr);
}
} }
// Add to return array even if it's already setup // Add to return array even if it's already setup
@ -2656,3 +2759,20 @@
return api; return api;
})); }));
// Custom event polyfill
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
(function () {
function CustomEvent (event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
if(!('CustomEvent' in window)) {
window.CustomEvent = CustomEvent;
}
})();

View File

@ -7,78 +7,78 @@
// ------------------------------- // -------------------------------
// Colors // Colors
@blue: #3498DB; @plyr-blue: #3498DB;
@gray-dark: #343F4A; @plyr-gray-dark: #343F4A;
@gray: #565D64; @plyr-gray: #565D64;
@gray-light: #6B7D86; @plyr-gray-light: #6B7D86;
@gray-lighter: #CBD0D3; @plyr-gray-lighter: #CBD0D3;
@off-white: #D6DADD; @plyr-off-white: #D6DADD;
// Font sizes // Font sizes
@font-size-small: 14px; @plyr-font-size-small: 14px;
@font-size-base: 16px; @plyr-font-size-base: 16px;
// Captions // Captions
@font-size-captions-base: ceil(@font-size-base * 1.25); @plyr-font-size-captions-base: ceil(@plyr-font-size-base * 1.25);
@font-size-captions-medium: ceil(@font-size-base * 1.5); @plyr-font-size-captions-medium: ceil(@plyr-font-size-base * 1.5);
@font-size-captions-large: (@font-size-base * 2); @plyr-font-size-captions-large: (@plyr-font-size-base * 2);
// Controls // Controls
@control-spacing: 10px; @plyr-control-spacing: 10px;
@controls-bg: #fff; @plyr-controls-bg: #fff;
@control-bg-hover: @blue; @plyr-control-bg-hover: @plyr-blue;
.contrast-control-color(@controls-bg); .contrast-control-color(@plyr-controls-bg);
.contrast-control-color-hover(@control-bg-hover); .contrast-control-color-hover(@plyr-control-bg-hover);
// Tooltips // Tooltips
@tooltip-bg: @controls-bg; @plyr-tooltip-bg: @plyr-controls-bg;
@tooltip-border-color: fade(@gray-dark, 10%); @plyr-tooltip-border-color: fade(darken(@plyr-controls-bg, 5%), 10%);
@tooltip-border-width: 1px; @plyr-tooltip-border-width: 1px;
@tooltip-shadow: 0 0 5px @tooltip-border-color, 0 0 0 @tooltip-border-width @tooltip-border-color; @plyr-tooltip-shadow: 0 0 5px @plyr-tooltip-border-color, 0 0 0 @plyr-tooltip-border-width @plyr-tooltip-border-color;
@tooltip-color: @control-color; @plyr-tooltip-color: @plyr-control-color;
@tooltip-padding: @control-spacing; @plyr-tooltip-padding: @plyr-control-spacing;
@tooltip-arrow-size: 6px; @plyr-tooltip-arrow-size: 6px;
@tooltip-radius: 3px; @plyr-tooltip-radius: 3px;
// Progress // Progress
@progress-bg: fade(@gray, 20%); @plyr-progress-bg: fade(@plyr-gray, 20%);
@progress-playing-bg: @blue; @plyr-progress-playing-bg: @plyr-blue;
@progress-buffered-bg: fade(@gray, 25%); @plyr-progress-buffered-bg: fade(@plyr-gray, 25%);
@progress-loading-size: 40px; @plyr-progress-loading-size: 40px;
@progress-loading-bg: rgba(0,0,0, .15); @plyr-progress-loading-bg: fade(#000, 15%);
// Volume // Volume
@volume-track-height: 6px; @plyr-volume-track-height: 6px;
@volume-track-bg: darken(@controls-bg, 10%); @plyr-volume-track-bg: darken(@plyr-controls-bg, 10%);
@volume-thumb-height: (@volume-track-height * 2); @plyr-volume-thumb-height: (@plyr-volume-track-height * 2);
@volume-thumb-width: (@volume-track-height * 2); @plyr-volume-thumb-width: (@plyr-volume-track-height * 2);
@volume-thumb-bg: @control-color; @plyr-volume-thumb-bg: @plyr-control-color;
@volume-thumb-bg-focus: @control-bg-hover; @plyr-volume-thumb-bg-focus: @plyr-control-bg-hover;
// Breakpoints // Breakpoints
@bp-control-split: 560px; // When controls split into left/right @plyr-bp-control-split: 560px; // When controls split into left/right
@bp-captions-large: 768px; // When captions jump to the larger font size @plyr-bp-captions-large: 768px; // When captions jump to the larger font size
// Animation // Animation
// --------------------------------------- // ---------------------------------------
@keyframes progress { @keyframes plyr-progress {
to { background-position: @progress-loading-size 0; } to { background-position: @plyr-progress-loading-size 0; }
} }
// Mixins // Mixins
// ------------------------------- // -------------------------------
// Contrast // Contrast
.contrast-control-color(@color: "") when (lightness(@color) >= 65%) { .contrast-control-color(@plyr-color: "") when (lightness(@plyr-color) >= 65%) {
@control-color: @gray-light; @plyr-control-color: @plyr-gray-light;
} }
.contrast-control-color(@color: "") when (lightness(@color) < 65%) { .contrast-control-color(@plyr-color: "") when (lightness(@plyr-color) < 65%) {
@control-color: @gray-lighter; @plyr-control-color: @plyr-gray-lighter;
} }
.contrast-control-color-hover(@color: "") when (lightness(@color) >= 65%) { .contrast-control-color-hover(@plyr-color: "") when (lightness(@plyr-color) >= 65%) {
@control-color-hover: @gray; @plyr-control-color-hover: @plyr-gray;
} }
.contrast-control-color-hover(@color: "") when (lightness(@color) < 65%) { .contrast-control-color-hover(@plyr-color: "") when (lightness(@plyr-color) < 65%) {
@control-color-hover: #fff; @plyr-control-color-hover: #fff;
} }
// Font smoothing // Font smoothing
@ -91,40 +91,30 @@
-webkit-font-smoothing: subpixel-antialiased; -webkit-font-smoothing: subpixel-antialiased;
} }
// Contain floats: nicolasgallagher.com/micro-clearfix-hack/
.clearfix() {
zoom: 1;
&:before,
&:after { content: ""; display: table; }
&:after { clear: both; }
}
// Tab focus styles
.tab-focus() {
outline: 1px dotted fade(@gray-dark, 80%);
outline-offset: 3px;
}
// <input type="range"> styling // <input type="range"> styling
.volume-thumb() { .volume-thumb() {
height: @volume-thumb-height; height: @plyr-volume-thumb-height;
width: @volume-thumb-width; width: @plyr-volume-thumb-width;
background: @volume-thumb-bg; background: @plyr-volume-thumb-bg;
border: 0; border: 0;
border-radius: 100%; border-radius: 100%;
transition: background .3s ease; transition: background .3s ease;
cursor: ew-resize; cursor: ew-resize;
} }
.volume-track() { .volume-track() {
height: @volume-track-height; height: @plyr-volume-track-height;
background: @volume-track-bg; background: @plyr-volume-track-bg;
border: 0; border: 0;
border-radius: (@volume-track-height / 2); border-radius: (@plyr-volume-track-height / 2);
} }
.seek-thumb() { .seek-thumb() {
background: transparent; background: transparent;
border: 0; border: 0;
width: (@control-spacing * 4); width: 1px;
height: @control-spacing; height: @plyr-control-spacing;
}
.seek-thumb-touch() {
width: (@plyr-control-spacing * 4);
transform: translateX(-50%); transform: translateX(-50%);
} }
.seek-track() { .seek-track() {
@ -191,6 +181,7 @@
height: 100%; height: 100%;
border: 0; border: 0;
user-select: none; user-select: none;
pointer-events: none; // To allow mouse events to be captured
} }
// Vimeo hack // Vimeo hack
@ -208,49 +199,55 @@
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
padding: (@control-spacing * 2) (@control-spacing * 2) (@control-spacing * 3); padding: (@plyr-control-spacing * 2) (@plyr-control-spacing * 2) (@plyr-control-spacing * 3);
color: #fff; color: #fff;
font-size: @font-size-captions-base; font-size: @plyr-font-size-captions-base;
text-align: center; text-align: center;
.font-smoothing(); .font-smoothing();
span { span {
border-radius: 2px; border-radius: 2px;
padding: 3px 10px; padding: 3px 10px;
background: rgba(0,0,0, .9); background: fade(#000, 90%);
} }
span:empty { span:empty {
display: none; display: none;
} }
@media (min-width: @bp-captions-large) { @media (min-width: @plyr-bp-captions-large) {
font-size: @font-size-captions-medium; font-size: @plyr-font-size-captions-medium;
} }
} }
&--captions-active &__captions { &--captions-active &__captions {
display: block; display: block;
} }
&--fullscreen-active &__captions { &--fullscreen-active &__captions {
font-size: @font-size-captions-large; font-size: @plyr-font-size-captions-large;
} }
// Playback controls // Playback controls
&__controls { &__controls {
.clearfix();
.font-smoothing(); .font-smoothing();
position: relative; position: relative;
padding: @control-spacing; padding: @plyr-control-spacing;
background: @controls-bg; background: @plyr-controls-bg;
line-height: 1; line-height: 1;
text-align: center; text-align: center;
box-shadow: 0 1px 1px fade(@gray-dark, 20%); box-shadow: 0 1px 1px fade(@plyr-gray-dark, 20%);
// Clear floats
&::after {
content: '';
display: table;
clear: both;
}
// Layout // Layout
&--right { &--right {
display: block; display: block;
margin: @control-spacing auto 0; margin: @plyr-control-spacing auto 0;
} }
@media (min-width: @bp-control-split) { @media (min-width: @plyr-bp-control-split) {
&--left { &--left {
float: left; float: left;
} }
@ -265,13 +262,13 @@
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
margin: 0 2px; margin: 0 2px;
padding: (@control-spacing / 2) @control-spacing; padding: (@plyr-control-spacing / 2) @plyr-control-spacing;
overflow: hidden; overflow: hidden;
border: 0; border: 0;
background: transparent; background: transparent;
border-radius: 3px; border-radius: 3px;
cursor: pointer; cursor: pointer;
color: @control-color; color: @plyr-control-color;
transition: background .3s ease, color .3s ease, opacity .3s ease; transition: background .3s ease, color .3s ease, opacity .3s ease;
svg { svg {
@ -285,8 +282,8 @@
// Hover and tab focus // Hover and tab focus
&.tab-focus:focus, &.tab-focus:focus,
&:hover { &:hover {
background: @control-bg-hover; background: @plyr-control-bg-hover;
color: @control-color-hover; color: @plyr-control-color-hover;
} }
// Default focus // Default focus
&:focus { &:focus {
@ -305,48 +302,49 @@
.plyr__time { .plyr__time {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
margin-left: @control-spacing; margin-left: @plyr-control-spacing;
color: @control-color; color: @plyr-control-color;
font-weight: 600; font-weight: 600;
font-size: @font-size-small; font-size: @plyr-font-size-small;
} }
// Media duration hidden on small screens // Media duration hidden on small screens
.plyr__time + .plyr__time { .plyr__time + .plyr__time {
display: none; display: none;
@media (min-width: @bp-control-split) { @media (min-width: @plyr-bp-control-split) {
display: inline-block; display: inline-block;
} }
// Add a slash in before // Add a slash in before
&::before { &::before {
content: '\2044'; content: '\2044';
margin-right: @control-spacing; margin-right: @plyr-control-spacing;
} }
} }
} }
// Tooltips // Tooltips
&__tooltip { &__tooltip {
visibility: hidden;
position: absolute; position: absolute;
z-index: 2; z-index: 2;
bottom: 100%; bottom: 100%;
margin-bottom: @tooltip-padding; margin-bottom: @plyr-tooltip-padding;
padding: @tooltip-padding (@tooltip-padding * 1.5); padding: @plyr-tooltip-padding (@plyr-tooltip-padding * 1.5);
opacity: 0; opacity: 0;
background: @tooltip-bg; background: @plyr-tooltip-bg;
box-shadow: @tooltip-shadow; box-shadow: @plyr-tooltip-shadow;
border-radius: @tooltip-radius; border-radius: @plyr-tooltip-radius;
color: @tooltip-color; color: @plyr-tooltip-color;
font-size: @font-size-small; font-size: @plyr-font-size-small;
line-height: 1.5; line-height: 1.5;
font-weight: 600; font-weight: 600;
transform: translate(-50%, (@tooltip-padding * 3)) scale(.8); transform: translate(-50%, 10px) scale(.8);
transform-origin: 50% 100%; transform-origin: 50% 100%;
transition: transform .2s .1s ease, opacity .2s .1s ease; transition: transform .2s .1s ease, opacity .2s .1s ease, visibility .3s ease;
// Arrows // Arrows
&::after, &::after,
@ -361,24 +359,26 @@
} }
// The border triangle // The border triangle
&::after { &::after {
@border-arrow-size: (@tooltip-arrow-size + (@tooltip-border-width * 1)); @plyr-border-arrow-size: (@plyr-tooltip-arrow-size + (@plyr-tooltip-border-width * 1));
bottom: -(@border-arrow-size + @tooltip-border-width); bottom: -(@plyr-border-arrow-size + @plyr-tooltip-border-width);
border-right: @border-arrow-size solid transparent; border-right: @plyr-border-arrow-size solid transparent;
border-top: @border-arrow-size solid @tooltip-border-color; border-top: @plyr-border-arrow-size solid @plyr-tooltip-border-color;
border-left: @border-arrow-size solid transparent; border-left: @plyr-border-arrow-size solid transparent;
z-index: 1; z-index: 1;
} }
// The background triangle // The background triangle
&::before { &::before {
bottom: -@tooltip-arrow-size; bottom: -@plyr-tooltip-arrow-size;
border-right: @tooltip-arrow-size solid transparent; border-right: @plyr-tooltip-arrow-size solid transparent;
border-top: @tooltip-arrow-size solid @tooltip-bg; border-top: @plyr-tooltip-arrow-size solid @plyr-tooltip-bg;
border-left: @tooltip-arrow-size solid transparent; border-left: @plyr-tooltip-arrow-size solid transparent;
z-index: 2; z-index: 2;
} }
} }
button:hover .plyr__tooltip, button:hover .plyr__tooltip,
button.tab-focus:focus .plyr__tooltip { button.tab-focus:focus .plyr__tooltip,
&__tooltip--visible {
visibility: visible;
opacity: 1; opacity: 1;
transform: translate(-50%, 0) scale(1); transform: translate(-50%, 0) scale(1);
} }
@ -388,7 +388,8 @@
// Common range styles // Common range styles
input[type='range'].tab-focus:focus { input[type='range'].tab-focus:focus {
.tab-focus(); outline: 1px dotted fade(@plyr-gray-dark, 80%);
outline-offset: 3px;
} }
// Playback progress // Playback progress
@ -399,8 +400,8 @@
left: 0; left: 0;
right: 0; right: 0;
width: 100%; width: 100%;
height: @control-spacing; height: @plyr-control-spacing;
background: @progress-bg; background: @plyr-progress-bg;
&--buffer[value], &--buffer[value],
&--played[value], &--played[value],
@ -409,7 +410,7 @@
left: 0; left: 0;
top: 0; top: 0;
width: 100%; width: 100%;
height: @control-spacing; height: @plyr-control-spacing;
margin: 0; margin: 0;
padding: 0; padding: 0;
vertical-align: top; vertical-align: top;
@ -423,22 +424,25 @@
&--played[value] { &--played[value] {
&::-webkit-progress-bar { &::-webkit-progress-bar {
background: transparent; background: transparent;
transition: width .2s ease;
} }
// Inherit from currentColor; // Inherit from currentColor;
&::-webkit-progress-value { &::-webkit-progress-value {
background: currentColor; background: currentColor;
transition: width .2s ease;
} }
&::-moz-progress-bar { &::-moz-progress-bar {
background: currentColor; background: currentColor;
transition: width .2s ease;
} }
} }
&--played[value] { &--played[value] {
z-index: 2; z-index: 2;
color: @progress-playing-bg; color: @plyr-progress-playing-bg;
} }
&--buffer[value] { &--buffer[value] {
color: @progress-buffered-bg; color: @plyr-progress-buffered-bg;
} }
// Seek control // Seek control
@ -487,21 +491,41 @@
border: 0; border: 0;
} }
} }
// Seek tooltip to show time
.plyr__tooltip {
left: 0;
}
}
// Touch seek wider handle
&--is-touch &--seek[type='range'] {
&::-webkit-slider-thumb {
.seek-thumb-touch();
}
// Mozilla
&::-moz-range-thumb {
.seek-thumb-touch();
}
// Microsoft
&::-ms-thumb {
.seek-thumb-touch();
}
} }
// Loading state // Loading state
&--loading .plyr__progress--buffer { &--loading .plyr__progress--buffer {
animation: progress 1s linear infinite; animation: plyr-progress 1s linear infinite;
background-size: @progress-loading-size @progress-loading-size; background-size: @plyr-progress-loading-size @plyr-progress-loading-size;
background-repeat: repeat-x; background-repeat: repeat-x;
background-color: @progress-buffered-bg; background-color: @plyr-progress-buffered-bg;
background-image: linear-gradient( background-image: linear-gradient(
-45deg, -45deg,
@progress-loading-bg 25%, @plyr-progress-loading-bg 25%,
transparent 25%, transparent 25%,
transparent 50%, transparent 50%,
@progress-loading-bg 50%, @plyr-progress-loading-bg 50%,
@progress-loading-bg 75%, @plyr-progress-loading-bg 75%,
transparent 75%, transparent 75%,
transparent); transparent);
color: transparent; color: transparent;
@ -525,7 +549,7 @@
-webkit-appearance: none; -webkit-appearance: none;
-moz-appearance: none; -moz-appearance: none;
width: 100px; width: 100px;
margin: 0 @control-spacing 0 0; margin: 0 @plyr-control-spacing 0 0;
padding: 0; padding: 0;
cursor: pointer; cursor: pointer;
background: transparent; background: transparent;
@ -537,7 +561,7 @@
} }
&::-webkit-slider-thumb { &::-webkit-slider-thumb {
-webkit-appearance: none; -webkit-appearance: none;
margin-top: -((@volume-thumb-height - @volume-track-height) / 2); margin-top: -((@plyr-volume-thumb-height - @plyr-volume-track-height) / 2);
.volume-thumb(); .volume-thumb();
} }
@ -551,10 +575,10 @@
// Microsoft // Microsoft
&::-ms-track { &::-ms-track {
height: @volume-track-height; height: @plyr-volume-track-height;
background: transparent; background: transparent;
border-color: transparent; border-color: transparent;
border-width: ((@volume-thumb-height - @volume-track-height) / 2) 0; border-width: ((@plyr-volume-thumb-height - @plyr-volume-track-height) / 2) 0;
color: transparent; color: transparent;
} }
&::-ms-fill-lower, &::-ms-fill-lower,
@ -569,13 +593,13 @@
outline: 0; outline: 0;
&::-webkit-slider-thumb { &::-webkit-slider-thumb {
background: @volume-thumb-bg-focus; background: @plyr-volume-thumb-bg-focus;
} }
&::-moz-range-thumb { &::-moz-range-thumb {
background: @volume-thumb-bg-focus; background: @plyr-volume-thumb-bg-focus;
} }
&::-ms-thumb { &::-ms-thumb {
background: @volume-thumb-bg-focus; background: @plyr-volume-thumb-bg-focus;
} }
} }
} }
@ -596,16 +620,16 @@
// Audio specific styles // Audio specific styles
// Position the progress within the container // Position the progress within the container
&--audio .plyr__controls { &--audio .plyr__controls {
padding-top: (@control-spacing * 2); padding-top: (@plyr-control-spacing * 2);
} }
&--audio .plyr__progress { &--audio .plyr__progress {
bottom: auto; bottom: auto;
top: 0; top: 0;
background: @off-white; background: @plyr-off-white;
} }
// Full screen mode // Full screen mode
&--fullscreen, &.plyr--fullscreen,
&--fullscreen-active { &--fullscreen-active {
position: fixed; position: fixed;
top: 0; top: 0;
@ -633,28 +657,29 @@
} }
// Hide controls when playing in full screen // Hide controls when playing in full screen
&--fullscreen--hide-controls&--fullscreen-active&--playing { &--fullscreen-active.plyr--fullscreen--hide-controls.plyr--playing,
&.plyr--fullscreen.plyr--fullscreen--hide-controls.plyr--playing {
.plyr__controls { .plyr__controls {
transform: translateY(100%) translateY(@control-spacing / 2); transform: translateY(100%) translateY(@plyr-control-spacing / 2);
transition: transform .3s .2s ease; transition: transform .3s .2s ease;
} }
.plyr__captions {
bottom: (@plyr-control-spacing / 2);
transition: bottom .3s .2s ease;
}
&.plyr--hover .plyr__controls { &.plyr--hover .plyr__controls {
transform: translateY(0); transform: translateY(0);
} }
.plyr__captions {
bottom: (@control-spacing / 2);
transition: bottom .3s .2s ease;
}
} }
// Captions // Captions
&--fullscreen .plyr__captions, &.plyr--fullscreen .plyr__captions,
&--fullscreen-active .plyr__captions, &--fullscreen-active .plyr__captions,
&--fullscreen--hide-controls&--fullscreen-active&--playing&--hover &__captions { &--fullscreen--hide-controls.plyr--fullscreen-active.plyr--playing.plyr--hover .plyr__captions {
top: auto; top: auto;
bottom: 90px; bottom: 90px;
@media (min-width: @bp-control-split) { @media (min-width: @plyr-bp-control-split) {
bottom: 60px; bottom: 60px;
} }
} }

View File

@ -7,76 +7,76 @@
// ------------------------------- // -------------------------------
// Colors // Colors
$blue: #3498DB !default; $plyr-blue: #3498DB !default;
$gray-dark: #343F4A !default; $plyr-gray-dark: #343F4A !default;
$gray: #565D64 !default; $plyr-gray: #565D64 !default;
$gray-light: #6B7D86 !default; $plyr-gray-light: #6B7D86 !default;
$gray-lighter: #CBD0D3 !default; $plyr-gray-lighter: #CBD0D3 !default;
$off-white: #D6DADD !default; $plyr-off-white: #D6DADD !default;
// Font sizes // Font sizes
$font-size-small: 14px !default; $plyr-font-size-small: 14px !default;
$font-size-base: 16px !default; $plyr-font-size-base: 16px !default;
// Captions // Captions
$font-size-captions-base: ceil($font-size-base * 1.25) !default; $plyr-font-size-captions-base: ceil($plyr-font-size-base * 1.25) !default;
$font-size-captions-medium: ceil($font-size-base * 1.5) !default; $plyr-font-size-captions-medium: ceil($plyr-font-size-base * 1.5) !default;
$font-size-captions-large: ($font-size-base * 2) !default; $plyr-font-size-captions-large: ($plyr-font-size-base * 2) !default;
// Controls // Controls
$control-spacing: 10px !default; $plyr-control-spacing: 10px !default;
$controls-bg: #fff !default; $plyr-controls-bg: #fff !default;
$control-bg-hover: $blue !default; $plyr-control-bg-hover: $plyr-blue !default;
$control-color: null !default; $plyr-control-color: null !default;
$control-color-hover: null !default; $plyr-control-color-hover: null !default;
// Contrast // Contrast
@if lightness($controls-bg) >= 65% { @if lightness($plyr-controls-bg) >= 65% {
$control-color: $gray-light; $plyr-control-color: $plyr-gray-light;
} }
@else { @else {
$control-color: $gray-lighter; $plyr-control-color: $plyr-gray-lighter;
} }
@if lightness($control-bg-hover) >= 65% { @if lightness($plyr-control-bg-hover) >= 65% {
$control-color-hover: $gray; $plyr-control-color-hover: $plyr-gray;
} }
@else { @else {
$control-color-hover: #fff; $plyr-control-color-hover: #fff;
} }
// Tooltips // Tooltips
$tooltip-bg: $controls-bg !default; $plyr-tooltip-bg: $plyr-controls-bg !default;
$tooltip-border-color: transparentize(@gray-dark, .1) !default; $plyr-tooltip-border-color: transparentize($plyr-gray-dark, .1) !default;
$tooltip-border-width: 1px; $plyr-tooltip-border-width: 1px;
$tooltip-shadow: 0 0 5px $tooltip-border-color, 0 0 0 $tooltip-border-width $tooltip-border-color; $plyr-tooltip-shadow: 0 0 5px $plyr-tooltip-border-color, 0 0 0 $plyr-tooltip-border-width $plyr-tooltip-border-color;
$tooltip-color: $control-color !default; $plyr-tooltip-color: $plyr-control-color !default;
$tooltip-padding: $control-spacing !default; $plyr-tooltip-padding: $plyr-control-spacing !default;
$tooltip-arrow-size: 6px !default; $plyr-tooltip-arrow-size: 6px !default;
$tooltip-radius: 3px !default; $plyr-tooltip-radius: 3px !default;
// Progress // Progress
$progress-bg: transparentize($gray, .2) !default; $plyr-progress-bg: transparentize($plyr-gray, .2) !default;
$progress-playing-bg: $blue !default; $plyr-progress-playing-bg: $plyr-blue !default;
$progress-buffered-bg: transparentize($gray, .25) !default; $plyr-progress-buffered-bg: transparentize($plyr-gray, .25) !default;
$progress-loading-size: 40px !default; $plyr-progress-loading-size: 40px !default;
$progress-loading-bg: rgba(0,0,0, .15) !default; $plyr-progress-loading-bg: transparentize(#000, .15) !default;
// Volume // Volume
$volume-track-height: 6px !default; $plyr-volume-track-height: 6px !default;
$volume-track-bg: darken($controls-bg, 10%) !default; $plyr-volume-track-bg: darken($plyr-controls-bg, 10%) !default;
$volume-thumb-height: ($volume-track-height * 2) !default; $plyr-volume-thumb-height: ($plyr-volume-track-height * 2) !default;
$volume-thumb-width: ($volume-track-height * 2) !default; $plyr-volume-thumb-width: ($plyr-volume-track-height * 2) !default;
$volume-thumb-bg: $control-color !default; $plyr-volume-thumb-bg: $plyr-control-color !default;
$volume-thumb-bg-focus: $control-bg-hover !default; $plyr-volume-thumb-bg-focus: $plyr-control-bg-hover !default;
// Breakpoints // Breakpoints
$bp-control-split: 560px !default; // When controls split into left/right $plyr-bp-control-split: 560px !default; // When controls split into left/right
$bp-captions-large: 768px !default; // When captions jump to the larger font size $plyr-bp-captions-large: 768px !default; // When captions jump to the larger font size
// Animation // Animation
// --------------------------------------- // ---------------------------------------
@keyframes progress { @keyframes plyr-progress {
to { background-position: $progress-loading-size 0; } to { background-position: $plyr-progress-loading-size 0; }
} }
// Font smoothing // Font smoothing
@ -92,41 +92,30 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
} }
} }
// Contain floats: nicolasgallagher.com/micro-clearfix-hack/
@mixin clearfix()
{
zoom: 1;
&:before,
&:after { content: ''; display: table; }
&:after { clear: both; }
}
// Tab focus styles
@mixin tab-focus() {
outline: thin dotted transparentize($gray-dark, .8);
outline-offset: 3px;
}
// <input type="range"> styling // <input type="range"> styling
@mixin volume-thumb() { @mixin volume-thumb() {
height: $volume-thumb-height; height: $plyr-volume-thumb-height;
width: $volume-thumb-width; width: $plyr-volume-thumb-width;
background: $volume-thumb-bg; background: $plyr-volume-thumb-bg;
border: 0; border: 0;
border-radius: 100%; border-radius: 100%;
transition: background .3s ease; transition: background .3s ease;
cursor: ew-resize; cursor: ew-resize;
} }
@mixin volume-track() { @mixin volume-track() {
height: $volume-track-height; height: $plyr-volume-track-height;
background: $volume-track-bg; background: $plyr-volume-track-bg;
border: 0; border: 0;
border-radius: ($volume-track-height / 2); border-radius: ($plyr-volume-track-height / 2);
} }
@mixin seek-thumb() { @mixin seek-thumb() {
background: transparent; background: transparent;
border: 0; border: 0;
width: ($control-spacing * 4); width: 1px;
height: $control-spacing; height: $plyr-control-spacing;
}
@mixin seek-thumb-touch() {
width: ($plyr-control-spacing * 4);
transform: translateX(-50%); transform: translateX(-50%);
} }
@mixin seek-track() { @mixin seek-track() {
@ -192,6 +181,8 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
width: 100%; width: 100%;
height: 100%; height: 100%;
border: 0; border: 0;
user-select: none;
pointer-events: none; // To allow mouse events to be captured
} }
// Vimeo hack // Vimeo hack
@ -209,49 +200,55 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
padding: ($control-spacing * 2) ($control-spacing * 2) ($control-spacing * 3); padding: ($plyr-control-spacing * 2) ($plyr-control-spacing * 2) ($plyr-control-spacing * 3);
color: #fff; color: #fff;
font-size: $font-size-captions-base; font-size: $plyr-font-size-captions-base;
text-align: center; text-align: center;
@include font-smoothing(); @include font-smoothing();
span { span {
border-radius: 2px; border-radius: 2px;
padding: 3px 10px; padding: 3px 10px;
background: rgba(0,0,0, .9); background: transparentize(#000, .9);
} }
span:empty { span:empty {
display: none; display: none;
} }
@media (min-width: $bp-captions-large) { @media (min-width: $plyr-bp-captions-large) {
font-size: $font-size-captions-medium; font-size: $plyr-font-size-captions-medium;
} }
} }
&--captions-active &__captions { &--captions-active &__captions {
display: block; display: block;
} }
&--fullscreen-active &__captions { &--fullscreen-active &__captions {
font-size: $font-size-captions-large; font-size: $plyr-font-size-captions-large;
} }
// Playback controls // Playback controls
&__controls { &__controls {
@include clearfix();
@include font-smoothing(); @include font-smoothing();
position: relative; position: relative;
padding: $control-spacing; padding: $plyr-control-spacing;
background: $controls-bg; background: $plyr-controls-bg;
line-height: 1; line-height: 1;
text-align: center; text-align: center;
box-shadow: 0 1px 1px transparentize($gray-dark, .2); box-shadow: 0 1px 1px transparentize($plyr-gray-dark, .2);
// Clear floats
&::after {
content: '';
display: table;
clear: both;
}
// Layout // Layout
&--right { &--right {
display: block; display: block;
margin: $control-spacing auto 0; margin: $plyr-control-spacing auto 0;
} }
@media (min-width: $bp-control-split) { @media (min-width: $plyr-bp-control-split) {
&--left { &--left {
float: left; float: left;
} }
@ -266,13 +263,13 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
margin: 0 2px; margin: 0 2px;
padding: ($control-spacing / 2) $control-spacing; padding: ($plyr-control-spacing / 2) $plyr-control-spacing;
overflow: hidden; overflow: hidden;
border: 0; border: 0;
background: transparent; background: transparent;
border-radius: 3px; border-radius: 3px;
cursor: pointer; cursor: pointer;
color: $control-color; color: $plyr-control-color;
transition: background .3s ease, color .3s ease, opacity .3s ease; transition: background .3s ease, color .3s ease, opacity .3s ease;
svg { svg {
@ -286,8 +283,8 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
// Hover and tab focus // Hover and tab focus
&.tab-focus:hover, &.tab-focus:hover,
&:hover { &:hover {
background: $control-bg-hover; background: $plyr-control-bg-hover;
color: $control-color-hover; color: $plyr-control-color-hover;
} }
// Default focus // Default focus
&:focus { &:focus {
@ -306,48 +303,49 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
.plyr__time { .plyr__time {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
margin-left: $control-spacing; margin-left: $plyr-control-spacing;
color: $control-color; color: $plyr-control-color;
font-weight: 600; font-weight: 600;
font-size: $font-size-small; font-size: $plyr-font-size-small;
} }
// Media duration hidden on small screens // Media duration hidden on small screens
.plyr__time + .plyr__time { .plyr__time + .plyr__time {
display: none; display: none;
@media (min-width: $bp-control-split) { @media (min-width: $plyr-bp-control-split) {
display: inline-block; display: inline-block;
} }
// Add a slash in before // Add a slash in before
&::before { &::before {
content: '\2044'; content: '\2044';
margin-right: $control-spacing; margin-right: $plyr-control-spacing;
} }
} }
} }
// Tooltips // Tooltips
&__tooltip { &__tooltip {
visibility: hidden;
position: absolute; position: absolute;
z-index: 2; z-index: 2;
bottom: 100%; bottom: 100%;
margin-bottom: $tooltip-padding; margin-bottom: $plyr-tooltip-padding;
padding: $tooltip-padding ($tooltip-padding * 1.5); padding: $plyr-tooltip-padding ($plyr-tooltip-padding * 1.5);
opacity: 0; opacity: 0;
background: $tooltip-bg; background: $plyr-tooltip-bg;
box-shadow: $tooltip-shadow; box-shadow: $plyr-tooltip-shadow;
border-radius: $tooltip-radius; border-radius: $plyr-tooltip-radius;
color: $tooltip-color; color: $plyr-tooltip-color;
font-size: $font-size-small; font-size: $plyr-font-size-small;
line-height: 1.5; line-height: 1.5;
font-weight: 600; font-weight: 600;
transform: translate(-50%, ($tooltip-padding * 3)) scale(.8); transform: translate(-50%, 10px) scale(.8);
transform-origin: 50% 100%; transform-origin: 50% 100%;
transition: transform .2s .1s ease, opacity .2s .1s ease; transition: transform .2s .1s ease, opacity .2s .1s ease, visibility .3s ease;
// Arrows // Arrows
&::after, &::after,
@ -362,24 +360,26 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
} }
// The border triangle // The border triangle
&::after { &::after {
$border-arrow-size: ($tooltip-arrow-size + ($tooltip-border-width * 1)); $plyr-border-arrow-size: ($plyr-tooltip-arrow-size + ($plyr-tooltip-border-width * 1));
bottom: -($border-arrow-size + $tooltip-border-width); bottom: -($plyr-border-arrow-size + $plyr-tooltip-border-width);
border-right: $border-arrow-size solid transparent; border-right: $plyr-border-arrow-size solid transparent;
border-top: $border-arrow-size solid $tooltip-border-color; border-top: $plyr-border-arrow-size solid $plyr-tooltip-border-color;
border-left: $border-arrow-size solid transparent; border-left: $plyr-border-arrow-size solid transparent;
z-index: 1; z-index: 1;
} }
// The background triangle // The background triangle
&::before { &::before {
bottom: -$tooltip-arrow-size; bottom: -$plyr-tooltip-arrow-size;
border-right: $tooltip-arrow-size solid transparent; border-right: $plyr-tooltip-arrow-size solid transparent;
border-top: $tooltip-arrow-size solid $tooltip-bg; border-top: $plyr-tooltip-arrow-size solid $plyr-tooltip-bg;
border-left: $tooltip-arrow-size solid transparent; border-left: $plyr-tooltip-arrow-size solid transparent;
z-index: 2; z-index: 2;
} }
} }
button:hover .plyr__tooltip, button:hover .plyr__tooltip,
button.tab-focus:focus .plyr__tooltip { button.tab-focus:focus .plyr__tooltip,
&__tooltip--visible {
visibility: visible;
opacity: 1; opacity: 1;
transform: translate(-50%, 0) scale(1); transform: translate(-50%, 0) scale(1);
} }
@ -389,19 +389,20 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
// Common range styles // Common range styles
input[type='range'].tab-focus:focus { input[type='range'].tab-focus:focus {
.tab-focus(); outline: thin dotted transparentize($plyr-gray-dark, .8);
outline-offset: 3px;
} }
// Playback progress // Playback progress
// <progress> element // <progress> element
&-progress { &__progress {
position: absolute; position: absolute;
bottom: 100%; bottom: 100%;
left: 0; left: 0;
right: 0; right: 0;
width: 100%; width: 100%;
height: $control-spacing; height: $plyr-control-spacing;
background: $progress-bg; background: $plyr-progress-bg;
&--buffer[value], &--buffer[value],
&--played[value], &--played[value],
@ -410,7 +411,7 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
left: 0; left: 0;
top: 0; top: 0;
width: 100%; width: 100%;
height: $control-spacing; height: $plyr-control-spacing;
margin: 0; margin: 0;
padding: 0; padding: 0;
vertical-align: top; vertical-align: top;
@ -424,22 +425,25 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
&--played[value] { &--played[value] {
&::-webkit-progress-bar { &::-webkit-progress-bar {
background: transparent; background: transparent;
transition: width .2s ease;
} }
// Inherit from currentColor; // Inherit from currentColor;
&::-webkit-progress-value { &::-webkit-progress-value {
background: currentColor; background: currentColor;
transition: width .2s ease;
} }
&::-moz-progress-bar { &::-moz-progress-bar {
background: currentColor; background: currentColor;
transition: width .2s ease;
} }
} }
&--played[value] { &--played[value] {
z-index: 2; z-index: 2;
color: $progress-playing-bg; color: $plyr-progress-playing-bg;
} }
&--buffer[value] { &--buffer[value] {
color: $progress-buffered-bg; color: $plyr-progress-buffered-bg;
} }
// Seek control // Seek control
@ -488,21 +492,41 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
border: 0; border: 0;
} }
} }
// Seek tooltip to show time
.plyr__tooltip {
left: 0;
}
}
// Touch seek wider handle
&--is-touch &--seek[type='range'] {
&::-webkit-slider-thumb {
@include seek-thumb-touch();
}
// Mozilla
&::-moz-range-thumb {
@include seek-thumb-touch();
}
// Microsoft
&::-ms-thumb {
@include seek-thumb-touch();
}
} }
// Loading state // Loading state
&--loading .plyr__progress--buffer { &--loading .plyr__progress--buffer {
animation: progress 1s linear infinite; animation: plyr-progress 1s linear infinite;
background-size: $progress-loading-size $progress-loading-size; background-size: $plyr-progress-loading-size $plyr-progress-loading-size;
background-repeat: repeat-x; background-repeat: repeat-x;
background-color: $progress-buffered-bg; background-color: $plyr-progress-buffered-bg;
background-image: linear-gradient( background-image: linear-gradient(
-45deg, -45deg,
$progress-loading-bg 25%, $plyr-progress-loading-bg 25%,
transparent 25%, transparent 25%,
transparent 50%, transparent 50%,
$progress-loading-bg 50%, $plyr-progress-loading-bg 50%,
$progress-loading-bg 75%, $plyr-progress-loading-bg 75%,
transparent 75%, transparent 75%,
transparent); transparent);
color: transparent; color: transparent;
@ -526,7 +550,7 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
-webkit-appearance: none; -webkit-appearance: none;
-moz-appearance: none; -moz-appearance: none;
width: 100px; width: 100px;
margin: 0 $control-spacing 0 0; margin: 0 $plyr-control-spacing 0 0;
padding: 0; padding: 0;
cursor: pointer; cursor: pointer;
background: transparent; background: transparent;
@ -538,7 +562,7 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
} }
&::-webkit-slider-thumb { &::-webkit-slider-thumb {
-webkit-appearance: none; -webkit-appearance: none;
margin-top: -(($volume-thumb-height - $volume-track-height) / 2); margin-top: -(($plyr-volume-thumb-height - $plyr-volume-track-height) / 2);
@include volume-thumb(); @include volume-thumb();
} }
@ -552,10 +576,10 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
// Microsoft // Microsoft
&::-ms-track { &::-ms-track {
height: $volume-track-height; height: $plyr-volume-track-height;
background: transparent; background: transparent;
border-color: transparent; border-color: transparent;
border-width: (($volume-thumb-height - $volume-track-height) / 2) 0; border-width: (($plyr-volume-thumb-height - $plyr-volume-track-height) / 2) 0;
color: transparent; color: transparent;
} }
&::-ms-fill-lower, &::-ms-fill-lower,
@ -570,13 +594,13 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
outline: 0; outline: 0;
&::-webkit-slider-thumb { &::-webkit-slider-thumb {
background: $volume-thumb-bg-focus; background: $plyr-volume-thumb-bg-focus;
} }
&::-moz-range-thumb { &::-moz-range-thumb {
background: $volume-thumb-bg-focus; background: $plyr-volume-thumb-bg-focus;
} }
&::-ms-thumb { &::-ms-thumb {
background: $volume-thumb-bg-focus; background: $plyr-volume-thumb-bg-focus;
} }
} }
} }
@ -597,12 +621,12 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
// Audio specific styles // Audio specific styles
// Position the progress within the container // Position the progress within the container
&--audio .plyr__controls { &--audio .plyr__controls {
padding-top: ($control-spacing * 2); padding-top: ($plyr-control-spacing * 2);
} }
&--audio .plyr__progress { &--audio .plyr__progress {
bottom: auto; bottom: auto;
top: 0; top: 0;
background: $off-white; background: $plyr-off-white;
} }
// Full screen mode // Full screen mode
@ -631,32 +655,33 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
left: 0; left: 0;
right: 0; right: 0;
} }
}
// Hide controls when playing in full screen // Hide controls when playing in full screen
&--fullscreen--hide-controls&--fullscreen-active&--playing { &--fullscreen-active.plyr--fullscreen--hide-controls.plyr--playing,
.plyr__controls { &.plyr--fullscreen.plyr--fullscreen--hide-controls.plyr--playing {
transform: translateY(100%) translateY($control-spacing / 2); .plyr__controls {
transition: transform .3s .2s ease; transform: translateY(100%) translateY($plyr-control-spacing / 2);
} transition: transform .3s .2s ease;
&.plyr--hover .plyr__controls {
transform: translateY(0);
}
.plyr__captions {
bottom: ($control-spacing / 2);
transition: bottom .3s .2s ease;
}
} }
.plyr__captions {
bottom: ($plyr-control-spacing / 2);
transition: bottom .3s .2s ease;
}
&.plyr--hover .plyr__controls {
transform: translateY(0);
}
}
// Captions // Captions
&--fullscreen .plyr__captions, &.plyr--fullscreen .plyr__captions,
&--fullscreen-active .plyr__captions, &--fullscreen-active .plyr__captions,
&--fullscreen--hide-controls&--fullscreen-active&--playing&--hover &__captions { &--fullscreen--hide-controls.plyr--fullscreen-active.plyr--playing.plyr--hover .plyr__captions {
top: auto; top: auto;
bottom: 90px; bottom: 90px;
@media (min-width: $bp-control-split) { @media (min-width: $plyr-bp-control-split) {
bottom: 60px; bottom: 60px;
}
} }
} }

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"> <svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<title>Captions Off</title>
<g> <g>
<path d="M1,2 C0.448,2 0,2.448 0,3 L0,15 C0,15.552 0.448,16 1,16 L17,16 C17.552,16 18,15.552 18,15 L18,3 C18,2.448 17.552,2 17,2 L1,2 Z M2,14 L2,4 L16,4 L16,14 L2,14 L2,14 Z"></path> <path d="M1,2 C0.448,2 0,2.448 0,3 L0,15 C0,15.552 0.448,16 1,16 L17,16 C17.552,16 18,15.552 18,15 L18,3 C18,2.448 17.552,2 17,2 L1,2 Z M2,14 L2,4 L16,4 L16,14 L2,14 L2,14 Z"></path>
</g> </g>

Before

Width:  |  Height:  |  Size: 474 B

After

Width:  |  Height:  |  Size: 443 B

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Captions On</title>
<g> <g>
<path d="M1,2 C0.448,2 0,2.448 0,3 L0,15 C0,15.552 0.448,16 1,16 L17,16 C17.552,16 18,15.552 18,15 L18,3 C18,2.448 17.552,2 17,2 L1,2 Z M2,14 L2,4 L16,4 L16,14 L2,14 L2,14 Z"></path> <path d="M1,2 C0.448,2 0,2.448 0,3 L0,15 C0,15.552 0.448,16 1,16 L17,16 C17.552,16 18,15.552 18,15 L18,3 C18,2.448 17.552,2 17,2 L1,2 Z M2,14 L2,4 L16,4 L16,14 L2,14 L2,14 Z"></path>
<rect x="3" y="11" width="3" height="2"></rect> <rect x="3" y="11" width="3" height="2"></rect>

Before

Width:  |  Height:  |  Size: 587 B

After

Width:  |  Height:  |  Size: 557 B

View File

@ -1,10 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Enter Fullscreen</title> <g transform="translate(9.000000, 9.000000) rotate(-180.000000) translate(-9.000000, -9.000000) translate(0.000000, 2.000000)">
<g> <path d="M7.69999981,6.30000001 C7.00064659,5.62264405 6.3,6.3 6.3,6.3 L2,10.6 L2,6 L0,6 L0,13 C0,13.6 0.4,14 1,14 L8,14 L8,12 L3.4,12 L7.7,7.7 C7.7,7.7 8.39935303,6.97735597 7.69999981,6.30000001 Z"></path>
<g transform="translate(9.000000, 9.000000) rotate(-180.000000) translate(-9.000000, -9.000000) translate(0.000000, 2.000000)"> <path d="M11,14 L11,12 L16,12 L16,2 L2,2 L2,3 L0,3 L0,1 C0,0.4 0.4,0 1,0 L17,0 C17.6,0 18,0.4 18,1 L18,13 C18,13.6 17.6,14 17,14 L11,14 Z"></path>
<path d="M7.69999981,6.30000001 C7.00064659,5.62264405 6.3,6.3 6.3,6.3 L2,10.6 L2,6 L0,6 L0,13 C0,13.6 0.4,14 1,14 L8,14 L8,12 L3.4,12 L7.7,7.7 C7.7,7.7 8.39935303,6.97735597 7.69999981,6.30000001 Z"></path>
<path d="M11,14 L11,12 L16,12 L16,2 L2,2 L2,3 L0,3 L0,1 C0,0.4 0.4,0 1,0 L17,0 C17.6,0 18,0.4 18,1 L18,13 C18,13.6 17.6,14 17,14 L11,14 Z"></path>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 787 B

After

Width:  |  Height:  |  Size: 719 B

View File

@ -1,10 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Exit Fullscreen</title> <g transform="translate(0.000000, 2.000000)">
<g> <path d="M7.69999981,6.30000001 C7.00064659,5.62264405 6.3,6.3 6.3,6.3 L2,10.6 L2,6 L0,6 L0,13 C0,13.6 0.4,14 1,14 L8,14 L8,12 L3.4,12 L7.7,7.7 C7.7,7.7 8.39935303,6.97735597 7.69999981,6.30000001 Z"></path>
<g transform="translate(0.000000, 2.000000)"> <path d="M11,14 L11,12 L16,12 L16,2 L2,2 L2,3 L0,3 L0,1 C0,0.4 0.4,0 1,0 L17,0 C17.6,0 18,0.4 18,1 L18,13 C18,13.6 17.6,14 17,14 L11,14 Z"></path>
<path d="M7.69999981,6.30000001 C7.00064659,5.62264405 6.3,6.3 6.3,6.3 L2,10.6 L2,6 L0,6 L0,13 C0,13.6 0.4,14 1,14 L8,14 L8,12 L3.4,12 L7.7,7.7 C7.7,7.7 8.39935303,6.97735597 7.69999981,6.30000001 Z"></path>
<path d="M11,14 L11,12 L16,12 L16,2 L2,2 L2,3 L0,3 L0,1 C0,0.4 0.4,0 1,0 L17,0 C17.6,0 18,0.4 18,1 L18,13 C18,13.6 17.6,14 17,14 L11,14 Z"></path>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 637 B

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Fast Forward</title>
<path d="M17.569 8.246l-10.569-6.246c-0.552 0-1 0.448-1 1v1.954l-5-2.954c-0.552 0-1 0.448-1 1v12c0 0.552 0.448 1 1 1l5-2.955v1.955c0 0.552 0.448 1 1 1l10.569-6.246c0.267-0.158 0.431-0.444 0.431-0.754s-0.164-0.597-0.431-0.754zM6 10.722l-4 2.364v-8.172l4 2.364v3.444zM8 13.086v-8.172l6.915 4.086-6.915 4.086z"></path> <path d="M17.569 8.246l-10.569-6.246c-0.552 0-1 0.448-1 1v1.954l-5-2.954c-0.552 0-1 0.448-1 1v12c0 0.552 0.448 1 1 1l5-2.955v1.955c0 0.552 0.448 1 1 1l10.569-6.246c0.267-0.158 0.431-0.444 0.431-0.754s-0.164-0.597-0.431-0.754zM6 10.722l-4 2.364v-8.172l4 2.364v3.444zM8 13.086v-8.172l6.915 4.086-6.915 4.086z"></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 481 B

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Muted</title>
<g transform="translate(0.000000, 2.000000)"> <g transform="translate(0.000000, 2.000000)">
<path d="M9.214,0 C9.103,0 8.989,0.032 8.88,0.101 L4.832,2.911 C4.749,2.969 4.65,3 4.549,3 L0.996,3 C0.446,3 1.33226763e-15,3.448 1.33226763e-15,4 L1.33226763e-15,10 C1.33226763e-15,10.552 0.446,11 0.996,11 L4.549,11 C4.651,11 4.749,11.031 4.832,11.089 L8.88,13.899 C8.989,13.968 9.103,14 9.214,14 C9.606,14 9.961,13.6 9.961,13.051 L9.961,0.95 C9.961,0.4 9.606,0.001 9.214,0.001 L9.214,0 Z M7.969,10.834 L5.582,9.177 C5.416,9.062 5.218,8.999 5.016,8.999 L2.491,8.999 C2.216,8.999 1.993,8.775 1.993,8.499 L1.993,5.499 C1.993,5.223 2.216,4.999 2.491,4.999 L5.016,4.999 C5.218,4.999 5.416,4.937 5.582,4.821 L7.969,3.164 L7.969,10.833 L7.969,10.834 Z"></path> <path d="M9.214,0 C9.103,0 8.989,0.032 8.88,0.101 L4.832,2.911 C4.749,2.969 4.65,3 4.549,3 L0.996,3 C0.446,3 1.33226763e-15,3.448 1.33226763e-15,4 L1.33226763e-15,10 C1.33226763e-15,10.552 0.446,11 0.996,11 L4.549,11 C4.651,11 4.749,11.031 4.832,11.089 L8.88,13.899 C8.989,13.968 9.103,14 9.214,14 C9.606,14 9.961,13.6 9.961,13.051 L9.961,0.95 C9.961,0.4 9.606,0.001 9.214,0.001 L9.214,0 Z M7.969,10.834 L5.582,9.177 C5.416,9.062 5.218,8.999 5.016,8.999 L2.491,8.999 C2.216,8.999 1.993,8.775 1.993,8.499 L1.993,5.499 C1.993,5.223 2.216,4.999 2.491,4.999 L5.016,4.999 C5.218,4.999 5.416,4.937 5.582,4.821 L7.969,3.164 L7.969,10.833 L7.969,10.834 Z"></path>
<path d="M14.934,6.799 C14.848,5.051 13.42,3.808 12.427,3.15 C11.957,2.838 11.333,3.028 11.102,3.558 L11.064,3.644 C10.876,4.075 11.019,4.583 11.4,4.838 C12.106,5.311 12.986,6.085 13.024,6.903 C13.056,7.579 12.471,8.371 11.361,9.173 C10.963,9.461 10.832,10.012 11.076,10.448 L11.118,10.523 C11.384,10.998 11.984,11.147 12.418,10.835 C14.158,9.584 15.004,8.229 14.934,6.798 L14.934,6.799 Z"></path> <path d="M14.934,6.799 C14.848,5.051 13.42,3.808 12.427,3.15 C11.957,2.838 11.333,3.028 11.102,3.558 L11.064,3.644 C10.876,4.075 11.019,4.583 11.4,4.838 C12.106,5.311 12.986,6.085 13.024,6.903 C13.056,7.579 12.471,8.371 11.361,9.173 C10.963,9.461 10.832,10.012 11.076,10.448 L11.118,10.523 C11.384,10.998 11.984,11.147 12.418,10.835 C14.158,9.584 15.004,8.229 14.934,6.798 L14.934,6.799 Z"></path>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Pause</title>
<g transform="translate(2.000000, 2.000000)"> <g transform="translate(2.000000, 2.000000)">
<path d="M0,2 L0,12 C5.24848613e-17,14 2,14 2,14 L4,14 C4,14 6,14 6,12 C6,11.786438 6,11.572876 6,11 L6,2 C6,3.17446247e-09 4,0 4,0 L2,0 C2,0 0,0 0,2 Z M2,2 L4,2 L4,12 L2,12 L2,2 Z"></path> <path d="M0,2 L0,12 C5.24848613e-17,14 2,14 2,14 L4,14 C4,14 6,14 6,12 C6,11.786438 6,11.572876 6,11 L6,2 C6,3.17446247e-09 4,0 4,0 L2,0 C2,0 0,0 0,2 Z M2,2 L4,2 L4,12 L2,12 L2,2 Z"></path>
<path d="M8,2 L8,12 C8,14 10,14 10,14 L12,14 C12,14 14,14 14,12 C14,11.786438 14,11.572876 14,11 L14,2 C14,3.17446247e-09 12,0 12,0 L10,0 C10,0 8,0 8,2 Z M10,2 L12,2 L12,12 L10,12 L10,2 Z"></path> <path d="M8,2 L8,12 C8,14 10,14 10,14 L12,14 C12,14 14,14 14,12 C14,11.786438 14,11.572876 14,11 L14,2 C14,3.17446247e-09 12,0 12,0 L10,0 C10,0 8,0 8,2 Z M10,2 L12,2 L12,12 L10,12 L10,2 Z"></path>

Before

Width:  |  Height:  |  Size: 666 B

After

Width:  |  Height:  |  Size: 642 B

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Play</title>
<path d="M5 4.914l6.915 4.086-6.915 4.086v-8.172zM4 2c-0.552 0-1 0.448-1 1v12c0 0.552 0.448 1 1 1l10.569-6.246c0.267-0.158 0.431-0.444 0.431-0.754s-0.164-0.597-0.431-0.754l-10.569-6.246z"></path> <path d="M5 4.914l6.915 4.086-6.915 4.086v-8.172zM4 2c-0.552 0-1 0.448-1 1v12c0 0.552 0.448 1 1 1l10.569-6.246c0.267-0.158 0.431-0.444 0.431-0.754s-0.164-0.597-0.431-0.754l-10.569-6.246z"></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 361 B

View File

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
<path d="M7.7,1.2l0.7,6.4l2.1-2.1c1.9,1.9,1.9,5.1,0,7C9.6,13.5,8.3,14,7,14c-1.3,0-2.6-0.5-3.5-1.5 <path d="M7.7,1.2l0.7,6.4l2.1-2.1c1.9,1.9,1.9,5.1,0,7C9.6,13.5,8.3,14,7,14c-1.3,0-2.6-0.5-3.5-1.5
c-1.9-1.9-1.9-5.1,0-7c0.6-0.6,1.4-1.1,2.3-1.3L5.2,2.3C4,2.6,2.9,3.2,2,4.1c-2.7,2.7-2.7,7.1,0,9.9c1.3,1.3,3.1,2,4.9,2 c-1.9-1.9-1.9-5.1,0-7c0.6-0.6,1.4-1.1,2.3-1.3L5.2,2.3C4,2.6,2.9,3.2,2,4.1c-2.7,2.7-2.7,7.1,0,9.9c1.3,1.3,3.1,2,4.9,2
c1.9,0,3.6-0.7,4.9-2c2.7-2.7,2.7-7.1,0-9.9l2.2-2.2L7.7,1.2z"/> c1.9,0,3.6-0.7,4.9-2c2.7-2.7,2.7-7.1,0-9.9l2.2-2.2L7.7,1.2z"/>

Before

Width:  |  Height:  |  Size: 760 B

After

Width:  |  Height:  |  Size: 505 B

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 18 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"> <svg viewBox="0 0 18 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<title>Rewind</title>
<path d="M17.569,9.246 L7,3 C6.448,3 6,3.448 6,4 L6,5.954 L1,3 C0.448,3 0,3.448 0,4 L0,16 C0,16.552 0.448,17 1,17 L6,14.045 L6,16 C6,16.552 6.448,17 7,17 L17.569,10.754 C17.836,10.596 18,10.31 18,10 C18,9.69 17.836,9.403 17.569,9.246 L17.569,9.246 Z M6,11.722 L2,14.086 L2,5.914 L6,8.278 L6,11.722 L6,11.722 Z M8,14.086 L8,5.914 L14.915,10 L8,14.086 L8,14.086 Z" transform="translate(9.000000, 10.000000) rotate(-180.000000) translate(-9.000000, -10.000000) "></path> <path d="M17.569,9.246 L7,3 C6.448,3 6,3.448 6,4 L6,5.954 L1,3 C0.448,3 0,3.448 0,4 L0,16 C0,16.552 0.448,17 1,17 L6,14.045 L6,16 C6,16.552 6.448,17 7,17 L17.569,10.754 C17.836,10.596 18,10.31 18,10 C18,9.69 17.836,9.403 17.569,9.246 L17.569,9.246 Z M6,11.722 L2,14.086 L2,5.914 L6,8.278 L6,11.722 L6,11.722 Z M8,14.086 L8,5.914 L14.915,10 L8,14.086 L8,14.086 Z" transform="translate(9.000000, 10.000000) rotate(-180.000000) translate(-9.000000, -10.000000) "></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 729 B

After

Width:  |  Height:  |  Size: 704 B

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Volume</title>
<path d="M10.214 2c-0.111 0-0.225 0.032-0.334 0.101l-4.048 2.81c-0.083 0.058-0.182 0.089-0.283 0.089h-3.553c-0.55 0-0.996 0.448-0.996 1v6c0 0.552 0.446 1 0.996 1h3.553c0.102 0 0.2 0.031 0.283 0.089l4.048 2.81c0.109 0.069 0.223 0.101 0.334 0.101 0.392 0 0.747-0.4 0.747-0.949v-12.101c0-0.55-0.355-0.949-0.747-0.949zM8.969 12.834l-2.387-1.657c-0.166-0.115-0.364-0.178-0.566-0.178h-2.525c-0.275 0-0.498-0.224-0.498-0.5v-3c0-0.276 0.223-0.5 0.498-0.5h2.525c0.202 0 0.4-0.062 0.566-0.178l2.387-1.657v7.669z"></path> <path d="M10.214 2c-0.111 0-0.225 0.032-0.334 0.101l-4.048 2.81c-0.083 0.058-0.182 0.089-0.283 0.089h-3.553c-0.55 0-0.996 0.448-0.996 1v6c0 0.552 0.446 1 0.996 1h3.553c0.102 0 0.2 0.031 0.283 0.089l4.048 2.81c0.109 0.069 0.223 0.101 0.334 0.101 0.392 0 0.747-0.4 0.747-0.949v-12.101c0-0.55-0.355-0.949-0.747-0.949zM8.969 12.834l-2.387-1.657c-0.166-0.115-0.364-0.178-0.566-0.178h-2.525c-0.275 0-0.498-0.224-0.498-0.5v-3c0-0.276 0.223-0.5 0.498-0.5h2.525c0.202 0 0.4-0.062 0.566-0.178l2.387-1.657v7.669z"></path>
<path d="M16.934 8.799c-0.086-1.748-1.514-2.991-2.507-3.649-0.47-0.312-1.094-0.122-1.325 0.408l-0.038 0.086c-0.188 0.431-0.045 0.939 0.336 1.194 0.706 0.473 1.586 1.247 1.624 2.065 0.032 0.676-0.553 1.468-1.663 2.27-0.398 0.288-0.529 0.839-0.285 1.275l0.042 0.075c0.266 0.475 0.866 0.624 1.3 0.312 1.74-1.251 2.586-2.606 2.516-4.037z"></path> <path d="M16.934 8.799c-0.086-1.748-1.514-2.991-2.507-3.649-0.47-0.312-1.094-0.122-1.325 0.408l-0.038 0.086c-0.188 0.431-0.045 0.939 0.336 1.194 0.706 0.473 1.586 1.247 1.624 2.065 0.032 0.676-0.553 1.468-1.663 2.27-0.398 0.288-0.529 0.839-0.285 1.275l0.042 0.075c0.266 0.475 0.866 0.624 1.3 0.312 1.74-1.251 2.586-2.606 2.516-4.037z"></path>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1020 B