Source API changes, Vimeo fixes, still WIP

This commit is contained in:
Sam Potts 2015-10-04 19:27:30 +11:00
parent 0674e13bab
commit daec1baebc
22 changed files with 539 additions and 368 deletions

View File

@ -9,8 +9,7 @@
"rhino" : false, "rhino" : false,
"couch" : false, "couch" : false,
"wsh" : true, // Windows Scripting Host. "wsh" : true, // Windows Scripting Host.
"jquery" : true, "jquery" : false,
"predef" : [ "jQuery", "$" ],
// Development. // Development.
"debug" : false, // Allow debugger statements e.g. browser breakpoints. "debug" : false, // Allow debugger statements e.g. browser breakpoints.
@ -51,6 +50,6 @@
"plusplus" : false, // Prohibit use of `++` & `--`. "plusplus" : false, // Prohibit use of `++` & `--`.
"sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
"trailing" : true, // Prohibit trailing whitespaces. "trailing" : true, // Prohibit trailing whitespaces.
"white" : false, // Check against strict whitespace and indentation rules. "white" : true, // Check against strict whitespace and indentation rules.
"indent" : 2 // Specify indentation spacing "indent" : 4 // Specify indentation spacing
} }

2
dist/plyr.css vendored

File diff suppressed because one or more lines are too long

2
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" id="Shape"/><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>icon-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" id="Shape"/><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.67z" id="Shape"/><path d="M14.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 18 18"><path d="M1 2c.552 0 1 .448 1 1v4.318L11 2c.552 0 1 .448 1 1v1.954L17 2c.552 0 1 .448 1 1v12c0 .552-.448 1-1 1l-5-2.955V15c0 .552-.448 1-1 1l-9-5.318V15c0 .552-.448 1-1 1s-1-.448-1-1V3c0-.552.448-1 1-1zm11 8.722l4 2.364V4.914l-4 2.364v3.444zm-2 2.364V4.914L3.085 9 10 13.086z"/></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> <?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 18 18"><title>Restart</title><path d="M1 2c.552 0 1 .448 1 1v4.318L11 2c.552 0 1 .448 1 1v1.954L17 2c.552 0 1 .448 1 1v12c0 .552-.448 1-1 1l-5-2.955V15c0 .552-.448 1-1 1l-9-5.318V15c0 .552-.448 1-1 1s-1-.448-1-1V3c0-.552.448-1 1-1zm11 8.722l4 2.364V4.914l-4 2.364v3.444zm-2 2.364V4.914L3.085 9 10 13.086z"/></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>

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

2
docs/dist/docs.css vendored

File diff suppressed because one or more lines are too long

2
docs/dist/docs.js vendored

File diff suppressed because one or more lines are too long

1
docs/dist/sprite.svg vendored Normal file
View File

