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>Fast forwards by the provided parameter, in seconds. If no parameter is provided, the default seekInterval is used (10 seconds).</td>
</tr>
<tr>
<td><code>seek</code></td>
<td>Number</td>
<td>Seeks the media to the provided parameter, time in seconds.</td>
</tr>
<tr>
<td><code>setVolume</code></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/)
- [HTML5 Weekly #177](http://html5weekly.com/issues/177)
- [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
- [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:
- [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
- [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:
- [Media Events - W3.org](http://www.w3.org/2010/05/video/mediaevents.html)

View File

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

View File

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

View File

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