Started on error handling

This commit is contained in:
Sam 2018-01-04 13:43:56 +11:00
parent 6b9106ddb1
commit 92cb9e22e2
16 changed files with 84 additions and 12 deletions

2
demo/dist/demo.css vendored

File diff suppressed because one or more lines are too long

2
demo/dist/demo.js vendored
View File

@ -1,3 +1,3 @@
document.addEventListener("DOMContentLoaded",function(){function e(e,t,o){e&&e.classList[o?"add":"remove"](t)}function t(t,n){if(t in r&&(n||t!==a)&&(a.length||t!==r.video)){switch(t){case r.video:o.source={type:"video",title:"View From A Blue Moon",sources:[{src:"media/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"}],poster:"media/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"media/View_From_A_Blue_Moon_Trailer-HD.en.vtt",default:!0},{kind:"captions",label:"French",srclang:"fr",src:"media/View_From_A_Blue_Moon_Trailer-HD.fr.vtt"}]};break;case r.audio:o.source={type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]};break;case r.youtube:o.source={type:"video",title:"View From A Blue Moon",sources:[{src:"https://youtube.com/watch?v=bTqVqk7FSmY",provider:"youtube"}]};break;case r.vimeo:o.source={type:"video",sources:[{src:"https://vimeo.com/76979871",provider:"vimeo"}]}}a=t,Array.from(i).forEach(function(t){return e(t.parentElement,"active",!1)}),e(document.querySelector('[data-source="'+t+'"]'),"active",!0),Array.from(document.querySelectorAll(".plyr__cite")).forEach(function(e){e.setAttribute("hidden","")}),document.querySelector(".plyr__cite--"+t).removeAttribute("hidden")}}window.shr&&window.shr.setup({count:{classname:"button__count"}});document.addEventListener("focusout",function(e){e.target.classList.remove("tab-focus")}),document.addEventListener("keydown",function(e){9===e.keyCode&&window.setTimeout(function(){document.activeElement.classList.add("tab-focus")},0)});var o=new window.Plyr("#player",{debug:!0,title:"View From A Blue Moon",iconUrl:"../dist/plyr.svg",keyboard:{global:!0},tooltips:{controls:!0},captions:{active:!0},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","fullscreen","pip","airplay"],keys:{google:"AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c"}});window.player=o;var i=document.querySelectorAll("[data-source]"),r={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},a=window.location.hash.replace("#",""),n=window.history&&window.history.pushState;if(Array.from(i).forEach(function(e){e.addEventListener("click",function(){var o=e.getAttribute("data-source");t(o),n&&window.history.pushState({type:o},"","#"+o)})}),window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),n){var s=!a.length;s&&(a=r.video),a in r&&window.history.replaceState({type:a},"",s?"":"#"+a),a!==r.video&&t(a,!0)}}),"plyr.io"===window.location.host&&(!function(e,t,o,i,r,a,n){e.GoogleAnalyticsObject="ga",e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,a=t.createElement("script"),n=t.getElementsByTagName("script")[0],a.async=1,a.src="//www.google-analytics.com/analytics.js",n.parentNode.insertBefore(a,n)}(window,document),window.ga("create","UA-40881672-11","auto"),window.ga("send","pageview")); document.addEventListener("DOMContentLoaded",function(){function e(e,t,o){e&&e.classList[o?"add":"remove"](t)}function t(t,o){if(t in a&&(o||t!==n)&&(n.length||t!==a.video)){switch(t){case a.video:i.source={type:"video",title:"View From A Blue Moon",sources:[{src:"media/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"}],poster:"media/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"media/View_From_A_Blue_Moon_Trailer-HD.en.vtt",default:!0},{kind:"captions",label:"French",srclang:"fr",src:"media/View_From_A_Blue_Moon_Trailer-HD.fr.vtt"}]};break;case a.audio:i.source={type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]};break;case a.youtube:i.source={type:"video",title:"View From A Blue Moon",sources:[{src:"https://youtube.com/watch?v=bTqVqk7FSmY",provider:"youtube"}]};break;case a.vimeo:i.source={type:"video",sources:[{src:"https://vimeo.com/76979871",provider:"vimeo"}]}}n=t,Array.from(r).forEach(function(t){return e(t.parentElement,"active",!1)}),e(document.querySelector('[data-source="'+t+'"]'),"active",!0),Array.from(document.querySelectorAll(".plyr__cite")).forEach(function(e){e.setAttribute("hidden","")}),document.querySelector(".plyr__cite--"+t).removeAttribute("hidden")}}window.shr&&window.shr.setup({count:{classname:"button__count"}});var o="tab-focus";document.addEventListener("focusout",function(e){e.target.classList.remove(o)}),document.addEventListener("keydown",function(e){9===e.keyCode&&window.setTimeout(function(){document.activeElement.classList.add(o)},0)});var i=new window.Plyr("#player",{debug:!0,title:"View From A Blue Moon",iconUrl:"../dist/plyr.svg",keyboard:{global:!0},tooltips:{controls:!0},captions:{active:!0},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","fullscreen","pip","airplay"],keys:{google:"AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c"}});window.player=i;var r=document.querySelectorAll("[data-source]"),a={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},n=window.location.hash.replace("#",""),s=window.history&&window.history.pushState;if(Array.from(r).forEach(function(e){e.addEventListener("click",function(){var o=e.getAttribute("data-source");t(o),s&&window.history.pushState({type:o},"","#"+o)})}),window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),s){var c=!n.length;c&&(n=a.video),n in a&&window.history.replaceState({type:n},"",c?"":"#"+n),n!==a.video&&t(n,!0)}}),"plyr.io"===window.location.host&&(!function(e,t,o,i,r,a,n){e.GoogleAnalyticsObject="ga",e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,a=t.createElement("script"),n=t.getElementsByTagName("script")[0],a.async=1,a.src="//www.google-analytics.com/analytics.js",n.parentNode.insertBefore(a,n)}(window,document),window.ga("create","UA-40881672-11","auto"),window.ga("send","pageview"));
//# sourceMappingURL=demo.js.map //# sourceMappingURL=demo.js.map

File diff suppressed because one or more lines are too long

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/plyr.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -260,7 +260,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
| `displayDuration` | Boolean | `true` | Displays the duration of the media on the "metadataloaded" event (on startup) in the current time display. This will only work if the `preload` attribute is not set to `none` (or is not set at all) and you choose not to display the duration (see `controls` option). | | `displayDuration` | Boolean | `true` | Displays the duration of the media on the "metadataloaded" event (on startup) in the current time display. This will only work if the `preload` attribute is not set to `none` (or is not set at all) and you choose not to display the duration (see `controls` option). |
| `invertTime` | Boolean | `true` | Display the current time as a countdown rather than an incremental counter. | | `invertTime` | Boolean | `true` | Display the current time as a countdown rather than an incremental counter. |
| `toggleInvert` | Boolean | `true` | Allow users to click to toggle the above. | | `toggleInvert` | Boolean | `true` | Allow users to click to toggle the above. |
| `listeners` | Object | `null` | Allows binding of event listeners to the controls before the default handlers. See the `defaults.js` for available listeners. IF your handler prevents default on the event, the default handler will not fire. | | `listeners` | Object | `null` | Allows binding of event listeners to the controls before the default handlers. See the `defaults.js` for available listeners. If your handler prevents default on the event (`event.preventDefault()`), the default handler will not fire. |
| `captions` | Object | `{ active: false, language: window.navigator.language.split('-')[0] }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). | | `captions` | Object | `{ active: false, language: window.navigator.language.split('-')[0] }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). |
| `fullscreen` | Object | `{ enabled: true, fallback: true }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution. | | `fullscreen` | Object | `{ enabled: true, fallback: true }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution. |
| `ratio` | String | `16:9` | The aspect ratio you want to use for embedded players. | | `ratio` | String | `16:9` | The aspect ratio you want to use for embedded players. |

View File

@ -305,6 +305,7 @@ const defaults = {
stopped: 'plyr--stopped', stopped: 'plyr--stopped',
playing: 'plyr--playing', playing: 'plyr--playing',
loading: 'plyr--loading', loading: 'plyr--loading',
error: 'plyr--has-error',
hover: 'plyr--hover', hover: 'plyr--hover',
tooltip: 'plyr__tooltip', tooltip: 'plyr__tooltip',
hidden: 'plyr__sr-only', hidden: 'plyr__sr-only',

View File

@ -221,6 +221,11 @@ const listeners = {
utils.on(document, fullscreen.eventType, event => { utils.on(document, fullscreen.eventType, event => {
this.toggleFullscreen(event); this.toggleFullscreen(event);
}); });
// Fullscreen toggle on double click
utils.on(this.elements.container, 'dblclick', event => {
this.toggleFullscreen(event);
});
} }
}, },
@ -263,6 +268,9 @@ const listeners = {
// Loading // Loading
utils.on(this.media, 'stalled waiting canplay seeked playing', event => ui.checkLoading.call(this, event)); utils.on(this.media, 'stalled waiting canplay seeked playing', event => ui.checkLoading.call(this, event));
// Check if media failed to load
// utils.on(this.media, 'play', event => ui.checkFailed.call(this, event));
// Click video // Click video
if (this.supported.ui && this.config.clickToPlay && !this.isAudio) { if (this.supported.ui && this.config.clickToPlay && !this.isAudio) {
// Re-fetch the wrapper // Re-fetch the wrapper

View File

@ -35,7 +35,11 @@ let scrollPosition = {
class Plyr { class Plyr {
constructor(target, options) { constructor(target, options) {
this.timers = {}; this.timers = {};
// State
this.ready = false; this.ready = false;
this.loading = false;
this.failed = false;
// Set the media element // Set the media element
this.media = target; this.media = target;
@ -809,6 +813,11 @@ class Plyr {
* @param {event} event * @param {event} event
*/ */
toggleFullscreen(event) { toggleFullscreen(event) {
// Video only
if (this.isAudio) {
return;
}
// Check for native support // Check for native support
if (fullscreen.enabled) { if (fullscreen.enabled) {
if (utils.is.event(event) && event.type === fullscreen.eventType) { if (utils.is.event(event) && event.type === fullscreen.eventType) {

View File

@ -153,7 +153,7 @@ const ui = {
// Check if media is loading // Check if media is loading
checkLoading(event) { checkLoading(event) {
this.loading = [ this.loading = this.media.networkState === 2 || [
'stalled', 'stalled',
'waiting', 'waiting',
].includes(event.type); ].includes(event.type);
@ -171,6 +171,29 @@ const ui = {
}, this.loading ? 250 : 0); }, this.loading ? 250 : 0);
}, },
// Check if media failed to load
checkFailed() {
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/networkState
this.failed = this.media.networkState === 3;
if (this.failed) {
utils.toggleClass(this.elements.container, this.config.classNames.loading, false);
utils.toggleClass(this.elements.container, this.config.classNames.error, true);
}
// Clear timer
clearTimeout(this.timers.failed);
// Timer to prevent flicker when seeking
this.timers.loading = setTimeout(() => {
// Toggle container class hook
utils.toggleClass(this.elements.container, this.config.classNames.loading, this.loading);
// Show controls if loading, hide if done
this.toggleControls(this.loading);
}, this.loading ? 250 : 0);
},
// Update volume UI and storage // Update volume UI and storage
updateVolume() { updateVolume() {
if (!this.supported.ui) { if (!this.supported.ui) {

View File

@ -37,6 +37,7 @@
@import 'components/video'; @import 'components/video';
@import 'components/volume'; @import 'components/volume';
@import 'states/error';
@import 'states/fullscreen'; @import 'states/fullscreen';
@import 'utils/animation'; @import 'utils/animation';

View File

@ -6,5 +6,5 @@ $plyr-captions-bg: rgba(#000, 0.8) !default;
$plyr-captions-color: #fff !default; $plyr-captions-color: #fff !default;
$plyr-font-size-captions-base: $plyr-font-size-base !default; $plyr-font-size-captions-base: $plyr-font-size-base !default;
$plyr-font-size-captions-small: $plyr-font-size-small !default; $plyr-font-size-captions-small: $plyr-font-size-small !default;
$plyr-font-size-captions-medium: 18px !default; $plyr-font-size-captions-medium: $plyr-font-size-large !default;
$plyr-font-size-captions-large: 21px !default; $plyr-font-size-captions-large: $plyr-font-size-xlarge !default;

View File

@ -5,6 +5,8 @@
$plyr-font-family: Avenir, 'Avenir Next', 'Helvetica Neue', 'Segoe UI', Helvetica, Arial, sans-serif !default; $plyr-font-family: Avenir, 'Avenir Next', 'Helvetica Neue', 'Segoe UI', Helvetica, Arial, sans-serif !default;
$plyr-font-size-base: 16px !default; $plyr-font-size-base: 16px !default;
$plyr-font-size-small: 14px !default; $plyr-font-size-small: 14px !default;
$plyr-font-size-large: 18px !default;
$plyr-font-size-xlarge: 21px !default;
$plyr-font-size-time: 14px !default; $plyr-font-size-time: 14px !default;
$plyr-font-size-badge: 9px !default; $plyr-font-size-badge: 9px !default;

View File

@ -0,0 +1,25 @@
// --------------------------------------------------------------
// Error state
// --------------------------------------------------------------
.plyr--has-error {
pointer-events: none;
&::after {
align-items: center;
background: rgba(#000, 90%);
color: #fff;
content: attr(data-plyr-error);
display: flex;
font-size: $plyr-font-size-base;
height: 100%;
justify-content: center;
left: 0;
position: absolute;
text-align: center;
text-shadow: 0 1px 1px rgba(#000, 10%);
top: 0;
width: 100%;
z-index: 10;
}
}

View File

@ -6,14 +6,17 @@
@include plyr-fullscreen-active(); @include plyr-fullscreen-active();
} }
/* stylelint-disable-next-line */
.plyr:-webkit-full-screen { .plyr:-webkit-full-screen {
@include plyr-fullscreen-active(); @include plyr-fullscreen-active();
} }
/* stylelint-disable-next-line */
.plyr:-moz-full-screen { .plyr:-moz-full-screen {
@include plyr-fullscreen-active(); @include plyr-fullscreen-active();
} }
/* stylelint-disable-next-line */
.plyr:-ms-fullscreen { .plyr:-ms-fullscreen {
@include plyr-fullscreen-active(); @include plyr-fullscreen-active();
} }
@ -22,10 +25,10 @@
.plyr--fullscreen-fallback { .plyr--fullscreen-fallback {
@include plyr-fullscreen-active(); @include plyr-fullscreen-active();
position: fixed;
top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
position: fixed;
right: 0; right: 0;
top: 0;
z-index: 10000000; z-index: 10000000;
} }