@ -0,0 +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-github" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 .2c-4.4 0-8 3.6-8 8 0 3.5 2.3 6.5 5.5 7.6.4.1.5-.2.5-.4V14c-2.2.5-2.7-1-2.7-1-.4-.9-.9-1.2-.9-1.2-.7-.5.1-.5.1-.5.8.1 1.2.8 1.2.8.7 1.3 1.9.9 2.3.7.1-.5.3-.9.5-1.1-1.8-.2-3.6-.9-3.6-4 0-.9.3-1.6.8-2.1-.1-.2-.4-1 .1-2.1 0 0 .7-.2 2.2.8.6-.2 1.3-.3 2-.3s1.4.1 2 .3c1.5-1 2.2-.8 2.2-.8.4 1.1.2 1.9.1 2.1.5.6.8 1.3.8 2.1 0 3.1-1.9 3.7-3.7 3.9.3.4.6.9.6 1.6v2.2c0 .2.1.5.6.4 3.2-1.1 5.5-4.1 5.5-7.6-.1-4.4-3.7-8-8.1-8z"/></symbol><symbol id="icon-twitter" viewBox="0 0 16 16"><title>Twitter</title><path d="M16 3c-.6.3-1.2.4-1.9.5.7-.4 1.2-1 1.4-1.8-.6.4-1.3.6-2.1.8-.6-.6-1.5-1-2.4-1-1.7 0-3.2 1.5-3.2 3.3 0 .3 0 .5.1.7-2.7-.1-5.2-1.4-6.8-3.4-.3.5-.4 1-.4 1.7 0 1.1.6 2.1 1.5 2.7-.5 0-1-.2-1.5-.4C.7 7.7 1.8 9 3.3 9.3c-.3.1-.6.1-.9.1-.2 0-.4 0-.6-.1.4 1.3 1.6 2.3 3.1 2.3-1.1.9-2.5 1.4-4.1 1.4H0c1.5.9 3.2 1.5 5 1.5 6 0 9.3-5 9.3-9.3v-.4C15 4.3 15.6 3.7 16 3z"/></symbol><symbol id="icon-vimeo" viewBox="0 0 16 16"><path d="M16 4.3c-.1 1.6-1.2 3.7-3.3 6.4-2.2 2.8-4 4.2-5.5 4.2-.9 0-1.7-.9-2.4-2.6C4 9.9 3.4 5 2 5c-.1 0-.5.3-1.2.8l-.8-1c.8-.7 3.5-3.4 4.7-3.5 1.2-.1 2 .7 2.3 2.5.3 2 .8 6.1 1.8 6.1.9 0 2.5-3.4 2.6-4 .1-.9-.3-1.9-2.3-1.1.8-2.6 2.3-3.8 4.5-3.8 1.7.1 2.5 1.2 2.4 3.3z"/></symbol><symbol id="icon-youtube" viewBox="0 0 16 16"><path d="M15.8 4.8c-.2-1.3-.8-2.2-2.2-2.4C11.4 2 8 2 8 2s-3.4 0-5.6.4C1 2.6.3 3.5.2 4.8 0 6.1 0 8 0 8s0 1.9.2 3.2c.2 1.3.8 2.2 2.2 2.4C4.6 14 8 14 8 14s3.4 0 5.6-.4c1.4-.3 2-1.1 2.2-2.4C16 9.9 16 8 16 8s0-1.9-.2-3.2zM6 11V5l5 3-5 3z"/></symbol></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -16,16 +16,18 @@
<body> <body>
<header> <header>
<h1>Plyr</h1> <h1>Plyr</h1>
<p>A simple HTML5 media player with custom controls and WebVTT captions by <a href="https://twitter.com/sam_potts" target="_blank">@sam_potts</a></p> <p>A simple, accessible HTML5 media player by <a href="https://twitter.com/sam_potts" target="_blank">@sam_potts</a> from <a href="https://twitter.com/selz" target="_blank">@selz</a></p>
<nav> <nav>
<ul> <ul>
<li> <li>
<a href="https://github.com/selz/plyr" target="_blank" class="btn btn-primary">Download on GitHub</a> <a href="https://github.com/selz/plyr" target="_blank" class="btn btn-primary" data-shr-network="github">
<span class="btn-count js-stargazers-count">&hellip;</span> <svg class="icon"><use xlink:href="#icon-github"/></svg>Get it on GitHub
</a>
</li> </li>
<li> <li>
<a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&url=http%3A%2F%2Fplyr.io&via=Sam_Potts" target="_blank" class="btn js-popup" data-window-height="250" data-window-width="500">Tweet</a> <a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&url=http%3A%2F%2Fplyr.io&via=Sam_Potts" target="_blank" class="btn btn-twitter" data-shr-network="twitter">
<span class="btn-count js-tweet-count">&hellip;</span> <svg class="icon"><use xlink:href="#icon-twitter"/></svg>Tweet
</a>
</li> </li>
</ul> </ul>
</nav> </nav>
@ -42,7 +44,7 @@
<div class="panels"> <div class="panels">
<section class="panel example-video active" id="video"> <section class="panel example-video active" id="video">
<div class="player"> <div class="player">
<video poster="https://cdn.plyr.io/static/poster.jpg" controls crossorigin> <video poster="https://cdn.selz.com/plyr/1.0/poster.jpg" controls crossorigin>
<!-- Video files --> <!-- Video files -->
<source src="https://cdn.selz.com/plyr/1.0/movie.mp4" type="video/mp4"> <source src="https://cdn.selz.com/plyr/1.0/movie.mp4" type="video/mp4">
<source src="https://cdn.selz.com/plyr/1.0/movie.webm" type="video/webm"> <source src="https://cdn.selz.com/plyr/1.0/movie.webm" type="video/webm">
@ -66,11 +68,11 @@
<div class="player"> <div class="player">
<audio controls> <audio controls>
<!-- Audio files --> <!-- Audio files -->
<source src="//cdn.selz.com/plyr/1.0/logistics-96-sample.mp3" type="audio/mp3"> <source src="https://cdn.selz.com/plyr/1.0/logistics-96-sample.mp3" type="audio/mp3">
<source src="//cdn.selz.com/plyr/1.0/logistics-96-sample.ogg" type="audio/ogg"> <source src="https://cdn.selz.com/plyr/1.0/logistics-96-sample.ogg" type="audio/ogg">
<!-- Fallback for browsers that don't support the <audio> element --> <!-- Fallback for browsers that don't support the <audio> element -->
<a href="//cdn.selz.com/plyr/1.0/logistics-96-sample.mp3">Download</a> <a href="https://cdn.selz.com/plyr/1.0/logistics-96-sample.mp3">Download</a>
</audio> </audio>
</div> </div>
<small>"96" by Logistics, which can be purchased from <a href="https://www.hospitalrecords.com/shop/artist/logistics" target="_blank">Hospital Records</a>.</small> <small>"96" by Logistics, which can be purchased from <a href="https://www.hospitalrecords.com/shop/artist/logistics" target="_blank">Hospital Records</a>.</small>
@ -81,28 +83,35 @@
<!-- Load SVG defs --> <!-- Load SVG defs -->
<!-- You should bundle all SVG/Icons into one file using a build tool such as gulp and svg store --> <!-- You should bundle all SVG/Icons into one file using a build tool such as gulp and svg store -->
<script> <script>
(function(d, u){ function loadSprite(d, u) {
var a = new XMLHttpRequest(), var a = new XMLHttpRequest(),
b = d.body; b = document.body;
// Check for CORS support // If proper CORS supported
// If you're loading from same domain, you can remove the if statement
if("withCredentials" in a) { if("withCredentials" in a) {
a.open("GET", u, true); a.open("GET", u, true);
a.send(); a.send();
a.onload = function(){ a.onload = function(){
var c = d.createElement("div"); var c = document.createElement("div");
c.setAttribute("hidden", ""); c.setAttribute("hidden", "");
c.innerHTML = a.responseText; c.innerHTML = a.responseText;
b.insertBefore(c, b.childNodes[0]); b.insertBefore(c, b.childNodes[0]);
} }
} }
})(document, "https://cdn.plyr.io/1.3.5/sprite.svg"); }
// Load the plyr sprite
loadSprite(document, "../dist/sprite.svg");
// This is for the docs only
loadSprite(document, "dist/sprite.svg");
</script> </script>
<!-- Plyr core script --> <!-- Plyr core script -->
<script src="https://cdn.plyr.io/1.3.5/plyr.js"></script> <script src="https://cdn.plyr.io/1.3.5/plyr.js"></script>
<!-- Shr core script -->
<script src="https://cdn.shr.one/0.1.7/shr.js"></script>
<!-- Docs script --> <!-- Docs script -->
<script src="https://cdn.plyr.io/1.3.5/docs.js"></script> <script src="https://cdn.plyr.io/1.3.5/docs.js"></script>
</body> </body>

View File

