Merge branch 'develop' of github.com:selz/plyr into develop

This commit is contained in:
Sam Potts 2015-03-05 20:08:53 +11:00
commit 4404e999eb
7 changed files with 203 additions and 103 deletions

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

9
notes.md Normal file
View File

@ -0,0 +1,9 @@
Loading
--------------
http://stackoverflow.com/questions/8685038/tell-whether-video-is-loaded-or-not-in-javascript
http://stackoverflow.com/questions/5181865/checking-if-a-html5-video-is-ready
Events
--------------
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events

View File

@ -263,6 +263,11 @@ Here's a list of the methods supported:
<td>Number</td> <td>Number</td>
<td>Fast forwards by the provided parameter, in seconds. If no parameter is provided, the default seekInterval is used (10 seconds).</td> <td>Fast forwards by the provided parameter, in seconds. If no parameter is provided, the default seekInterval is used (10 seconds).</td>
</tr> </tr>
<tr>
<td><code>seek</code></td>
<td>Number</td>
<td>Seeks the media to the provided parameter, time in seconds.</td>
</tr>
<tr> <tr>
<td><code>setVolume</code></td> <td><code>setVolume</code></td>
<td>Number</td> <td>Number</td>
@ -346,6 +351,9 @@ Plyr is developed by Sam Potts ([@sam_potts](https://twitter.com/sam_potts)) ([s
- [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/) - [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/)
- [HTML5 Weekly #177](http://html5weekly.com/issues/177) - [HTML5 Weekly #177](http://html5weekly.com/issues/177)
- [Web Design Weekly #174](https://web-design-weekly.com/2015/02/24/web-design-weekly-174/) - [Web Design Weekly #174](https://web-design-weekly.com/2015/02/24/web-design-weekly-174/)
- [Hacker News](https://news.ycombinator.com/item?id=9136774)
- [Web Platform Daily](http://webplatformdaily.org/releases/2015-03-04)
- [LayerVault Designer News](https://news.layervault.com/stories/45394-plyr--a-simple-html5-media-player)
## Used by ## Used by
- [Selz.com](https://selz.com) - [Selz.com](https://selz.com)
@ -356,6 +364,7 @@ Let me know on [Twitter](https://twitter.com/sam_potts) I can add you to the abo
Credit to the PayPal HTML5 Video player from which Plyr's caption functionality is ported from: Credit to the PayPal HTML5 Video player from which Plyr's caption functionality is ported from:
- [PayPal's Accessible HTML5 Video Player](https://github.com/paypal/accessible-html5-video-player) - [PayPal's Accessible HTML5 Video Player](https://github.com/paypal/accessible-html5-video-player)
- The icons used in Plyr are [Vicons](https://dribbble.com/shots/1663443-60-Vicons-Free-Icon-Set) plus some ones I made - The icons used in Plyr are [Vicons](https://dribbble.com/shots/1663443-60-Vicons-Free-Icon-Set) plus some ones I made
- [An awesome guide for Plyr in Japanese!](http://syncer.jp/how-to-use-plyr-io) by [@arayutw](https://twitter.com/arayutw)
Also these links helped created Plyr: Also these links helped created Plyr:
- [Media Events - W3.org](http://www.w3.org/2010/05/video/mediaevents.html) - [Media Events - W3.org](http://www.w3.org/2010/05/video/mediaevents.html)

View File

@ -274,7 +274,7 @@
// Get percentage // Get percentage
function _getPercentage(current, max) { function _getPercentage(current, max) {
return Math.floor((current / max) * 100); return ((current / max) * 100).toFixed(2);
} }
// Deep extend/merge two Objects // Deep extend/merge two Objects
@ -781,19 +781,7 @@
if(typeof seekTime !== "number") { if(typeof seekTime !== "number") {
seekTime = config.seekTime; seekTime = config.seekTime;
} }
_seek(player.media.currentTime - seekTime);
var targetTime = player.media.currentTime - seekTime;
if (targetTime < 0) {
player.media.currentTime = 0;
}
else {
player.media.currentTime = targetTime;
}
// Special handling for "manual" captions
if (!player.isTextTracks && player.type === "video") {
_adjustManualCaptions(player);
}
} }
// Fast forward // Fast forward
@ -802,15 +790,43 @@
if(typeof seekTime !== "number") { if(typeof seekTime !== "number") {
seekTime = config.seekTime; seekTime = config.seekTime;
} }
_seek(player.media.currentTime + seekTime);
}
var targetTime = player.media.currentTime + seekTime; // Seek to time
var _seek = function(input) {
//var value = config.seekTime;
var targetTime = 0;
// If no event or time is passed, bail
if (typeof input === "undefined") {
return;
}
// Explicit position
else if (typeof input === "number") {
targetTime = input;
}
// Event
else if (input.type === "change" || input.type === "input") {
// It's the seek slider
// Seek to the selected time
targetTime = ((this.value / this.max) * player.media.duration).toFixed(1);
}
// Handle min and max values
if (targetTime > player.media.duration) { if (targetTime > player.media.duration) {
player.media.currentTime = player.media.duration; player.media.currentTime = player.media.duration;
} }
else if (targetTime < 0) {
player.media.currentTime = 0;
}
else { else {
player.media.currentTime = targetTime; player.media.currentTime = targetTime;
} }
// Logging
_log("Seeking to " + player.media.currentTime + " seconds");
// Special handling for "manual" captions // Special handling for "manual" captions
if (!player.isTextTracks && player.type === "video") { if (!player.isTextTracks && player.type === "video") {
_adjustManualCaptions(player); _adjustManualCaptions(player);
@ -939,16 +955,19 @@
switch(event.type) { switch(event.type) {
// Video playing // Video playing
case "timeupdate": case "timeupdate":
case "seeking":
progress = player.progress.played.bar; progress = player.progress.played.bar;
text = player.progress.played.text; text = player.progress.played.text;
value = _getPercentage(player.media.currentTime, player.media.duration); value = _getPercentage(player.media.currentTime, player.media.duration);
// Set seeking value // Set seek range value only if it's a "natural" time event
player.buttons.seek.value = value; if(event.type == "timeupdate") {
player.buttons.seek.value = value;
}
break; break;
// Seeking // Events from seek range
case "change": case "change":
case "input": case "input":
progress = player.progress.played.bar; progress = player.progress.played.bar;
@ -995,6 +1014,13 @@
player.duration.innerHTML = player.mins + ":" + player.secs; player.duration.innerHTML = player.mins + ":" + player.secs;
} }
function _timeUpdate(event) {
// Duration
_updateTimeDisplay();
// Playing progress
_updateProgress(event);
}
// Listen for events // Listen for events
function _listeners() { function _listeners() {
// Play // Play
@ -1051,29 +1077,26 @@
} }
// Time change on media // Time change on media
_on(player.media, "timeupdate", function(event) { _on(player.media, "timeupdate seeking", _timeUpdate);
// Duration
_updateTimeDisplay(); // Pause and resume while seeking
// Playing progress /*_on(player.media, "seeking", function() {
_updateProgress(event); if(!player.media.paused && !player.seekPaused) {
player.seekPaused = true;
_pause();
}
_log("Seeking")
}); });
_on(player.media, "seeked", function() {
if(player.seekPaused) {
player.seekPaused = false;
_play();
}
_log("Seeked")
});*/
// Seek // Seek
_on(player.buttons.seek, "change input", function(event) { _on(player.buttons.seek, "change input", _seek);
// Update progress elements
_updateProgress(event);
// Update the text label
_updateTimeDisplay();
// Seek to the selected time
player.media.currentTime = ((this.value / this.max) * player.media.duration);
// Special handling for "manual" captions
if (!player.isTextTracks && player.type === "video") {
_adjustManualCaptions(player);
}
});
// Captions // Captions
_on(player.buttons.captions, "click", function() { _on(player.buttons.captions, "click", function() {
@ -1159,6 +1182,7 @@
restart: _restart, restart: _restart,
rewind: _rewind, rewind: _rewind,
forward: _forward, forward: _forward,
seek: _seek,
setVolume: _setVolume, setVolume: _setVolume,
toggleMute: _toggleMute, toggleMute: _toggleMute,
toggleCaptions: _toggleCaptions toggleCaptions: _toggleCaptions

View File

@ -66,7 +66,7 @@
outline-offset: 0; outline-offset: 0;
} }
// Range styling // <input type="range"> styling
// --------------------------------------- // ---------------------------------------
.volume-thumb() { .volume-thumb() {
height: @volume-thumb-height; height: @volume-thumb-height;
@ -205,13 +205,13 @@
transition: fill .3s ease; transition: fill .3s ease;
} }
} }
[type="checkbox"] + label, input + label,
.inverted:checked + label { .inverted:checked + label {
color: @control-color-inactive; color: @control-color-inactive;
} }
button, button,
.inverted + label, .inverted + label,
[type="checkbox"]:checked + label { input:checked + label {
color: @control-color; color: @control-color;
} }
button { button {
@ -222,13 +222,13 @@
button:focus, button:focus,
button:hover, button:hover,
[type="checkbox"]:focus + label, input:focus + label,
[type="checkbox"] + label:hover { input + label:hover {
background: @control-bg-hover; background: @control-bg-hover;
color: @control-color-hover; color: @control-color-hover;
} }
button:focus, button:focus,
[type="checkbox"]:focus + label { input:focus + label {
outline: 0; outline: 0;
} }
.icon-exit-fullscreen, .icon-exit-fullscreen,
@ -258,8 +258,8 @@
height: @control-spacing; height: @control-spacing;
background: @progress-bg; background: @progress-bg;
&-buffer, &-buffer[value],
&-played, &-played[value],
&-seek[type=range] { &-seek[type=range] {
position: absolute; position: absolute;
left: 0; left: 0;
@ -275,8 +275,8 @@
border: none; border: none;
background: transparent; background: transparent;
} }
&-buffer, &-buffer[value],
&-played { &-played[value] {
&::-webkit-progress-bar { &::-webkit-progress-bar {
background: transparent; background: transparent;
} }
@ -284,18 +284,18 @@
// Inherit from currentColor; // Inherit from currentColor;
&::-webkit-progress-value { &::-webkit-progress-value {
background: currentColor; background: currentColor;
transition: width .1s ease;
} }
&::-moz-progress-bar { &::-moz-progress-bar {
background: currentColor; background: currentColor;
transition: width .1s ease;
} }
} }
&-played { &-played[value] {
z-index: 2; z-index: 2;
}
&-played{
color: @progress-playing-bg; color: @progress-playing-bg;
} }
&-buffer { &-buffer[value] {
color: @progress-buffered-bg; color: @progress-buffered-bg;
} }
@ -339,7 +339,6 @@
} }
&:focus { &:focus {
//.tab-focus();
outline: 0; outline: 0;
} }
&::-moz-focus-outer { &::-moz-focus-outer {

View File

@ -30,12 +30,12 @@ $progress-playing-bg: $blue;
$progress-buffered-bg: $gray; $progress-buffered-bg: $gray;
// Range // Range
$range-track-height: 6px; $volume-track-height: 6px;
$range-track-bg: $gray; $volume-track-bg: $gray;
$range-thumb-height: ($range-track-height * 2); $volume-thumb-height: ($volume-track-height * 2);
$range-thumb-width: ($range-track-height * 2); $volume-thumb-width: ($volume-track-height * 2);
$range-thumb-bg: $control-color; $volume-thumb-bg: $control-color;
$range-thumb-bg-focus: $control-bg-hover; $volume-thumb-bg-focus: $control-bg-hover;
// Breakpoints // Breakpoints
$bp-control-split: 560px; // When controls split into left/right $bp-control-split: 560px; // When controls split into left/right
@ -66,27 +66,37 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
@mixin tab-focus() @mixin tab-focus()
{ {
outline: thin dotted #000; outline: thin dotted #000;
outline-offset: 1px; outline-offset: 0;
} }
// Range styling // <input type="range"> styling
// --------------------------------------- // ---------------------------------------
@mixin range-thumb() @mixin volume-thumb()
{ {
height: $range-thumb-height; height: $volume-thumb-height;
width: $range-thumb-width; width: $volume-thumb-width;
background: $range-thumb-bg; background: $volume-thumb-bg;
border: 0; border: 0;
border-radius: ($range-thumb-height / 2); border-radius: ($volume-thumb-height / 2);
transition: background .3s ease; transition: background .3s ease;
cursor: ew-resize; cursor: ew-resize;
} }
@mixin range-track() @mixin volume-track()
{ {
height: $range-track-height; height: $volume-track-height;
background: $range-track-bg; background: $volume-track-bg;
border: 0;
border-radius: ($volume-track-height / 2);
}
@mixin seek-thumb() {
background: transparent;
border: 0;
width: 2px;
height: $control-spacing;
}
@mixin seek-track() {
background: none;
border: 0; border: 0;
border-radius: ($range-track-height / 2);
} }
// Font smoothing // Font smoothing
@ -202,13 +212,13 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
transition: fill .3s ease; transition: fill .3s ease;
} }
} }
[type="checkbox"] + label, input + label,
.inverted:checked + label { .inverted:checked + label {
color: $control-color-inactive; color: $control-color-inactive;
} }
button, button,
.inverted + label, .inverted + label,
[type="checkbox"]:checked + label { input:checked + label {
color: $control-color; color: $control-color;
} }
button { button {
@ -216,13 +226,13 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
background: transparent; background: transparent;
overflow: hidden; overflow: hidden;
} }
[type="checkbox"]:focus + label, input:focus + label,
button:focus { button:focus {
@include tab-focus(); @include tab-focus();
color: $control-color-focus; color: $control-color-focus;
} }
button:hover, button:hover,
[type="checkbox"] + label:hover { input + label:hover {
background: $control-bg-hover; background: $control-bg-hover;
color: $control-color-hover; color: $control-color-hover;
} }
@ -253,8 +263,9 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
height: $control-spacing; height: $control-spacing;
background: $progress-bg; background: $progress-bg;
&-buffer, &-buffer[value],
&-played { &-played[value],
&-seek[type=range] {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
@ -263,34 +274,82 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
margin: 0; margin: 0;
vertical-align: top; vertical-align: top;
&[value] { -webkit-appearance: none;
-webkit-appearance: none; -moz-appearance: none;
border: none; border: none;
background: transparent;
}
&-buffer[value],
&-played[value] {
&::-webkit-progress-bar {
background: transparent; background: transparent;
}
&::-webkit-progress-bar { // Inherit from currentColor;
background: transparent; &::-webkit-progress-value {
} background: currentColor;
transition: width .1s ease;
// Inherit from currentColor; }
&::-webkit-progress-value { &::-moz-progress-bar {
background: currentColor; background: currentColor;
} transition: width .1s ease;
&::-moz-progress-bar {
background: currentColor;
}
} }
} }
&-played {
z-index: 2;
}
&-played[value] { &-played[value] {
cursor: pointer; z-index: 2;
color: $progress-playing-bg; color: $progress-playing-bg;
} }
&-buffer[value] { &-buffer[value] {
color: $progress-buffered-bg; color: $progress-buffered-bg;
} }
// Seek control
// <input[type='range']> element
// Specificity is for bootstrap compatibility
&-seek[type=range] {
z-index: 3;
cursor: pointer;
outline: 0;
// Webkit
&::-webkit-slider-runnable-track {
@include seek-track();
}
&::-webkit-slider-thumb {
-webkit-appearance: none;
@include seek-thumb();
}
// Mozilla
&::-moz-range-track {
@include seek-track();
}
&::-moz-range-thumb {
-moz-appearance: none;
@include seek-thumb();
}
// Microsoft
&::-ms-track {
color: transparent;
@include seek-track();
}
&::-ms-fill-lower,
&::-ms-fill-upper {
@include seek-track();
}
&::-ms-thumb {
@include seek-thumb();
}
&:focus {
outline: 0;
}
&::-moz-focus-outer {
border: 0;
}
}
} }
// States // States
@ -321,7 +380,7 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
} }
&::-webkit-slider-thumb { &::-webkit-slider-thumb {
-webkit-appearance: none; -webkit-appearance: none;
margin-top: -(($range-thumb-height - $range-track-height) / 2); margin-top: -(($volume-thumb-height - $volume-track-height) / 2);
@include range-thumb(); @include range-thumb();
} }
@ -335,10 +394,10 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
// Microsoft // Microsoft
&::-ms-track { &::-ms-track {
height: $range-track-height; height: $volume-track-height;
background: transparent; background: transparent;
border-color: transparent; border-color: transparent;
border-width: (($range-thumb-height - $range-track-height) / 2) 0; border-width: (($volume-thumb-height - $volume-track-height) / 2) 0;
color: transparent; color: transparent;
} }
&::-ms-fill-lower, &::-ms-fill-lower,
@ -353,13 +412,13 @@ $bp-captions-large: 768px; // When captions jump to the larger font size
outline: 0; outline: 0;
&::-webkit-slider-thumb { &::-webkit-slider-thumb {
background: $range-thumb-bg-focus; background: $volume-thumb-bg-focus;
} }
&::-moz-range-thumb { &::-moz-range-thumb {
background: $range-thumb-bg-focus; background: $volume-thumb-bg-focus;
} }
&::-ms-thumb { &::-ms-thumb {
background: $range-thumb-bg-focus; background: $volume-thumb-bg-focus;
} }
} }
} }