Setup improvements, player -> plyr, docs (WIP)

This commit is contained in:
Sam Potts 2015-10-05 16:33:26 +11:00
parent 262c9f9e13
commit b164a2f3fb
12 changed files with 579 additions and 495 deletions

View File

@ -16,9 +16,7 @@
},
"js": {
"docs.js": [
"docs/src/js/lib/hogan-3.0.2.mustache.js",
"docs/src/js/lib/classlist.js",
"docs/dist/templates.js",
"docs/src/js/docs.js"
]
}

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
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

View File

@ -1,2 +0,0 @@
var templates = {};
templates['controls'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"player-controls\">");t.b("\n" + i);t.b(" <div class=\"player-progress\">");t.b("\n" + i);t.b(" <label for=\"seek{id}\" class=\"sr-only\">Seek</label>");t.b("\n" + i);t.b(" <input id=\"seek{id}\" class=\"player-progress-seek\" type=\"range\" min=\"0\" max=\"100\" step=\"0.5\" value=\"0\" data-player=\"seek\">");t.b("\n" + i);t.b(" <progress class=\"player-progress-played\" max=\"100\" value=\"0\">");t.b("\n" + i);t.b(" <span>0</span>% played");t.b("\n" + i);t.b(" </progress>");t.b("\n" + i);t.b(" <progress class=\"player-progress-buffer\" max=\"100\" value=\"0\">");t.b("\n" + i);t.b(" <span>0</span>% buffered");t.b("\n" + i);t.b(" </progress>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" <span class=\"player-controls-left\">");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"restart\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-restart\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Restart</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"rewind\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-rewind\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Rewind {seektime} secs</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"play\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-play\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Play</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"pause\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-pause\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Pause</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"fast-forward\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-fast-forward\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Forward {seektime} secs</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <span class=\"player-time\">");t.b("\n" + i);t.b(" <span class=\"sr-only\">Current time</span>");t.b("\n" + i);t.b(" <span class=\"player-current-time\">00:00</span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" <span class=\"player-time\">");t.b("\n" + i);t.b(" <span class=\"sr-only\">Duration</span>");t.b("\n" + i);t.b(" <span class=\"player-duration\">00:00</span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" <span class=\"player-controls-right\">");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"mute\">");t.b("\n" + i);t.b(" <svg class=\"icon-muted\"><use xlink:href=\"#icon-muted\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-volume\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Mute</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <label for=\"volume{id}\" class=\"sr-only\">Volume</label>");t.b("\n" + i);t.b(" <input id=\"volume{id}\" class=\"player-volume\" type=\"range\" min=\"0\" max=\"10\" step=\"0.5\" value=\"0\" data-player=\"volume\">");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"captions\">");t.b("\n" + i);t.b(" <svg class=\"icon-captions-on\"><use xlink:href=\"#icon-captions-on\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-captions-off\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Captions</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"fullscreen\">");t.b("\n" + i);t.b(" <svg class=\"icon-exit-fullscreen\"><use xlink:href=\"#icon-exit-fullscreen\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-enter-fullscreen\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Fullscreen</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }});

View File

@ -37,7 +37,7 @@ shr.setup({
function newSource() {
var trigger = this,
type = trigger.getAttribute('data-source'),
player = document.querySelector('.player').plyr;
player = document.querySelector('.plyr').plyr;
switch(type) {
case 'video':
@ -81,16 +81,16 @@ shr.setup({
case 'youtube':
player.source({
type: 'youtube',
title: 'Introducing Apple Pencil',
sources: 'iicnVez5U7M'
title: 'Enovato interview of Dan Cederholm for Made By',
sources: 'Au87oAJ2jeE'
});
break;
case 'vimeo':
player.source({
type: 'vimeo',
title: 'The Beaten Track',
sources: '125220818'
title: 'Yosemite HD II',
sources: '87701971'
});
break;
}

View File

@ -3,7 +3,7 @@
// ==========================================================================
// Example players
.player {
.plyr {
margin: 0 auto @padding-base;
max-width: @example-width-video;
@ -11,38 +11,38 @@
border-radius: 0 0 @border-radius-base @border-radius-base;
}
}
.player-audio {
.plyr-audio {
max-width: @example-width-audio;
.player-controls {
.plyr-controls {
border-radius: @border-radius-base;
}
.player-progress {
.plyr-progress {
border-radius: @border-radius-base @border-radius-base 0 0;
overflow: hidden;
}
}
video,
.player-video-embed {
.plyr-video-embed {
border-radius: @border-radius-base;
}
.player-video-embed {
.plyr-video-embed {
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
// Style full supported player
.player-video,
.player-youtube,
.player-vimeo {
.plyr-video,
.plyr-youtube,
.plyr-vimeo {
video,
.player-video-embed {
.plyr-video-embed {
border-radius: @border-radius-base @border-radius-base 0 0;
}
&.player-fullscreen,
&.plyr-fullscreen,
&.fullscreen-active {
max-width: none;
.player-controls,
.plyr-controls,
video,
iframe {
border-radius: 0;
@ -52,3 +52,18 @@ video,
}
}
}
.cite {
display: none;
.icon {
margin-right: (@padding-base / 4);
}
}
.plyr-video ~ ul .cite-video,
.plyr-audio ~ ul .cite-audio,
.plyr-youtube ~ ul .cite-youtube,
.plyr-vimeo ~ ul .cite-vimeo {
display: block;
}

View File

@ -26,17 +26,24 @@ small {
padding: 0 (@padding-base / 2);
.font-size(14);
}
ul
li {
list-style: none;
margin: 0;
padding: 0;
}
// Links
a {
text-decoration: none;
color: @link-color;
border-bottom: 1px solid currentColor;
transition: background .3s ease, color .3s ease;
border-bottom: 1px dotted currentColor;
transition: background .3s ease, color .3s ease, border .3s ease;
&:hover,
&:focus {
color: @gray-dark;
border-bottom-color: rgba(0,0,0,0);
}
&:focus {
.tab-focus();
@ -45,3 +52,10 @@ a {
border: 0;
}
}
.color-vimeo {
color: @color-vimeo;
}
.color-youtube {
color: @color-youtube;
}

View File

@ -100,7 +100,7 @@ and the AJAX technique here:
### HTML
The only extra markup that's needed to use plyr is a `<div>` wrapper. Replace the source, poster and captions with urls for your media.
```html
<div class="player">
<div class="plyr">
<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">
@ -117,7 +117,7 @@ The only extra markup that's needed to use plyr is a `<div>` wrapper. Replace th
And the same for `<audio>`
```html
<div class="player">
<div class="plyr">
<audio controls>
<!-- Audio files -->
<source src="https://cdn.selz.com/plyr/1.0/logistics-96-sample.mp3" type="audio/mp3">
@ -132,7 +132,7 @@ And the same for `<audio>`
For YouTube, Plyr uses the standard YouTube API markup (an empty `<div>`):
```html
<div class="player">
<div class="plyr">
<div data-video-id="L1h9xxCU20g" data-type="youtube"></div>
</div>
```
@ -144,16 +144,43 @@ More info on CORS here:
[https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
### JavaScript
Much of the behaviour of the player is configurable when initialising the library. Here's an example of a default setup:
#### Quick setup
Here's an example of a default setup:
```html
<script src="dist/plyr.js"></script>
<script src="https://cdn.plyr.io/1.3.5/plyr.js"></script>
<script>plyr.setup();</script>
```
This will look for all elements with the `plyr` classname and setup plyr on each element found. You can specify other options, including a different selector hook below.
You can initialise the player a few other ways:
Passing a [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList):
```javascript
plyr.setup(document.querySelectorAll('.js-plyr'), options);
```
Passing a [HTMLElement](https://developer.mozilla.org/en/docs/Web/API/HTMLElement):
```javascript
plyr.setup(document.querySelector('.js-plyr'), options);
```
Passing a [string selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll):
```javascript
plyr.setup('.js-plyr', options);
```
Passing just the options object:
```javascript
plyr.setup(options);
```
#### Options
You can pass the following options to the setup method using `plyr.setup({...})`.
Options must be passed as an object to the `setup()` method as above.
<table class="table" width="100%">
<thead>
@ -235,7 +262,7 @@ You can pass the following options to the setup method using `plyr.setup({...})`
<td><code>selectors</code></td>
<td>Object</td>
<td>&mdash;</td>
<td>See <code>plyr.js</code> in <code>/src</code> for more info. The only option you might want to change is <code>player</code> which is the hook used for Plyr, the default is <code>.player</code>.</td>
<td>See <code>plyr.js</code> in <code>/src</code> for more info. The only option you might want to change is <code>container</code> which is the hook used for `setup()`, the default is <code>.plyr</code>.</td>
</tr>
<tr>
<td><code>classes</code></td>
@ -272,10 +299,27 @@ You can pass the following options to the setup method using `plyr.setup({...})`
## API
A `plyr` object is added to any element that Plyr is initialised on. You can then control the player by accessing methods in the `plyr` object. For example if you wanted to pause Plyr:
#### Fetching the plyr instance
A `plyr` object is added to any element that Plyr is initialised on. You can then control the player by accessing methods in the `plyr` object.
There are two ways to access the instance, firstly you re-query the element container you used for setup (e.g. `.js-plyr`) like so:
```javascript
document.querySelectorAll(".player")[0].plyr.pause();
var player = document.querySelector('.js-plyr');
```
Or you can use the returned object from your call to the setup method:
```javascript
var player = plyr.setup('.js-plyr')[0];
```
This will return an array of plyr instances setup, so you need to specify the index of the instance you want. This is less useful if you are setting up mutliple instances. You can also use the `onSetup` callback documented below which will return each instance one by one, as they are setup.
Once you have your instance, you can use the API methods below on it. For example to pause it:
```javascript
player.pause();
```
Here's a list of the methods supported:
@ -395,7 +439,7 @@ Here's a list of the methods supported:
The `plyr` object on the player element also contains a `media` property which is a reference to the `<audio>` or `<video>` element within the player which you can use to listen for events. Here's an example:
```javascript
var media = document.querySelectorAll(".player")[0].plyr.media;
var media = document.querySelector(".plyr").plyr.media;
media.addEventListener("playing", function() {
console.log("playing");
@ -415,7 +459,7 @@ Currently only YouTube is supported. Vimeo will be coming soon. Some HTML5 media
Due to the way the YouTube API works, the `timeupdate` and `progress` events are triggered by polling every 200ms so the event may trigger without an actual value change. Buffering progress is `media.buffered` in the `plyr` object. It is a a number between 0 and 1 that specifies the percentage of the video that the player shows as buffered.
```javascript
document.querySelector(".player").plyr.media.addEventListener("play", function() {
document.querySelector(".plyr").plyr.media.addEventListener("play", function() {
console.log("play");
});
```
@ -426,7 +470,7 @@ Currently caption control is not supported but I will work on this.
## Fullscreen
Fullscreen in Plyr is supported for all browsers that [currently support it](http://caniuse.com/#feat=fullscreen). If you're using the default CSS, you can also use a "full browser" mode which will use the full browser window by adding the `player-fullscreen` class to your container.
Fullscreen in Plyr is supported for all browsers that [currently support it](http://caniuse.com/#feat=fullscreen). If you're using the default CSS, you can also use a "full browser" mode which will use the full browser window by adding the `plyr-fullscreen` class to your container.
## Browser support

File diff suppressed because it is too large Load Diff

View File

@ -144,7 +144,7 @@
// Styles
// -------------------------------
// Base
.player {
.plyr {
position: relative;
max-width: 100%;
min-width: 290px;
@ -227,7 +227,7 @@
font-size: @font-size-captions-large;
}
// Player controls
// Plyr controls
&-controls {
.clearfix();
.font-smoothing();
@ -294,8 +294,8 @@
display: none;
}
// Player time
.player-time {
// plyr time
.plyr-time {
display: inline-block;
vertical-align: middle;
margin-left: @control-spacing;
@ -306,7 +306,7 @@
}
// Media duration hidden on small screens
.player-time + .player-time {
.plyr-time + .plyr-time {
display: none;
@media (min-width: @bp-control-split) {
@ -358,16 +358,16 @@
border-width: 0 1px 1px 0;
}
}
button:hover .player-tooltip,
button.tab-focus:focus .player-tooltip {
button:hover .plyr-tooltip,
button.tab-focus:focus .plyr-tooltip {
opacity: 1;
transform: translate(-50%, 0) scale(1);
}
button:hover .player-tooltip {
button:hover .plyr-tooltip {
z-index: 3;
}
// Player progress
// Playback progress
// <progress> element
&-progress {
position: absolute;
@ -466,7 +466,7 @@
}
// Loading state
&.loading .player-progress-buffer {
&.loading .plyr-progress-buffer {
animation: progress 1s linear infinite;
background-size: @progress-loading-size @progress-loading-size;
background-repeat: repeat-x;
@ -484,11 +484,11 @@
}
// States
&-controls [data-player='pause'],
&.playing .player-controls [data-player='play'] {
&-controls [data-plyr='pause'],
&.playing .plyr-controls [data-plyr='play'] {
display: none;
}
&.playing .player-controls [data-player='pause'] {
&.playing .plyr-controls [data-plyr='pause'] {
display: inline-block;
}
@ -560,7 +560,7 @@
// It's not supported to change volume using JavaScript:
// https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
&.ios &-volume,
&.ios [data-player='mute'],
&.ios [data-plyr='mute'],
&-audio.ios &-controls-right {
display: none;
}
@ -571,10 +571,10 @@
// Audio specific styles
// Position the progress within the container
&-audio .player-controls {
&-audio .plyr-controls {
padding-top: (@control-spacing * 2);
}
&-audio .player-progress {
&-audio .plyr-progress {
bottom: auto;
top: 0;
background: @off-white;
@ -596,11 +596,11 @@
video {
height: 100%;
}
.player-video-wrapper {
.plyr-video-wrapper {
height: 100%;
width: 100%;
}
.player-controls {
.plyr-controls {
position: absolute;
bottom: 0;
left: 0;
@ -609,22 +609,22 @@
// Hide controls when playing in full screen
&.fullscreen-hide-controls.playing {
.player-controls {
.plyr-controls {
transform: translateY(100%) translateY(@control-spacing / 2);
transition: transform .3s .2s ease;
}
&.player-hover .player-controls {
&.plyr-hover .plyr-controls {
transform: translateY(0);
}
.player-captions {
.plyr-captions {
bottom: (@control-spacing / 2);
transition: bottom .3s .2s ease;
}
}
// Captions
.player-captions,
&.fullscreen-hide-controls.playing.player-hover .player-captions {
.plyr-captions,
&.fullscreen-hide-controls.playing.plyr-hover .plyr-captions {
top: auto;
bottom: 90px;
@ -636,8 +636,8 @@
// Change icons on state change
&.fullscreen-active .icon-exit-fullscreen,
&.muted .player-controls .icon-muted,
&.captions-active .player-controls .icon-captions-on {
&.muted .plyr-controls .icon-muted,
&.captions-active .plyr-controls .icon-captions-on {
display: block;
& + svg {
@ -646,12 +646,12 @@
}
// Some options are hidden by default
[data-player='captions'],
[data-player='fullscreen'] {
[data-plyr='captions'],
[data-plyr='fullscreen'] {
display: none;
}
&.captions-enabled [data-player='captions'],
&.fullscreen-enabled [data-player='fullscreen'] {
&.captions-enabled [data-plyr='captions'],
&.fullscreen-enabled [data-plyr='fullscreen'] {
display: inline-block;
}
}