@ -2,182 +2,124 @@
// Docs example // Docs example
// ========================================================================== // ==========================================================================
/*global plyr, templates */ /*global plyr, shr, templates */
// Setup the player // Setup the player
plyr.setup({ plyr.setup({
debug: true, debug: true,
volume: 9, volume: 9,
title: "Video demo", title: 'Video demo',
html: templates.controls.render({}), html: templates.controls.render({}),
tooltips: true, tooltips: true,
captions: { captions: {
defaultActive: true defaultActive: true
}, },
onSetup: function() { onSetup: function() {
if(!("media" in this)) { if(!('media' in this)) {
return; return;
} }
var player = this, var player = this,
type = player.media.tagName.toLowerCase(), type = player.media.tagName.toLowerCase(),
toggle = document.querySelector("[data-toggle='fullscreen']"); toggle = document.querySelector('[data-toggle="fullscreen"]');
console.log("✓ Setup done for <" + type + ">"); console.log('✓ Setup done for <' + type + '>');
if(type === "video" && toggle) { if(type === 'video' && toggle) {
toggle.addEventListener("click", player.toggleFullscreen, false); toggle.addEventListener('click', player.toggleFullscreen, false);
} }
} }
}); });
// Setup shr
shr.setup({
count: {
classname: 'btn-count'
}
});
// General functions // General functions
(function() { (function() {
// Popup var buttons = document.querySelectorAll('[data-source]');
function popup(event) {
// Prevent the link opening // Bind to each button
if(event.target.nodeName.toLowerCase() == "a") { for (var i = buttons.length - 1; i >= 0; i--) {
if(event.preventDefault) { buttons[i].addEventListener('click', newSource);
event.preventDefault();
}
else {
event.returnValue = false;
}
} }
var link = event.target, // Set a new source
url = link.href, function newSource() {
width = link.getAttribute("data-window-width") || 600, var trigger = this,
height = link.getAttribute("data-window-height") || 600, type = trigger.getAttribute('data-source'),
name = link.getAttribute("data-window-name") || "popup"; player = document.querySelector('.player').plyr;
// If window exists, just focus it switch(type) {
if(window["window-"+name] && !window["window-"+name].closed) { case 'video':
window["window-"+name].focus(); player.source({
} type: 'video',
else { sources: [{
// Get position src: 'https://cdn.selz.com/plyr/1.0/movie.mp4',
var left = window.screenLeft !== undefined ? window.screenLeft : screen.left; type: 'video/mp4'
var top = window.screenTop !== undefined ? window.screenTop : screen.top; },
{
// Open in the centre of the screen src: 'https://cdn.selz.com/plyr/1.0/movie.webm',
var x = (screen.width / 2) - (width / 2) + left, type: 'video/webm'
y = (screen.height / 2) - (height / 2) + top; }],
poster: 'https://cdn.selz.com/plyr/1.0/poster.jpg',
// Open that window tracks: [{
window["window-"+name] = window.open(url, name, "top=" + y +",left="+ x +",width=" + width + ",height=" + height); kind: 'captions',
label: 'English',
// Focus new window srclang:'en',
window["window-"+name].focus(); src: 'https://cdn.selz.com/plyr/1.0/example_captions_en.vtt',
} default: true
} }]
// Trigger popups
document.querySelector(".js-popup").addEventListener("click", popup);
// Get JSONP
function getJSONP(url, callback) {
var name = "jsonp_callback_" + Math.round(100000 * Math.random());
// Cleanup to prevent memory leaks and hit original callback
window[name] = function(data) {
delete window[name];
document.body.removeChild(script);
callback(data);
};
// Create a faux script
var script = document.createElement("script");
script.setAttribute("src", url + (url.indexOf("?") >= 0 ? "&" : "?") + "callback=" + name);
// Inject to the body
document.body.appendChild(script);
}
// Get star count
var storageSupported = ("sessionStorage" in window),
selectors = {
github: ".js-stargazers-count",
twitter: ".js-tweet-count"
};
// Display the count next to the button
function displayCount(selector, count) {
document.querySelector(selector).innerHTML = count;
}
// Add star
function formatGitHubCount(count) {
return "&#9733; " + count;
}
// Check if it's in session storage first
if(storageSupported && "github_stargazers" in window.sessionStorage) {
displayCount(selectors.github, formatGitHubCount(window.sessionStorage.github_stargazers));
}
else {
getJSONP("https://api.github.com/repos/selz/plyr?access_token=a46ac653210ba6a6be44260c29c333470c3fbbf5", function (json) {
if (json && typeof json.data.stargazers_count !== "undefined") {
// Update UI
displayCount(selectors.github, formatGitHubCount(json.data.stargazers_count));
// Store in session storage
window.sessionStorage.github_stargazers = json.data.stargazers_count;
}
}); });
} break;
// Get tweet count case 'audio':
if(storageSupported && "tweets" in window.sessionStorage) { player.source({
displayCount(selectors.twitter, window.sessionStorage.tweets); type: 'audio',
} sources: [{
else { src: 'https://cdn.selz.com/plyr/1.0/logistics-96-sample.mp3',
getJSONP("https://cdn.api.twitter.com/1/urls/count.json?url=plyr.io", function (json) { type: 'audio/mp3'
if (json && typeof json.count !== "undefined") { },
// Update UI {
displayCount(selectors.twitter, json.count); src: 'https://cdn.selz.com/plyr/1.0/logistics-96-sample.ogg',
type: 'audio/ogg'
// Store in session storage }]
window.sessionStorage.tweets = json.count;
}
}); });
break;
case 'youtube':
player.source({
type: 'youtube',
sources: 'iicnVez5U7M'
});
break;
case 'vimeo':
player.source({
type: 'vimeo',
sources: '125220818'
});
break;
} }
// Tabs for (var x = buttons.length - 1; x >= 0; x--) {
var tabs = document.querySelectorAll(".nav-panel a"), buttons[x].classList.remove('active');
panels = document.querySelectorAll(".panels > .panel"),
activeClass = "active";
for (var i = tabs.length - 1; i >= 0; i--) {
tabs[i].addEventListener("click", togglePanel);
} }
function togglePanel(event) { event.target.classList.add('active');
event.preventDefault();
var tab = event.target,
panel = document.querySelector(tab.getAttribute("href"));
for (var i = panels.length - 1; i >= 0; i--) {
panels[i].classList.remove(activeClass);
}
for (var x = tabs.length - 1; x >= 0; x--) {
tabs[x].classList.remove(activeClass);
}
panel.classList.add(activeClass);
event.target.classList.add(activeClass);
} }
})(); })();
// Google analytics // Google analytics
// For demo site (http://[www.]plyr.io) only // For demo site (http://[www.]plyr.io) only
if(document.domain.indexOf("plyr.io") > -1) { if(document.domain.indexOf('plyr.io') > -1) {
(function(i,s,o,g,r,a,m){i.GoogleAnalyticsObject=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){i.GoogleAnalyticsObject=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,"script","//www.google-analytics.com/analytics.js","ga"); })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga("create", "UA-40881672-11", "auto"); ga('create', 'UA-40881672-11', 'auto');
ga("send", "pageview"); ga('send', 'pageview');
} }

View File

