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,
"couch" : false,
"wsh" : true, // Windows Scripting Host.
"jquery" : true,
"predef" : [ "jQuery", "$" ],
"jquery" : false,
// Development.
"debug" : false, // Allow debugger statements e.g. browser breakpoints.
@ -51,6 +50,6 @@
"plusplus" : false, // Prohibit use of `++` & `--`.
"sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
"trailing" : true, // Prohibit trailing whitespaces.
"white" : false, // Check against strict whitespace and indentation rules.
"indent" : 2 // Specify indentation spacing
"white" : true, // Check against strict whitespace and indentation rules.
"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>
<header>
<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>
<ul>
<li>
<a href="https://github.com/selz/plyr" target="_blank" class="btn btn-primary">Download on GitHub</a>
<span class="btn-count js-stargazers-count">&hellip;</span>
<a href="https://github.com/selz/plyr" target="_blank" class="btn btn-primary" data-shr-network="github">
<svg class="icon"><use xlink:href="#icon-github"/></svg>Get it on GitHub
</a>
</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>
<span class="btn-count js-tweet-count">&hellip;</span>
<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">
<svg class="icon"><use xlink:href="#icon-twitter"/></svg>Tweet
</a>
</li>
</ul>
</nav>
@ -42,7 +44,7 @@
<div class="panels">
<section class="panel example-video active" id="video">
<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 -->
<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">
@ -66,11 +68,11 @@
<div class="player">
<audio controls>
<!-- Audio files -->
<source src="//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.mp3" type="audio/mp3">
<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 -->
<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>
</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>
@ -81,28 +83,35 @@
<!-- Load SVG defs -->
<!-- You should bundle all SVG/Icons into one file using a build tool such as gulp and svg store -->
<script>
(function(d, u){
function loadSprite(d, u) {
var a = new XMLHttpRequest(),
b = d.body;
b = document.body;
// Check for CORS support
// If you're loading from same domain, you can remove the if statement
// If proper CORS supported
if("withCredentials" in a) {
a.open("GET", u, true);
a.send();
a.onload = function(){
var c = d.createElement("div");
var c = document.createElement("div");
c.setAttribute("hidden", "");
c.innerHTML = a.responseText;
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>
<!-- Plyr core 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 -->
<script src="https://cdn.plyr.io/1.3.5/docs.js"></script>
</body>

View File

@ -2,182 +2,124 @@
// Docs example
// ==========================================================================
/*global plyr, templates */
/*global plyr, shr, templates */
// Setup the player
plyr.setup({
debug: true,
volume: 9,
title: "Video demo",
title: 'Video demo',
html: templates.controls.render({}),
tooltips: true,
captions: {
defaultActive: true
},
onSetup: function() {
if(!("media" in this)) {
if(!('media' in this)) {
return;
}
var player = this,
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) {
toggle.addEventListener("click", player.toggleFullscreen, false);
if(type === 'video' && toggle) {
toggle.addEventListener('click', player.toggleFullscreen, false);
}
}
});
// Setup shr
shr.setup({
count: {
classname: 'btn-count'
}
});
// General functions
(function() {
// Popup
function popup(event) {
// Prevent the link opening
if(event.target.nodeName.toLowerCase() == "a") {
if(event.preventDefault) {
event.preventDefault();
}
else {
event.returnValue = false;
}
var buttons = document.querySelectorAll('[data-source]');
// Bind to each button
for (var i = buttons.length - 1; i >= 0; i--) {
buttons[i].addEventListener('click', newSource);
}
var link = event.target,
url = link.href,
width = link.getAttribute("data-window-width") || 600,
height = link.getAttribute("data-window-height") || 600,
name = link.getAttribute("data-window-name") || "popup";
// Set a new source
function newSource() {
var trigger = this,
type = trigger.getAttribute('data-source'),
player = document.querySelector('.player').plyr;
// If window exists, just focus it
if(window["window-"+name] && !window["window-"+name].closed) {
window["window-"+name].focus();
}
else {
// Get position
var left = window.screenLeft !== undefined ? window.screenLeft : screen.left;
var top = window.screenTop !== undefined ? window.screenTop : screen.top;
// Open in the centre of the screen
var x = (screen.width / 2) - (width / 2) + left,
y = (screen.height / 2) - (height / 2) + top;
// Open that window
window["window-"+name] = window.open(url, name, "top=" + y +",left="+ x +",width=" + width + ",height=" + height);
// Focus new window
window["window-"+name].focus();
}
}
// 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;
}
switch(type) {
case 'video':
player.source({
type: 'video',
sources: [{
src: 'https://cdn.selz.com/plyr/1.0/movie.mp4',
type: 'video/mp4'
},
{
src: 'https://cdn.selz.com/plyr/1.0/movie.webm',
type: 'video/webm'
}],
poster: 'https://cdn.selz.com/plyr/1.0/poster.jpg',
tracks: [{
kind: 'captions',
label: 'English',
srclang:'en',
src: 'https://cdn.selz.com/plyr/1.0/example_captions_en.vtt',
default: true
}]
});
}
break;
// Get tweet count
if(storageSupported && "tweets" in window.sessionStorage) {
displayCount(selectors.twitter, window.sessionStorage.tweets);
}
else {
getJSONP("https://cdn.api.twitter.com/1/urls/count.json?url=plyr.io", function (json) {
if (json && typeof json.count !== "undefined") {
// Update UI
displayCount(selectors.twitter, json.count);
// Store in session storage
window.sessionStorage.tweets = json.count;
}
case 'audio':
player.source({
type: 'audio',
sources: [{
src: 'https://cdn.selz.com/plyr/1.0/logistics-96-sample.mp3',
type: 'audio/mp3'
},
{
src: 'https://cdn.selz.com/plyr/1.0/logistics-96-sample.ogg',
type: 'audio/ogg'
}]
});
break;
case 'youtube':
player.source({
type: 'youtube',
sources: 'iicnVez5U7M'
});
break;
case 'vimeo':
player.source({
type: 'vimeo',
sources: '125220818'
});
break;
}
// Tabs
var tabs = document.querySelectorAll(".nav-panel a"),
panels = document.querySelectorAll(".panels > .panel"),
activeClass = "active";
for (var i = tabs.length - 1; i >= 0; i--) {
tabs[i].addEventListener("click", togglePanel);
for (var x = buttons.length - 1; x >= 0; x--) {
buttons[x].classList.remove('active');
}
function togglePanel(event) {
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);
event.target.classList.add('active');
}
})();
// Google analytics
// 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(){
(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)
})(window,document,"script","//www.google-analytics.com/analytics.js","ga");
ga("create", "UA-40881672-11", "auto");
ga("send", "pageview");
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-40881672-11', 'auto');
ga('send', 'pageview');
}

View File

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

View File

@ -3,46 +3,46 @@
// ==========================================================================
// Example players
.example-audio .player,
.example-video .player {
.player {
margin: 0 auto @padding-base;
&-controls {
border-radius: 0 0 @border-radius-base @border-radius-base;
}
}
.example-audio .player {
.player-audio {
max-width: @example-width-audio;
&-controls {
.player-controls {
border-radius: @border-radius-base;
}
&-progress {
.player-progress {
border-radius: @border-radius-base @border-radius-base 0 0;
overflow: hidden;
}
}
// Base styles
.example-video .player {
.player-video,
.player-youtube,
.player-vimeo {
max-width: @example-width-video;
}
video,
iframe {
.player-video-embed {
border-radius: @border-radius-base;
}
iframe {
.player-video-embed {
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
}
// Style full supported player
.example-video .player-video,
.example-video .player-youtube {
.player-video,
.player-youtube,
.player-vimeo {
video,
iframe {
.player-video-embed {
border-radius: @border-radius-base @border-radius-base 0 0;
}
&-fullscreen,
&.player-fullscreen,
&.fullscreen-active {
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
@import "lib/animation.less";
// Base layout
@import "components/base.less";
// Type
@import "lib/fontface.less";
@import "components/type.less";
// Buttons
// Components
@import "components/base.less";
@import "components/icons.less";
@import "components/buttons.less";
// Panels
@import "components/panels.less";
// Error
@import "components/error.less";
// Examples
@import "components/examples.less";

View File

@ -10,6 +10,11 @@
@gray-lighter: #dbe3e8;
@off-white: #f2f5f7;
// Brands
@color-twitter: #4BAAF4;
@color-youtube: #cc181e;
@color-vimeo: #19b7ed;
// Base
@body-background: @off-white;
@ -18,6 +23,9 @@
@padding-base: 20px;
@arrow-size: 8px;
// Icons
@icon-size: 18px;
// Breakpoints
@screen-sm: 480px;
@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: {
less: path.join(root, "docs/src/less/**/*"),
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: path.join(root, "docs/dist/"),
@ -129,18 +130,18 @@ var build = {
})(key);
}
},
sprite: function() {
sprite: function(bundle) {
// Process Icons
gulp.task("sprite", function () {
gulp.task("sprite-" + bundle, function () {
return gulp
.src(paths.plyr.src.sprite)
.src(paths[bundle].src.sprite)
.pipe(svgmin({
plugins: [{
removeDesc: true
}]
}))
.pipe(svgstore())
.pipe(gulp.dest(paths.plyr.output));
.pipe(gulp.dest(paths[bundle].output));
});
},
templates: function() {
@ -163,12 +164,13 @@ var build = {
build.js(bundles.plyr.js, "plyr");
build.less(bundles.plyr.less, "plyr");
build.sass(bundles.plyr.sass, "plyr");
build.sprite();
build.sprite("plyr");
// Docs files
build.templates();
build.less(bundles.docs.less, "docs");
build.js(bundles.docs.js, "docs");
build.sprite("docs");
// Build all JS (inc. templates)
gulp.task("js", function(){
@ -185,17 +187,18 @@ gulp.task("watch", function () {
// Plyr core
gulp.watch(paths.plyr.src.js, tasks.js);
gulp.watch(paths.plyr.src.less, tasks.less);
gulp.watch(paths.plyr.src.sprite, ["sprite"]);
gulp.watch(paths.plyr.src.sprite, ["sprite-plyr"]);
// Docs
gulp.watch(paths.docs.src.js, tasks.js);
gulp.watch(paths.docs.src.less, tasks.less);
gulp.watch(paths.docs.src.templates, ["js"]);
gulp.watch(paths.docs.src.sprite, ["sprite-docs"]);
});
// Default gulp task
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

View File

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

View File

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

View File

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