Merge branch 'develop' of github.com:selz/plyr into develop
This commit is contained in:
commit
4404e999eb
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.js
vendored
2
dist/plyr.js
vendored
File diff suppressed because one or more lines are too long
9
notes.md
Normal file
9
notes.md
Normal 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
|
@ -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)
|
||||
|
102
src/js/plyr.js
102
src/js/plyr.js
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user