@ -67,6 +67,10 @@ nav {
box-shadow: inset 0 1px 1px rgba(0,0,0, .2); box-shadow: inset 0 1px 1px rgba(0,0,0, .2);
position: relative; position: relative;
z-index: 1; z-index: 1;
.icon {
color: inherit;
}
} }
@media (min-width: 560px) { @media (min-width: 560px) {
@ -92,6 +96,7 @@ nav {
box-shadow: inset 0 1px 0 #fff, 0 1px 1px rgba(0,0,0, .05); box-shadow: inset 0 1px 0 #fff, 0 1px 1px rgba(0,0,0, .05);
text-shadow: 0 1px 1px #fff; text-shadow: 0 1px 1px #fff;
color: @gray; color: @gray;
transition: all .3s ease;
&:hover, &:hover,
&:focus { &:focus {
@ -100,6 +105,15 @@ nav {
color: @link-color; color: @link-color;
outline: 0; outline: 0;
} }
&-youtube .icon {
color: @color-youtube;
}
&-vimeo .icon {
color: @color-vimeo;
}
&-twitter .icon {
color: @color-twitter;
}
} }
.btn-primary { .btn-primary {
background-image: linear-gradient(@link-color, darken(@link-color, 3%)); background-image: linear-gradient(@link-color, darken(@link-color, 3%));
@ -123,8 +137,8 @@ nav {
// Count bubble // Count bubble
.btn-count { .btn-count {
position: relative; position: relative;
margin-left: 6px; margin-left: (@padding-base / 2);
padding: ((@padding-base / 2) - 1px); padding: (@padding-base / 2) (@padding-base * .75);
background: #fff; background: #fff;
border: 1px solid @gray-light; border: 1px solid @gray-light;

View File

@ -3,46 +3,46 @@
// ========================================================================== // ==========================================================================
// Example players // Example players
.example-audio .player, .player {
.example-video .player {
margin: 0 auto @padding-base; margin: 0 auto @padding-base;
&-controls { &-controls {
border-radius: 0 0 @border-radius-base @border-radius-base; border-radius: 0 0 @border-radius-base @border-radius-base;
} }
} }
.example-audio .player { .player-audio {
max-width: @example-width-audio; max-width: @example-width-audio;
&-controls { .player-controls {
border-radius: @border-radius-base; border-radius: @border-radius-base;
} }
&-progress { .player-progress {
border-radius: @border-radius-base @border-radius-base 0 0; border-radius: @border-radius-base @border-radius-base 0 0;
overflow: hidden; overflow: hidden;
} }
} }
// Base styles .player-video,
.example-video .player { .player-youtube,
.player-vimeo {
max-width: @example-width-video; max-width: @example-width-video;
}
video, video,
iframe { .player-video-embed {
border-radius: @border-radius-base; border-radius: @border-radius-base;
} }
iframe { .player-video-embed {
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC); -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
} }
}
// Style full supported player // Style full supported player
.example-video .player-video, .player-video,
.example-video .player-youtube { .player-youtube,
.player-vimeo {
video, video,
iframe { .player-video-embed {
border-radius: @border-radius-base @border-radius-base 0 0; border-radius: @border-radius-base @border-radius-base 0 0;
} }
&-fullscreen, &.player-fullscreen,
&.fullscreen-active { &.fullscreen-active {
max-width: none; max-width: none;
@ -56,7 +56,3 @@
} }
} }
} }
.example-video .player-vimeo .player-video-embed {
border-radius: @border-radius-base @border-radius-base 0 0;
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}

View File

@ -0,0 +1,22 @@
// ==========================================================================
// Icons
// ==========================================================================
// Base size icon styles
.icon {
fill: currentColor;
width: @icon-size;
height: @icon-size;
vertical-align: -3px;
}
// Within elements
a svg,
button svg,
label svg {
pointer-events: none;
}
a .icon,
.btn .icon {
margin-right: (@padding-base / 2);
}

View File

@ -14,21 +14,14 @@
// Animation // Animation
@import "lib/animation.less"; @import "lib/animation.less";
// Base layout
@import "components/base.less";
// Type // Type
@import "lib/fontface.less"; @import "lib/fontface.less";
@import "components/type.less"; @import "components/type.less";
// Buttons // Components
@import "components/base.less";
@import "components/icons.less";
@import "components/buttons.less"; @import "components/buttons.less";
// Panels
@import "components/panels.less"; @import "components/panels.less";
// Error
@import "components/error.less"; @import "components/error.less";
// Examples
@import "components/examples.less"; @import "components/examples.less";

View File

@ -10,6 +10,11 @@
@gray-lighter: #dbe3e8; @gray-lighter: #dbe3e8;
@off-white: #f2f5f7; @off-white: #f2f5f7;
// Brands
@color-twitter: #4BAAF4;
@color-youtube: #cc181e;
@color-vimeo: #19b7ed;
// Base // Base
@body-background: @off-white; @body-background: @off-white;
@ -18,6 +23,9 @@
@padding-base: 20px; @padding-base: 20px;
@arrow-size: 8px; @arrow-size: 8px;
// Icons
@icon-size: 18px;
// Breakpoints // Breakpoints
@screen-sm: 480px; @screen-sm: 480px;
@screen-md: 768px; @screen-md: 768px;

12
docs/src/sprite/icon-github.svg Executable file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!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 fill-rule="evenodd" clip-rule="evenodd" d="M8,0.2c-4.4,0-8,3.6-8,8c0,3.5,2.3,6.5,5.5,7.6
C5.9,15.9,6,15.6,6,15.4c0-0.2,0-0.7,0-1.4C3.8,14.5,3.3,13,3.3,13c-0.4-0.9-0.9-1.2-0.9-1.2c-0.7-0.5,0.1-0.5,0.1-0.5
c0.8,0.1,1.2,0.8,1.2,0.8C4.4,13.4,5.6,13,6,12.8c0.1-0.5,0.3-0.9,0.5-1.1c-1.8-0.2-3.6-0.9-3.6-4c0-0.9,0.3-1.6,0.8-2.1
c-0.1-0.2-0.4-1,0.1-2.1c0,0,0.7-0.2,2.2,0.8c0.6-0.2,1.3-0.3,2-0.3c0.7,0,1.4,0.1,2,0.3c1.5-1,2.2-0.8,2.2-0.8
c0.4,1.1,0.2,1.9,0.1,2.1c0.5,0.6,0.8,1.3,0.8,2.1c0,3.1-1.9,3.7-3.7,3.9C9.7,12,10,12.5,10,13.2c0,1.1,0,1.9,0,2.2
c0,0.2,0.1,0.5,0.6,0.4c3.2-1.1,5.5-4.1,5.5-7.6C16,3.8,12.4,0.2,8,0.2z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!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">
<title>Twitter</title>
<path d="M16,3c-0.6,0.3-1.2,0.4-1.9,0.5c0.7-0.4,1.2-1,1.4-1.8c-0.6,0.4-1.3,0.6-2.1,0.8c-0.6-0.6-1.5-1-2.4-1
C9.3,1.5,7.8,3,7.8,4.8c0,0.3,0,0.5,0.1,0.7C5.2,5.4,2.7,4.1,1.1,2.1c-0.3,0.5-0.4,1-0.4,1.7c0,1.1,0.6,2.1,1.5,2.7
c-0.5,0-1-0.2-1.5-0.4c0,0,0,0,0,0c0,1.6,1.1,2.9,2.6,3.2C3,9.4,2.7,9.4,2.4,9.4c-0.2,0-0.4,0-0.6-0.1c0.4,1.3,1.6,2.3,3.1,2.3
c-1.1,0.9-2.5,1.4-4.1,1.4c-0.3,0-0.5,0-0.8,0c1.5,0.9,3.2,1.5,5,1.5c6,0,9.3-5,9.3-9.3c0-0.1,0-0.3,0-0.4C15,4.3,15.6,3.7,16,3z"/>
</svg>

After

Width:  |  Height:  |  Size: 981 B

9
docs/src/sprite/icon-vimeo.svg Executable file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!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="M16,4.3c-0.1,1.6-1.2,3.7-3.3,6.4c-2.2,2.8-4,4.2-5.5,4.2c-0.9,0-1.7-0.9-2.4-2.6C4,9.9,3.4,5,2,5
C1.9,5,1.5,5.3,0.8,5.8L0,4.8c0.8-0.7,3.5-3.4,4.7-3.5C5.9,1.2,6.7,2,7,3.8c0.3,2,0.8,6.1,1.8,6.1c0.9,0,2.5-3.4,2.6-4
c0.1-0.9-0.3-1.9-2.3-1.1c0.8-2.6,2.3-3.8,4.5-3.8C15.3,1.1,16.1,2.2,16,4.3z"/>
</svg>

After

Width:  |  Height:  |  Size: 779 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!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="M15.8,4.8c-0.2-1.3-0.8-2.2-2.2-2.4C11.4,2,8,2,8,2S4.6,2,2.4,2.4C1,2.6,0.3,3.5,0.2,4.8C0,6.1,0,8,0,8
s0,1.9,0.2,3.2c0.2,1.3,0.8,2.2,2.2,2.4C4.6,14,8,14,8,14s3.4,0,5.6-0.4c1.4-0.3,2-1.1,2.2-2.4C16,9.9,16,8,16,8S16,6.1,15.8,4.8z
M6,11V5l5,3L6,11z"/>
</svg>

After

Width:  |  Height:  |  Size: 739 B

View File

@ -43,7 +43,8 @@ paths = {
src: { src: {
less: path.join(root, "docs/src/less/**/*"), less: path.join(root, "docs/src/less/**/*"),
js: path.join(root, "docs/src/js/**/*"), js: path.join(root, "docs/src/js/**/*"),
templates: path.join(root, "docs/src/templates/*.html") templates: path.join(root, "docs/src/templates/*.html"),
sprite: path.join(root, "docs/src/sprite/*.svg")
}, },
// Output paths // Output paths
output: path.join(root, "docs/dist/"), output: path.join(root, "docs/dist/"),
@ -129,18 +130,18 @@ var build = {
})(key); })(key);
} }
}, },
sprite: function() { sprite: function(bundle) {
// Process Icons // Process Icons
gulp.task("sprite", function () { gulp.task("sprite-" + bundle, function () {
return gulp return gulp
.src(paths.plyr.src.sprite) .src(paths[bundle].src.sprite)
.pipe(svgmin({ .pipe(svgmin({
plugins: [{ plugins: [{
removeDesc: true removeDesc: true
}] }]
})) }))
.pipe(svgstore()) .pipe(svgstore())
.pipe(gulp.dest(paths.plyr.output)); .pipe(gulp.dest(paths[bundle].output));
}); });
}, },
templates: function() { templates: function() {
@ -163,12 +164,13 @@ var build = {
build.js(bundles.plyr.js, "plyr"); build.js(bundles.plyr.js, "plyr");
build.less(bundles.plyr.less, "plyr"); build.less(bundles.plyr.less, "plyr");
build.sass(bundles.plyr.sass, "plyr"); build.sass(bundles.plyr.sass, "plyr");
build.sprite(); build.sprite("plyr");
// Docs files // Docs files
build.templates(); build.templates();
build.less(bundles.docs.less, "docs"); build.less(bundles.docs.less, "docs");
build.js(bundles.docs.js, "docs"); build.js(bundles.docs.js, "docs");
build.sprite("docs");
// Build all JS (inc. templates) // Build all JS (inc. templates)
gulp.task("js", function(){ gulp.task("js", function(){
@ -185,17 +187,18 @@ gulp.task("watch", function () {
// Plyr core // Plyr core
gulp.watch(paths.plyr.src.js, tasks.js); gulp.watch(paths.plyr.src.js, tasks.js);
gulp.watch(paths.plyr.src.less, tasks.less); gulp.watch(paths.plyr.src.less, tasks.less);
gulp.watch(paths.plyr.src.sprite, ["sprite"]); gulp.watch(paths.plyr.src.sprite, ["sprite-plyr"]);
// Docs // Docs
gulp.watch(paths.docs.src.js, tasks.js); gulp.watch(paths.docs.src.js, tasks.js);
gulp.watch(paths.docs.src.less, tasks.less); gulp.watch(paths.docs.src.less, tasks.less);
gulp.watch(paths.docs.src.templates, ["js"]); gulp.watch(paths.docs.src.templates, ["js"]);
gulp.watch(paths.docs.src.sprite, ["sprite-docs"]);
}); });
// Default gulp task // Default gulp task
gulp.task("default", function(){ gulp.task("default", function(){
run("templates", tasks.js, tasks.less, "sprite", "watch"); run("templates", tasks.js, tasks.less, "sprite-plyr", "sprite-docs", "watch");
}); });
// Publish a version to CDN and docs // Publish a version to CDN and docs

View File

@ -1,6 +1,6 @@
// ========================================================================== // ==========================================================================
// Plyr // Plyr
// plyr.js v1.3.5 // plyr.js v1.4.0
// https://github.com/selz/plyr // https://github.com/selz/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
@ -18,6 +18,8 @@
var defaults = { var defaults = {
enabled: true, enabled: true,
debug: false, debug: false,
autoplay: false,
loop: false,
seekTime: 10, seekTime: 10,
volume: 5, volume: 5,
click: true, click: true,
@ -97,6 +99,10 @@
toggleMute: 'Toggle Mute', toggleMute: 'Toggle Mute',
toggleCaptions: 'Toggle Captions', toggleCaptions: 'Toggle Captions',
toggleFullscreen: 'Toggle Fullscreen' toggleFullscreen: 'Toggle Fullscreen'
},
types: {
embed: ['youtube','vimeo'],
html5: ['video', 'audio']
} }
}; };
@ -427,10 +433,27 @@
// Set attributes // Set attributes
function _setAttributes(element, attributes) { function _setAttributes(element, attributes) {
for (var key in attributes) { for (var key in attributes) {
element.setAttribute(key, attributes[key]); element.setAttribute(key, (typeof attributes[key] === 'boolean' && attributes[key]) ? '' : attributes[key]);
} }
} }
// Insert a HTML element
function _insertElement(type, parent, attributes) {
// Create a new <element>
var element = document.createElement(type);
// Set all passed attributes
_setAttributes(element, attributes);
// Inject the new element
_prependChild(parent, element);
}
// Get a classname from selector
function _getClassname(selector) {
return selector.replace('.', '');
}
// Toggle class on an element // Toggle class on an element
function _toggleClass(element, name, state) { function _toggleClass(element, name, state) {
if (element) { if (element) {
@ -632,6 +655,11 @@
// https://twitter.com/Sam_Potts/status/573715746506731521 // https://twitter.com/Sam_Potts/status/573715746506731521
time = typeof time === 'number' ? time : player.media.currentTime; time = typeof time === 'number' ? time : player.media.currentTime;
// If there's no subs available, bail
if(!player.captions[player.subcount]) {
return;
}
while (_timecodeMax(player.captions[player.subcount][0]) < time.toFixed(1)) { while (_timecodeMax(player.captions[player.subcount][0]) < time.toFixed(1)) {
player.subcount++; player.subcount++;
if (player.subcount > player.captions.length-1) { if (player.subcount > player.captions.length-1) {
@ -847,7 +875,7 @@
_toggleClass(player.container, config.classes.type.replace('{0}', player.type), true); _toggleClass(player.container, config.classes.type.replace('{0}', player.type), true);
// If there's no autoplay attribute, assume the video is stopped and add state class // If there's no autoplay attribute, assume the video is stopped and add state class
_toggleClass(player.container, config.classes.stopped, (player.media.getAttribute('autoplay') === null)); _toggleClass(player.container, config.classes.stopped, config.autoplay);
// Add iOS class // Add iOS class
if (player.browser.ios) { if (player.browser.ios) {
@ -868,62 +896,67 @@
} }
} }
// YouTube // Embeds
if (player.type == 'youtube') { if (_inArray(config.types.embed, player.type)) {
_setupEmbed(player.media.getAttribute('data-video-id'), 0); _setupEmbed(player.embedId, player.type);
}
// Vimeo // Clean up
if (player.type == 'vimeo') { player.embedId = null;
_setupEmbed(player.media.getAttribute('data-video-id'), 1);
} }
else {
// Autoplay // Autoplay
if (player.media.getAttribute('autoplay') !== null) { if (config.autoplay) {
_play(); _play();
} }
} }
}
// Setup YouTube/Vimeo // Setup YouTube/Vimeo
function _setupEmbed(videoId, type) { function _setupEmbed(videoId) {
var container = document.createElement('div'), var container = document.createElement('div'),
providers = ['youtube', 'vimeo'], id = player.type + '-' + Math.floor(Math.random() * (10000));
id = providers[type] + '-' + Math.floor(Math.random() * (10000));
// Remove old containers // Remove old containers
var containers = _getElements('[id^="' + providers[type] + '-"]'); var containers = _getElements('[id^="' + player.type + '-"]');
for (var i = containers.length - 1; i >= 0; i--) { for (var i = containers.length - 1; i >= 0; i--) {
_remove(containers[i]); _remove(containers[i]);
} }
// Set ID
container.setAttribute('id', id);
// Add embed class for responsive // Add embed class for responsive
_toggleClass(player.media, config.classes.videoWrapper, true); _toggleClass(player.media, config.classes.videoWrapper, true);
_toggleClass(player.media, config.classes.embedWrapper, true); _toggleClass(player.media, config.classes.embedWrapper, true);
// YouTube // YouTube
if (type === 0) { if (player.type === 'youtube') {
// Create the YouTube container // Create the YouTube container
container.setAttribute('id', id);
player.media.appendChild(container); player.media.appendChild(container);
// Setup API // Setup API
if (typeof YT === 'object') { if (typeof YT === 'object') {
_YouTubeReady(videoId, container); _youTubeReady(videoId, container);
} }
else { else {
// Load the API // Load the API
_injectScript('https://www.youtube.com/iframe_api'); _injectScript('https://www.youtube.com/iframe_api');
// Setup callback for the API // Setup callback for the API
window.onYouTubeIframeAPIReady = function () { _YouTubeReady(videoId, container); }; window.onYouTubeIframeAPIReady = function () { _youTubeReady(videoId, container); };
} }
} }
// Vimeo // Vimeo
else if (type === 1) { else if (player.type === 'vimeo') {
// Inject the iframe // Inject the iframe
var iframe = document.createElement('iframe'); var iframe = document.createElement('iframe');
iframe.src = 'https://player.vimeo.com/video/' + videoId + '?player_id=' + id + '&api=1&badge=0&byline=0&portrait=0&title=0';
// Watch for iframe load
iframe.loaded = false;
_on(iframe, 'load', function() { iframe.loaded = true; });
_setAttributes(iframe, { _setAttributes(iframe, {
'src': 'https://player.vimeo.com/video/' + videoId + '?player_id=' + id + '&api=1&badge=0&byline=0&portrait=0&title=0',
'id': id, 'id': id,
'webkitallowfullscreen': '', 'webkitallowfullscreen': '',
'mozallowfullscreen': '', 'mozallowfullscreen': '',
@ -935,27 +968,41 @@
// Setup API // Setup API
if (typeof Froogaloop === 'function') { if (typeof Froogaloop === 'function') {
_VimeoReady(id, iframe); _on(iframe, 'load', _vimeoReady);
} }
else { else {
// Load the API // Load the API
_injectScript('https://f.vimeocdn.com/js/froogaloop2.min.js'); _injectScript('https://rawgit.com/vimeo/player-api/master/javascript/froogaloop.js');
// Wait for fragaloop load // Wait for fragaloop load
var timer = window.setInterval(function() { var timer = window.setInterval(function() {
if('$f' in window) { if('$f' in window && iframe.loaded) {
window.clearInterval(timer); window.clearInterval(timer);
_VimeoReady(id, iframe);
_vimeoReady.call(iframe);
} }
}, 50); }, 50);
} }
} }
} }
// Handle YouTube API ready // When embeds are ready
function _YouTubeReady(videoId, container) { function _embedReady() {
_log('YouTube API Ready'); // Inject and update UI
if (player.supported.full) {
// Only setup controls once
if (!player.container.querySelectorAll(config.selectors.controls).length) {
_setupInterface();
}
}
// Set the volume
_setVolume();
_updateVolume();
}
// Handle YouTube API ready
function _youTubeReady(videoId, container) {
// Setup timers object // Setup timers object
// We have to poll YouTube for updates // We have to poll YouTube for updates
if (!('timer' in player)) { if (!('timer' in player)) {
@ -967,7 +1014,7 @@
player.embed = new YT.Player(container.id, { player.embed = new YT.Player(container.id, {
videoId: videoId, videoId: videoId,
playerVars: { playerVars: {
autoplay: 0, autoplay: (config.autoplay ? 1 : 0),
controls: (player.supported.full ? 0 : 1), controls: (player.supported.full ? 0 : 1),
rel: 0, rel: 0,
showinfo: 0, showinfo: 0,
@ -988,7 +1035,7 @@
player.media.pause = function() { instance.pauseVideo(); }; player.media.pause = function() { instance.pauseVideo(); };
player.media.stop = function() { instance.stopVideo(); }; player.media.stop = function() { instance.stopVideo(); };
player.media.duration = instance.getDuration(); player.media.duration = instance.getDuration();
player.media.paused = true; player.media.paused = !config.autoplay;
player.media.currentTime = instance.getCurrentTime(); player.media.currentTime = instance.getCurrentTime();
player.media.muted = instance.isMuted(); player.media.muted = instance.isMuted();
@ -1012,17 +1059,13 @@
} }
}, 200); }, 200);
if (player.supported.full) { // Update UI
// Only setup controls once _embedReady();
if (!player.container.querySelectorAll(config.selectors.controls).length) {
_setupInterface();
}
// Display duration if available // Display duration if available
if (config.displayDuration) { if (config.displayDuration) {
_displayDuration(); _displayDuration();
} }
}
}, },
'onStateChange': function(event) { 'onStateChange': function(event) {
// Get the instance // Get the instance
@ -1069,24 +1112,22 @@
} }
// Vimeo ready // Vimeo ready
function _VimeoReady(id, iframe) { function _vimeoReady() {
player.embed = $f(iframe); /* jshint validthis: true */
// Get the frame with fragaloop lib
player.embed = $f(this);
// Setup on ready
player.embed.addEvent('ready', function() { player.embed.addEvent('ready', function() {
// Create a faux HTML5 API using the Vimeo API // Create a faux HTML5 API using the Vimeo API
player.media.play = function() { player.embed.api('play'); }; player.media.play = function() { player.embed.api('play'); };
player.media.pause = function() { player.embed.api('pause'); }; player.media.pause = function() { player.embed.api('pause'); };
player.media.stop = function() { player.embed.api('stop') }; player.media.stop = function() { player.embed.api('stop') };
player.media.paused = true; player.media.paused = !config.autoplay;
player.media.currentTime = 0; player.media.currentTime = 0;
player.media.muted = false;
if (player.supported.full) { // Update UI
// Only setup controls once _embedReady();
if (!player.container.querySelectorAll(config.selectors.controls).length) {
_setupInterface();
}
}
player.embed.api('getCurrentTime', function (value) { player.embed.api('getCurrentTime', function (value) {
player.media.currentTime = value; player.media.currentTime = value;
@ -1105,28 +1146,24 @@
}); });
player.embed.addEvent('play', function() { player.embed.addEvent('play', function() {
console.log('play');
player.media.paused = false; player.media.paused = false;
_triggerEvent(player.media, 'play'); _triggerEvent(player.media, 'play');
}); });
player.embed.addEvent('pause', function() { player.embed.addEvent('pause', function() {
console.log('pause');
player.media.paused = true; player.media.paused = true;
_triggerEvent(player.media, 'pause'); _triggerEvent(player.media, 'pause');
}); });
player.embed.addEvent('playProgress', function(data) { player.embed.addEvent('playProgress', function(data) {
// Set the current time
player.media.currentTime = data.seconds; player.media.currentTime = data.seconds;
// Trigger timeupdate
_triggerEvent(player.media, 'timeupdate'); _triggerEvent(player.media, 'timeupdate');
}); });
player.embed.addEvent('loadProgress', function(data) { player.embed.addEvent('loadProgress', function(data) {
// Get loaded %
player.media.buffered = data.percent; player.media.buffered = data.percent;
// Trigger progress
_triggerEvent(player.media, 'progress'); _triggerEvent(player.media, 'progress');
}); });
@ -1134,6 +1171,14 @@
player.media.paused = true; player.media.paused = true;
_triggerEvent(player.media, 'ended'); _triggerEvent(player.media, 'ended');
}); });
/*// Always seek to 0
player.embed.api('seekTo', 0);
// Prevent autoplay if needed (seek will play)
if (!config.autoplay) {
player.embed.api('pause');
}*/
}); });
} }
@ -1141,7 +1186,9 @@
function _setupCaptions() { function _setupCaptions() {
if (player.type === 'video') { if (player.type === 'video') {
// Inject the container // Inject the container
player.videoContainer.insertAdjacentHTML('afterbegin', '<div class="' + config.selectors.captions.replace('.', '') + '"><span></span></div>'); if(!_getElement(config.selectors.captions)) {
player.videoContainer.insertAdjacentHTML('afterbegin', '<div class="' + _getClassname(config.selectors.captions) + '"><span></span></div>');
}
// Cache selector // Cache selector
player.captionsContainer = _getElement(config.selectors.captions).querySelector('span'); player.captionsContainer = _getElement(config.selectors.captions).querySelector('span');
@ -1508,6 +1555,28 @@
} }
} }
// Mute
function _toggleMute(muted) {
// If the method is called without parameter, toggle based on current value
if (typeof muted !== 'boolean') {
muted = !player.media.muted;
}
// Set button state
_toggleState(player.buttons.mute, muted);
// Set mute on the player
player.media.muted = muted;
// YouTube
if (player.type === 'youtube') {
player.embed[player.media.muted ? 'mute' : 'unMute']();
// Trigger timeupdate
_triggerEvent(player.media, 'volumechange');
}
}
// Set volume // Set volume
function _setVolume(volume) { function _setVolume(volume) {
// Use default if no value specified // Use default if no value specified
@ -1532,6 +1601,9 @@
// Set the player volume // Set the player volume
player.media.volume = parseFloat(volume / 10); player.media.volume = parseFloat(volume / 10);
// Store in config
config.volume = volume;
// YouTube // YouTube
if (player.type === 'youtube') { if (player.type === 'youtube') {
player.embed.setVolume(player.media.volume * 100); player.embed.setVolume(player.media.volume * 100);
@ -1553,28 +1625,6 @@
} }
} }
// Mute
function _toggleMute(muted) {
// If the method is called without parameter, toggle based on current value
if (typeof muted !== 'boolean') {
muted = !player.media.muted;
}
// Set button state
_toggleState(player.buttons.mute, muted);
// Set mute on the player
player.media.muted = muted;
// YouTube
if (player.type === 'youtube') {
player.embed[player.media.muted ? 'mute' : 'unMute']();
// Trigger timeupdate
_triggerEvent(player.media, 'volumechange');
}
}
// Update volume UI and storage // Update volume UI and storage
function _updateVolume() { function _updateVolume() {
// Get the current volume // Get the current volume
@ -1696,6 +1746,11 @@
return; return;
} }
// Fallback to 0
if(isNaN(time)) {
time = 0;
}
player.secs = parseInt(time % 60); player.secs = parseInt(time % 60);
player.mins = parseInt((time / 60) % 60); player.mins = parseInt((time / 60) % 60);
player.hours = parseInt(((time / 60) / 60) % 60); player.hours = parseInt(((time / 60) / 60) % 60);
@ -1736,7 +1791,7 @@
} }
// Remove <source> children and src attribute // Remove <source> children and src attribute
function _removeSources() { /*function _removeSources() {
// Find child <source> elements // Find child <source> elements
var sources = player.media.querySelectorAll('source'); var sources = player.media.querySelectorAll('source');
@ -1747,72 +1802,130 @@
// Remove src attribute // Remove src attribute
player.media.removeAttribute('src'); player.media.removeAttribute('src');
}*/
// Add a source element
function _addSource(attributes) {
_insertElement('source', player.media, attributes);
} }
// Inject a source // Add a source element
function _addSource(attributes) { function _addTracks(tracks) {
if (attributes.src) { for (var i = tracks.length - 1; i >= 0; i--) {
// Create a new <source> _insertElement('track', player.media, tracks[i]);
var element = document.createElement('source'); }
}
// Set all passed attributes // Add sources to HTML5 media
_setAttributes(element, attributes); function _addSources(sources) {
// Set new sources
// Inject the new source if(typeof sources === 'string') {
_prependChild(player.media, element); _addSource({ src: sources });
}
else if(sources.constructor === Array) {
for (var i = sources.length - 1; i >= 0; i--) {
_addSource(sources[i]);
}
} }
} }
// Update source // Update source
// Sources are not checked for support so be careful // Sources are not checked for support so be careful
function _parseSource(sources) { function _updateSource(source) {
// Embed if(typeof source === 'undefined') {
if('embed' in player && typeof sources === 'string') {
// YouTube
if (player.type === 'youtube') {
// Destroy YouTube instance
player.embed.destroy();
// Re-setup YouTube
_setupEmbed(sources, 0);
}
// Vimeo
if(player.type === 'vimeo') {
_setupEmbed(sources, 1);
}
// Reset time display
_timeUpdate();
// Bail
return; return;
} }
// Pause playback (webkit freaks out) // Pause playback
_pause(); _pause();
// Restart // Clean up YouTube stuff
_seek(); if(player.type === 'youtube') {
// Destroy the embed instance
player.embed.destroy();
// Remove current sources // Clear timer
_removeSources(); window.clearInterval(player.timer.buffering);
window.clearInterval(player.timer.playing);
// If a single source is passed }
// .source('path/to/video.mp4') else if (player.type === 'video') {
if (typeof sources === 'string') { // Remove video wrapper
_addSource({ src: sources }); _remove(player.videoContainer);
} }
// An array of source objects // Remove the old media
// Check if a source exists, use that or set the 'src' attribute? _remove(player.media);
// .source([{ src: 'path/to/video.mp4', type: 'video/mp4' },{ src: 'path/to/video.webm', type: 'video/webm' }])
else if (sources.constructor === Array) { // Set the new type
for (var index in sources) { if('type' in source && source.type !== player.type) {
_addSource(sources[index]); player.type = source.type;
}
// Create new markup
switch(player.type) {
case 'video':
player.media = document.createElement('video');
break;
case 'audio':
player.media = document.createElement('audio');
break;
case 'youtube':
case 'vimeo':
player.media = document.createElement('div');
player.embedId = source.sources;
break;
}
// Inject the new element
_prependChild(player.container, player.media);
// Set attributes for audio video
if(_inArray(config.types.html5, player.type)) {
if(config.crossorigin) {
player.media.setAttribute('crossorigin', '');
}
if (config.autoplay) {
player.media.setAttribute('autoplay', '');
}
if ('poster' in source) {
player.media.setAttribute('poster', source.poster);
}
if (config.loop) {
player.media.setAttribute('loop', '');
} }
} }
// Classname reset
player.container.className = _getClassname(config.selectors.container);
// Autoplay the new source?
config.autoplay = (source.autoplay || config.autoplay);
// Set media id for embeds
if(_inArray(config.types.embed, player.type)) {
player.embedId = source.sources;
}
// Set new sources and tracks for html5
if(_inArray(config.types.html5, player.type)) {
_addSources(source.sources);
}
// Set up from scratch
_setupMedia();
// Trigger media updated
_mediaUpdated();
// HTML5 stuff
if(_inArray(config.types.html5, player.type)) {
// Set volume
_setVolume();
_updateVolume();
// UI updates
if(player.supported.full) { if(player.supported.full) {
// Reset time display // Reset time display
_timeUpdate(); _timeUpdate();
@ -1821,14 +1934,23 @@
_checkPlaying(); _checkPlaying();
} }
// Re-load sources // Setup captions
if('tracks' in source) {
_addTracks(source.tracks);
// Captions
_setupCaptions();
}
// Load HTML5 sources
player.media.load(); player.media.load();
// Play if autoplay attribute is present // Play if autoplay attribute is present
if (player.media.getAttribute('autoplay') !== null) { if (config.autoplay) {
_play(); _play();
} }
} }
}
// Update poster // Update poster
function _updatePoster(source) { function _updatePoster(source) {
@ -1974,7 +2096,7 @@
} }
// Reset container classname // Reset container classname
player.container.setAttribute('class', config.selectors.container.replace('.', '')); player.container.setAttribute('class', _getClassname(config.selectors.container));
// Remove init flag // Remove init flag
player.init = false; player.init = false;
@ -2022,13 +2144,22 @@
// Get the media element // Get the media element
player.media = player.container.querySelectorAll('audio, video, div')[0]; player.media = player.container.querySelectorAll('audio, video, div')[0];
// Set media type // Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube
var tagName = player.media.tagName.toLowerCase(); var tagName = player.media.tagName.toLowerCase();
if (tagName === 'div') { if (tagName === 'div') {
player.type = player.media.getAttribute('data-type'); player.type = player.media.getAttribute('data-type');
player.embedId = player.media.getAttribute('data-video-id');
// Clean up
player.media.removeAttribute('data-type');
player.media.removeAttribute('data-video-id');
} }
else { else {
player.type = tagName; player.type = tagName;
config.crossorigin = (player.media.getAttribute('crossorigin') !== null);
config.autoplay = (config.autoplay || (player.media.getAttribute('autoplay') !== null));
config.loop = (config.loop || (player.media.getAttribute('loop') !== null));
} }
// Check for full support // Check for full support
@ -2084,10 +2215,15 @@
// Captions // Captions
_setupCaptions(); _setupCaptions();
// Media updated
_mediaUpdated();
// Set volume // Set volume
_setVolume(); _setVolume();
_updateVolume(); _updateVolume();
}
function _mediaUpdated() {
// Setup fullscreen // Setup fullscreen
_setupFullscreen(); _setupFullscreen();
@ -2111,7 +2247,7 @@
rewind: _rewind, rewind: _rewind,
forward: _forward, forward: _forward,
seek: _seek, seek: _seek,
source: _parseSource, source: _updateSource,
poster: _updatePoster, poster: _updatePoster,
setVolume: _setVolume, setVolume: _setVolume,
togglePlay: _togglePlay, togglePlay: _togglePlay,

View File

@ -39,9 +39,9 @@
@tooltip-radius: 3px; @tooltip-radius: 3px;
// Progress // Progress
@progress-bg: rgba(red(@gray), green(@gray), blue(@gray), .2); @progress-bg: fade(@gray, 20%);
@progress-playing-bg: @blue; @progress-playing-bg: @blue;
@progress-buffered-bg: rgba(red(@gray), green(@gray), blue(@gray), .25); @progress-buffered-bg: fade(@gray, 25%);
@progress-loading-size: 40px; @progress-loading-size: 40px;
@progress-loading-bg: rgba(0,0,0, .15); @progress-loading-bg: rgba(0,0,0, .15);
@ -59,14 +59,12 @@
// Animation // Animation
// --------------------------------------- // ---------------------------------------
@keyframes progress { @keyframes progress {
to { background-position: @progress-loading-size 0; } to { background-position: @progress-loading-size 0; }
} }
// Mixins // Mixins
// ------------------------------- // -------------------------------
// Contrast // Contrast
.contrast-control-color(@color: "") when (lightness(@color) >= 65%) { .contrast-control-color(@color: "") when (lightness(@color) >= 65%) {
@control-color: @gray-light; @control-color: @gray-light;
@ -176,6 +174,7 @@
padding-bottom: 56.25%; /* 16:9 */ padding-bottom: 56.25%; /* 16:9 */
height: 0; height: 0;
overflow: hidden; overflow: hidden;
background: #000;
iframe { iframe {
position: absolute; position: absolute;

View File

@ -70,7 +70,6 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
// Animation // Animation
// --------------------------------------- // ---------------------------------------
@keyframes progress { @keyframes progress {
to { background-position: $progress-loading-size 0; } to { background-position: $progress-loading-size 0; }
} }
@ -178,6 +177,8 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
&-video-embed { &-video-embed {
padding-bottom: 56.25%; /* 16:9 */ padding-bottom: 56.25%; /* 16:9 */
height: 0; height: 0;
overflow: hidden;
background: #000;
iframe { iframe {
position: absolute; position: absolute;
@ -187,6 +188,13 @@ $bp-captions-large: 768px !default; // When captions jump to the larger
height: 100%; height: 100%;
border: 0; border: 0;
} }
// Vimeo hack
> div {
position: relative;
padding-bottom: 200%;
transform: translateY(-35.95%);
}
} }
// Captions // Captions