Fullscreen fixes

This commit is contained in:
Sam Potts
2019-01-14 00:33:48 +11:00
parent 6be125db87
commit 6782737009
23 changed files with 3141 additions and 568 deletions
+1 -1
View File
@@ -48,7 +48,7 @@
- Add support for YouTube's hl param (thanks @renaudleo)
- Fix for captions positioning when no controls (thanks @friday and @mjfwebb)
- Fix #1108: Make sure youtube.onReady doesn't run twice (thanks @friday)
- Fix for WebKit redraw loop on the `<input type="range">` elements
- Fix for WebKit repaint loop on the `<input type="range">` elements
### v3.3.22
+1 -1
View File
File diff suppressed because one or more lines are too long
+165 -67
View File
@@ -1,88 +1,128 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<head>
<meta charset="utf-8" />
<title>Plyr - A simple, customizable HTML5 Video, Audio, YouTube and Vimeo player</title>
<meta name="description" property="og:description" content="A simple HTML5 media player with custom controls and WebVTT captions.">
<meta name="author" content="Sam Potts">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta
name="description"
property="og:description"
content="A simple HTML5 media player with custom controls and WebVTT captions."
/>
<meta name="author" content="Sam Potts" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Icons -->
<link rel="icon" href="https://cdn.plyr.io/static/icons/favicon.ico">
<link rel="icon" type="image/png" href="https://cdn.plyr.io/static/icons/32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="https://cdn.plyr.io/static/icons/16x16.png" sizes="16x16">
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.plyr.io/static/icons/180x180.png">
<link rel="icon" href="https://cdn.plyr.io/static/icons/favicon.ico" />
<link rel="icon" type="image/png" href="https://cdn.plyr.io/static/icons/32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="https://cdn.plyr.io/static/icons/16x16.png" sizes="16x16" />
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.plyr.io/static/icons/180x180.png" />
<!-- Opengraph -->
<meta property="og:title" content="Plyr - A simple, customizable HTML5 Video, Audio, YouTube and Vimeo player">
<meta property="og:site_name" content="Plyr">
<meta property="og:url" content="https://plyr.io">
<meta property="og:image" content="https://cdn.plyr.io/static/icons/1200x630.png">
<meta
property="og:title"
content="Plyr - A simple, customizable HTML5 Video, Audio, YouTube and Vimeo player"
/>
<meta property="og:site_name" content="Plyr" />
<meta property="og:url" content="https://plyr.io" />
<meta property="og:image" content="https://cdn.plyr.io/static/icons/1200x630.png" />
<!-- Twitter -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@sam_potts">
<meta name="twitter:creator" content="@sam_potts">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@sam_potts" />
<meta name="twitter:creator" content="@sam_potts" />
<meta name="twitter:card" content="summary_large_image" />
<!-- Docs styles -->
<link rel="stylesheet" href="dist/demo.css?v=2">
<link rel="stylesheet" href="dist/demo.css?v=2" />
<!-- Preload -->
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/gordita-medium.woff2">
<link rel="preload" as="font" crossorigin type="font/woff2" href="https://cdn.plyr.io/static/fonts/gordita-bold.woff2">
</head>
<link
rel="preload"
as="font"
crossorigin
type="font/woff2"
href="https://cdn.plyr.io/static/fonts/gordita-medium.woff2"
/>
<link
rel="preload"
as="font"
crossorigin
type="font/woff2"
href="https://cdn.plyr.io/static/fonts/gordita-bold.woff2"
/>
</head>
<body>
<body>
<div class="grid">
<header>
<h1>Plyr</h1>
<p>A simple, accessible and customisable media player for
<p>
A simple, accessible and customisable media player for
<button type="button" class="faux-link" data-source="video">
<svg class="icon">
<title>HTML5</title>
<path d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"></path>
</svg>Video</button>,
<path
d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"
></path></svg
>Video</button
>,
<button type="button" class="faux-link" data-source="audio">
<svg class="icon">
<title>HTML5</title>
<path d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"></path>
</svg>Audio</button>,
<path
d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"
></path></svg
>Audio</button
>,
<button type="button" class="faux-link" data-source="youtube">
<svg class="icon" role="presentation">
<title>YouTube</title>
<path d="M15.8,4.8c-0.2-1.3-0.8-2.2-2.2-2.4C11.4,2,8,2,8,2S4.6,2,2.4,2.4C1,2.6,0.3,3.5,0.2,4.8C0,6.1,0,8,0,8
<path
d="M15.8,4.8c-0.2-1.3-0.8-2.2-2.2-2.4C11.4,2,8,2,8,2S4.6,2,2.4,2.4C1,2.6,0.3,3.5,0.2,4.8C0,6.1,0,8,0,8
s0,1.9,0.2,3.2c0.2,1.3,0.8,2.2,2.2,2.4C4.6,14,8,14,8,14s3.4,0,5.6-0.4c1.4-0.3,2-1.1,2.2-2.4C16,9.9,16,8,16,8S16,6.1,15.8,4.8z
M6,11V5l5,3L6,11z"></path>
</svg>YouTube</button> and
M6,11V5l5,3L6,11z"
></path></svg
>YouTube
</button>
and
<button type="button" class="faux-link" data-source="vimeo">
<svg class="icon" role="presentation">
<title>Vimeo</title>
<path d="M16,4.3c-0.1,1.6-1.2,3.7-3.3,6.4c-2.2,2.8-4,4.2-5.5,4.2c-0.9,0-1.7-0.9-2.4-2.6C4,9.9,3.4,5,2,5
<path
d="M16,4.3c-0.1,1.6-1.2,3.7-3.3,6.4c-2.2,2.8-4,4.2-5.5,4.2c-0.9,0-1.7-0.9-2.4-2.6C4,9.9,3.4,5,2,5
C1.9,5,1.5,5.3,0.8,5.8L0,4.8c0.8-0.7,3.5-3.4,4.7-3.5C5.9,1.2,6.7,2,7,3.8c0.3,2,0.8,6.1,1.8,6.1c0.9,0,2.5-3.4,2.6-4
c0.1-0.9-0.3-1.9-2.3-1.1c0.8-2.6,2.3-3.8,4.5-3.8C15.3,1.1,16.1,2.2,16,4.3z"></path>
</svg>Vimeo</button>
c0.1-0.9-0.3-1.9-2.3-1.1c0.8-2.6,2.3-3.8,4.5-3.8C15.3,1.1,16.1,2.2,16,4.3z"
></path></svg
>Vimeo
</button>
</p>
<p>Premium video monitization from
<p>
Premium video monitization from
<a href="https://vi.ai/publisher-video-monetization/?aid=plyrio" target="_blank" class="no-border">
<img src="https://cdn.plyr.io/static/vi-logo-24x24.svg" alt="ai.vi">
<img src="https://cdn.plyr.io/static/vi-logo-24x24.svg" alt="ai.vi" />
<span class="sr-only">ai.vi</span>
</a>
</p>
<div class="call-to-action">
<span class="button--with-count">
<a href="https://github.com/sampotts/plyr" target="_blank" class="button" data-shr-network="github">
<a
href="https://github.com/sampotts/plyr"
target="_blank"
class="button"
data-shr-network="github"
>
<svg class="icon" role="presentation">
<title>GitHub</title>
<path d="M8,0.2c-4.4,0-8,3.6-8,8c0,3.5,2.3,6.5,5.5,7.6
<path
d="M8,0.2c-4.4,0-8,3.6-8,8c0,3.5,2.3,6.5,5.5,7.6
C5.9,15.9,6,15.6,6,15.4c0-0.2,0-0.7,0-1.4C3.8,14.5,3.3,13,3.3,13c-0.4-0.9-0.9-1.2-0.9-1.2c-0.7-0.5,0.1-0.5,0.1-0.5
c0.8,0.1,1.2,0.8,1.2,0.8C4.4,13.4,5.6,13,6,12.8c0.1-0.5,0.3-0.9,0.5-1.1c-1.8-0.2-3.6-0.9-3.6-4c0-0.9,0.3-1.6,0.8-2.1
c-0.1-0.2-0.4-1,0.1-2.1c0,0,0.7-0.2,2.2,0.8c0.6-0.2,1.3-0.3,2-0.3c0.7,0,1.4,0.1,2,0.3c1.5-1,2.2-0.8,2.2-0.8
c0.4,1.1,0.2,1.9,0.1,2.1c0.5,0.6,0.8,1.3,0.8,2.1c0,3.1-1.9,3.7-3.7,3.9C9.7,12,10,12.5,10,13.2c0,1.1,0,1.9,0,2.2
c0,0.2,0.1,0.5,0.6,0.4c3.2-1.1,5.5-4.1,5.5-7.6C16,3.8,12.4,0.2,8,0.2z"></path>
c0,0.2,0.1,0.5,0.6,0.4c3.2-1.1,5.5-4.1,5.5-7.6C16,3.8,12.4,0.2,8,0.2z"
></path>
</svg>
Download on GitHub
</a>
@@ -92,19 +132,49 @@
<main>
<div id="container">
<video controls crossorigin playsinline poster="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg" id="player">
<video
controls
crossorigin
playsinline
poster="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg"
id="player"
>
<!-- Video files -->
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4" type="video/mp4" size="576">
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4" type="video/mp4" size="720">
<source src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1080p.mp4" type="video/mp4" size="1080">
<source
src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4"
type="video/mp4"
size="576"
/>
<source
src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4"
type="video/mp4"
size="720"
/>
<source
src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-1080p.mp4"
type="video/mp4"
size="1080"
/>
<!-- Caption files -->
<track kind="captions" label="English" srclang="en" src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt"
default>
<track kind="captions" label="Français" srclang="fr" src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt">
<track
kind="captions"
label="English"
srclang="en"
src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt"
default
/>
<track
kind="captions"
label="Français"
srclang="fr"
src="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt"
/>
<!-- Fallback for browsers that don't support the <video> element -->
<a href="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4" download>Download</a>
<a href="https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4" download
>Download</a
>
</video>
</div>
@@ -113,30 +183,47 @@
<small>
<svg class="icon">
<title>HTML5</title>
<path d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"></path>
<path
d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"
></path>
</svg>
<a href="https://itunes.apple.com/au/movie/view-from-a-blue-moon/id1041586323" target="_blank">View From A Blue Moon</a> &copy; Brainfarm
<a
href="https://itunes.apple.com/au/movie/view-from-a-blue-moon/id1041586323"
target="_blank"
>View From A Blue Moon</a
>
&copy; Brainfarm
</small>
</li>
<li class="plyr__cite plyr__cite--audio" hidden>
<small>
<svg class="icon" title="HTML5">
<title>HTML5</title>
<path d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"></path>
<path
d="M14.738.326C14.548.118 14.28 0 14 0H2c-.28 0-.55.118-.738.326S.98.81 1.004 1.09l1 11c.03.317.208.603.48.767l5 3c.16.095.338.143.516.143s.356-.048.515-.143l5-3c.273-.164.452-.45.48-.767l1-11c.026-.28-.067-.557-.257-.764zM12 4H6v2h6v5.72l-4 1.334-4-1.333V9h2v1.28l2 .666 2-.667V8H4V2h8v2z"
></path>
</svg>
<a href="http://www.kishibashi.com/" target="_blank">Kishi Bashi &ndash; &ldquo;It All Began With A Burst&rdquo;</a> &copy; Kishi Bashi
<a href="http://www.kishibashi.com/" target="_blank"
>Kishi Bashi &ndash; &ldquo;It All Began With A Burst&rdquo;</a
>
&copy; Kishi Bashi
</small>
</li>
<li class="plyr__cite plyr__cite--youtube" hidden>
<small>
<a href="https://www.youtube.com/watch?v=bTqVqk7FSmY" target="_blank">View From A Blue Moon</a> on&nbsp;
<a href="https://www.youtube.com/watch?v=bTqVqk7FSmY" target="_blank"
>View From A Blue Moon</a
>
on&nbsp;
<span class="color--youtube">
<svg class="icon" role="presentation">
<title>YouTube</title>
<path d="M15.8,4.8c-0.2-1.3-0.8-2.2-2.2-2.4C11.4,2,8,2,8,2S4.6,2,2.4,2.4C1,2.6,0.3,3.5,0.2,4.8C0,6.1,0,8,0,8
<path
d="M15.8,4.8c-0.2-1.3-0.8-2.2-2.2-2.4C11.4,2,8,2,8,2S4.6,2,2.4,2.4C1,2.6,0.3,3.5,0.2,4.8C0,6.1,0,8,0,8
s0,1.9,0.2,3.2c0.2,1.3,0.8,2.2,2.2,2.4C4.6,14,8,14,8,14s3.4,0,5.6-0.4c1.4-0.3,2-1.1,2.2-2.4C16,9.9,16,8,16,8S16,6.1,15.8,4.8z
M6,11V5l5,3L6,11z"></path>
</svg>YouTube
M6,11V5l5,3L6,11z"
></path></svg
>YouTube
</span>
</small>
</li>
@@ -146,10 +233,12 @@
<span class="color--vimeo">
<svg class="icon" role="presentation">
<title>Vimeo</title>
<path d="M16,4.3c-0.1,1.6-1.2,3.7-3.3,6.4c-2.2,2.8-4,4.2-5.5,4.2c-0.9,0-1.7-0.9-2.4-2.6C4,9.9,3.4,5,2,5
<path
d="M16,4.3c-0.1,1.6-1.2,3.7-3.3,6.4c-2.2,2.8-4,4.2-5.5,4.2c-0.9,0-1.7-0.9-2.4-2.6C4,9.9,3.4,5,2,5
C1.9,5,1.5,5.3,0.8,5.8L0,4.8c0.8-0.7,3.5-3.4,4.7-3.5C5.9,1.2,6.7,2,7,3.8c0.3,2,0.8,6.1,1.8,6.1c0.9,0,2.5-3.4,2.6-4
c0.1-0.9-0.3-1.9-2.3-1.1c0.8-2.6,2.3-3.8,4.5-3.8C15.3,1.1,16.1,2.2,16,4.3z"></path>
</svg>Vimeo
c0.1-0.9-0.3-1.9-2.3-1.1c0.8-2.6,2.3-3.8,4.5-3.8C15.3,1.1,16.1,2.2,16,4.3z"
></path></svg
>Vimeo
</span>
</small>
</li>
@@ -160,20 +249,30 @@
<aside>
<svg class="icon">
<title>Twitter</title>
<path d="M16,3c-0.6,0.3-1.2,0.4-1.9,0.5c0.7-0.4,1.2-1,1.4-1.8c-0.6,0.4-1.3,0.6-2.1,0.8c-0.6-0.6-1.5-1-2.4-1
<path
d="M16,3c-0.6,0.3-1.2,0.4-1.9,0.5c0.7-0.4,1.2-1,1.4-1.8c-0.6,0.4-1.3,0.6-2.1,0.8c-0.6-0.6-1.5-1-2.4-1
C9.3,1.5,7.8,3,7.8,4.8c0,0.3,0,0.5,0.1,0.7C5.2,5.4,2.7,4.1,1.1,2.1c-0.3,0.5-0.4,1-0.4,1.7c0,1.1,0.6,2.1,1.5,2.7
c-0.5,0-1-0.2-1.5-0.4c0,0,0,0,0,0c0,1.6,1.1,2.9,2.6,3.2C3,9.4,2.7,9.4,2.4,9.4c-0.2,0-0.4,0-0.6-0.1c0.4,1.3,1.6,2.3,3.1,2.3
c-1.1,0.9-2.5,1.4-4.1,1.4c-0.3,0-0.5,0-0.8,0c1.5,0.9,3.2,1.5,5,1.5c6,0,9.3-5,9.3-9.3c0-0.1,0-0.3,0-0.4C15,4.3,15.6,3.7,16,3z"></path>
c-1.1,0.9-2.5,1.4-4.1,1.4c-0.3,0-0.5,0-0.8,0c1.5,0.9,3.2,1.5,5,1.5c6,0,9.3-5,9.3-9.3c0-0.1,0-0.3,0-0.4C15,4.3,15.6,3.7,16,3z"
></path>
</svg>
<p>If you think Plyr's good,
<a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&amp;url=http%3A%2F%2Fplyr.io&amp;via=Sam_Potts"
target="_blank" data-shr-network="twitter">tweet it</a> 👍
<p>
If you think Plyr's good,
<a
href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&amp;url=http%3A%2F%2Fplyr.io&amp;via=Sam_Potts"
target="_blank"
data-shr-network="twitter"
>tweet it</a
>
👍
</p>
</aside>
<!-- Polyfills -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent,Object.entries,Object.values,URL"
crossorigin="anonymous"></script>
<script
src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent,Object.entries,Object.values,URL,Math.trunc"
crossorigin="anonymous"
></script>
<!-- Plyr core script -->
<script src="../dist/plyr.js" crossorigin="anonymous"></script>
@@ -186,6 +285,5 @@
<!-- Docs script -->
<script src="dist/demo.js" crossorigin="anonymous"></script>
</body>
</body>
</html>
+1 -1
View File
File diff suppressed because one or more lines are too long
+929 -99
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1730 -201
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

+29 -12
View File
@@ -65,11 +65,11 @@ Plyr extends upon the standard [HTML5 media element](https://developer.mozilla.o
```html
<video poster="/path/to/poster.jpg" id="player" playsinline controls>
<source src="/path/to/video.mp4" type="video/mp4">
<source src="/path/to/video.webm" type="video/webm">
<source src="/path/to/video.mp4" type="video/mp4" />
<source src="/path/to/video.webm" type="video/webm" />
<!-- Captions are optional -->
<track kind="captions" label="English captions" src="/path/to/captions.vtt" srclang="en" default>
<track kind="captions" label="English captions" src="/path/to/captions.vtt" srclang="en" default />
</video>
```
@@ -77,8 +77,8 @@ Plyr extends upon the standard [HTML5 media element](https://developer.mozilla.o
```html
<audio id="player" controls>
<source src="/path/to/audio.mp3" type="audio/mp3">
<source src="/path/to/audio.ogg" type="audio/ogg">
<source src="/path/to/audio.mp3" type="audio/mp3" />
<source src="/path/to/audio.ogg" type="audio/ogg" />
</audio>
```
@@ -90,7 +90,12 @@ We recommend [progressive enhancement](https://www.smashingmagazine.com/2009/04/
```html
<div class="plyr__video-embed" id="player">
<iframe src="https://www.youtube.com/embed/bTqVqk7FSmY?origin=https://plyr.io&amp;iv_load_policy=3&amp;modestbranding=1&amp;playsinline=1&amp;showinfo=0&amp;rel=0&amp;enablejsapi=1" allowfullscreen allowtransparency allow="autoplay"></iframe>
<iframe
src="https://www.youtube.com/embed/bTqVqk7FSmY?origin=https://plyr.io&amp;iv_load_policy=3&amp;modestbranding=1&amp;playsinline=1&amp;showinfo=0&amp;rel=0&amp;enablejsapi=1"
allowfullscreen
allowtransparency
allow="autoplay"
></iframe>
</div>
```
@@ -110,7 +115,12 @@ Much the same as YouTube above.
```html
<div class="plyr__video-embed" id="player">
<iframe src="https://player.vimeo.com/video/76979871?loop=false&amp;byline=false&amp;portrait=false&amp;title=false&amp;speed=true&amp;transparent=0&amp;gesture=media" allowfullscreen allowtransparency allow="autoplay"></iframe>
<iframe
src="https://player.vimeo.com/video/76979871?loop=false&amp;byline=false&amp;portrait=false&amp;title=false&amp;speed=true&amp;transparent=0&amp;gesture=media"
allowfullscreen
allowtransparency
allow="autoplay"
></iframe>
</div>
```
@@ -126,7 +136,9 @@ Include the `plyr.js` script before the closing `</body>` tag and then in your J
```html
<script src="path/to/plyr.js"></script>
<script>const player = new Plyr('#player');</script>
<script>
const player = new Plyr('#player');
</script>
```
See [initialising](#initialising) for more information on advanced setups.
@@ -148,13 +160,13 @@ You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the Java
Include the `plyr.css` stylsheet into your `<head>`
```html
<link rel="stylesheet" href="path/to/plyr.css">
<link rel="stylesheet" href="path/to/plyr.css" />
```
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
```html
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.7/plyr.css">
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.7/plyr.css" />
```
### SVG Sprite
@@ -277,7 +289,12 @@ In all cases, the constructor will return a Plyr object that can be used with th
Options can be passed as an object to the constructor as above or as JSON in `data-plyr-config` attribute on each of your target elements:
```html
<video src="/path/to/video.mp4" id="player" controls data-plyr-config='{ "title": "This is an example video", "volume": 1, "debug": true }'></video>
<video
src="/path/to/video.mp4"
id="player"
controls
data-plyr-config="{ &quot;title&quot;: &quot;This is an example video&quot;, &quot;volume&quot;: 1, &quot;debug&quot;: true }"
></video>
```
Note the single quotes encapsulating the JSON and double quotes on the object keys. Only string values need double quotes.
@@ -310,7 +327,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
| `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 (`event.preventDefault()`), the default handler will not fire. |
| `captions` | Object | `{ active: false, language: 'auto', update: false }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). 'auto' uses the browser language. `update`: Listen to changes to tracks and update menu. This is needed for some streaming libraries, but can result in unselectable language options). |
| `fullscreen` | Object | `{ enabled: true, fallback: true, iosNative: false }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution. `iosNative`: whether to use native iOS fullscreen when entering fullscreen (no custom controls) |
| `fullscreen` | Object | `{ enabled: true, fallback: true, iosNative: false }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution (true/false/'force'). `iosNative`: whether to use native iOS fullscreen when entering fullscreen (no custom controls) |
| `ratio` | String | `16:9` | The aspect ratio you want to use for embedded players. |
| `storage` | Object | `{ enabled: true, key: 'plyr' }` | `enabled`: Allow use of local storage to store user settings. `key`: The key name to use. |
| `speed` | Object | `{ selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] }` | `selected`: The default speed for playback. `options`: Options to display in the menu. Most browsers will refuse to play slower than 0.5. |
+1 -1
View File
@@ -108,7 +108,7 @@ const defaults = {
// Fullscreen settings
fullscreen: {
enabled: true, // Allow fullscreen?
fallback: true, // Fallback for vintage browsers
fallback: true, // Fallback using full viewport/window
iosNative: false, // Use the native fullscreen in iOS (disables custom controls)
},
+22 -7
View File
@@ -9,7 +9,20 @@ import support from './support';
import { repaint, transitionEndEvent } from './utils/animation';
import { dedupe } from './utils/arrays';
import browser from './utils/browser';
import { createElement, emptyElement, getAttributesFromSelector, getElement, getElements, hasClass, matches, removeElement, setAttributes, setFocus, toggleClass, toggleHidden } from './utils/elements';
import {
createElement,
emptyElement,
getAttributesFromSelector,
getElement,
getElements,
hasClass,
matches,
removeElement,
setAttributes,
setFocus,
toggleClass,
toggleHidden,
} from './utils/elements';
import { off, on } from './utils/events';
import i18n from './utils/i18n';
import is from './utils/is';
@@ -667,7 +680,7 @@ const controls = {
}
// Set CSS custom property
range.style.setProperty('--value', `${range.value / range.max * 100}%`);
range.style.setProperty('--value', `${(range.value / range.max) * 100}%`);
},
// Update hover tooltip for seeking
@@ -699,7 +712,7 @@ const controls = {
// Determine percentage, if already visible
if (is.event(event)) {
percent = 100 / clientRect.width * (event.pageX - clientRect.left);
percent = (100 / clientRect.width) * (event.pageX - clientRect.left);
} else if (hasClass(this.elements.display.seekTooltip, visible)) {
percent = parseFloat(this.elements.display.seekTooltip.style.left, 10);
} else {
@@ -714,7 +727,7 @@ const controls = {
}
// Display the time a click would seek to
controls.updateTimeDisplay.call(this, this.elements.display.seekTooltip, this.duration / 100 * percent);
controls.updateTimeDisplay.call(this, this.elements.display.seekTooltip, (this.duration / 100) * percent);
// Set position
this.elements.display.seekTooltip.style.left = `${percent}%`;
@@ -1674,15 +1687,17 @@ const controls = {
.filter(Boolean)
.forEach(button => {
if (is.array(button) || is.nodeList(button)) {
Array.from(button).filter(Boolean).forEach(addProperty);
Array.from(button)
.filter(Boolean)
.forEach(addProperty);
} else {
addProperty(button);
}
});
}
// Edge sometimes doesn't finish the paint so force a redraw
if (window.navigator.userAgent.includes('Edge')) {
// Edge sometimes doesn't finish the paint so force a repaint
if (browser.isEdge) {
repaint(target);
}
+22 -4
View File
@@ -94,6 +94,9 @@ class Fullscreen {
// Scroll position
this.scrollPosition = { x: 0, y: 0 };
// Force the use of 'full window/browser' rather than fullscreen
this.forceFallback = player.config.fullscreen.fallback === 'force';
// Register event listeners
// Handle event (incase user presses escape etc)
on.call(
@@ -130,6 +133,11 @@ class Fullscreen {
);
}
// If we're actually using native
get usingNative() {
return Fullscreen.native && !this.forceFallback;
}
// Get the prefix for handlers
static get prefix() {
// No prefix
@@ -174,7 +182,7 @@ class Fullscreen {
}
// Fallback using classname
if (!Fullscreen.native) {
if (!Fullscreen.native || this.forceFallback) {
return hasClass(this.target, this.player.config.classNames.fullscreen.fallback);
}
@@ -193,7 +201,17 @@ class Fullscreen {
// Update UI
update() {
if (this.enabled) {
this.player.debug.log(`${Fullscreen.native ? 'Native' : 'Fallback'} fullscreen enabled`);
let mode;
if (this.forceFallback) {
mode = 'Fallback (forced)';
} else if (Fullscreen.native) {
mode = 'Native';
} else {
mode = 'Fallback';
}
this.player.debug.log(`${mode} fullscreen enabled`);
} else {
this.player.debug.log('Fullscreen not supported and fallback disabled');
}
@@ -211,7 +229,7 @@ class Fullscreen {
// iOS native fullscreen doesn't need the request step
if (browser.isIos && this.player.config.fullscreen.iosNative) {
this.target.webkitEnterFullscreen();
} else if (!Fullscreen.native) {
} else if (!Fullscreen.native || this.forceFallback) {
toggleFallback.call(this, true);
} else if (!this.prefix) {
this.target.requestFullscreen();
@@ -230,7 +248,7 @@ class Fullscreen {
if (browser.isIos && this.player.config.fullscreen.iosNative) {
this.target.webkitExitFullscreen();
this.player.play();
} else if (!Fullscreen.native) {
} else if (!Fullscreen.native || this.forceFallback) {
toggleFallback.call(this, false);
} else if (!this.prefix) {
(document.cancelFullScreen || document.exitFullscreen).call(document);
+73 -6
View File
@@ -7,8 +7,9 @@ import ui from './ui';
import { repaint } from './utils/animation';
import browser from './utils/browser';
import { getElement, getElements, matches, toggleClass, toggleHidden } from './utils/elements';
import { on, once, toggleListener, triggerEvent } from './utils/events';
import { off, on, once, toggleListener, triggerEvent } from './utils/events';
import is from './utils/is';
import { setAspectRatio } from './utils/style';
class Listeners {
constructor(player) {
@@ -164,7 +165,7 @@ class Listeners {
// Escape is handle natively when in full screen
// So we only need to worry about non native
if (!player.fullscreen.enabled && player.fullscreen.active && code === 27) {
if (code === 27 && !player.fullscreen.usingNative && player.fullscreen.active) {
player.fullscreen.toggle();
}
@@ -261,10 +262,10 @@ class Listeners {
// Container listeners
container() {
const { player } = this;
const { elements } = player;
const { config, elements, timers } = player;
// Keyboard shortcuts
if (!player.config.keyboard.global && player.config.keyboard.focused) {
if (!config.keyboard.global && config.keyboard.focused) {
on.call(player, elements.container, 'keydown keyup', this.handleKey, false);
}
@@ -294,12 +295,78 @@ class Listeners {
}
// Clear timer
clearTimeout(player.timers.controls);
clearTimeout(timers.controls);
// Set new timer to prevent flicker when seeking
player.timers.controls = setTimeout(() => ui.toggleControls.call(player, false), delay);
timers.controls = setTimeout(() => ui.toggleControls.call(player, false), delay);
},
);
// Force edge to repaint on exit fullscreen
// TODO: Fix weird bug where Edge doesn't re-draw when exiting fullscreen
/* if (browser.isEdge) {
on.call(player, elements.container, 'exitfullscreen', () => {
setTimeout(() => repaint(elements.container), 100);
});
} */
// Set a gutter for Vimeo
const setGutter = (ratio, padding, toggle) => {
if (!player.isVimeo) {
return;
}
const target = player.elements.wrapper.firstChild;
const [, height] = ratio.split(':').map(Number);
const [videoWidth, videoHeight] = player.embed.ratio.split(':').map(Number);
target.style.maxWidth = toggle ? `${(height / videoHeight) * videoWidth}px` : null;
target.style.margin = toggle ? '0 auto' : null;
};
// Resize on fullscreen change
const setPlayerSize = measure => {
// If we don't need to measure the viewport
if (!measure) {
return setAspectRatio.call(player);
}
const rect = elements.container.getBoundingClientRect();
const { width, height } = rect;
return setAspectRatio.call(player, `${width}:${height}`);
};
const resized = () => {
window.clearTimeout(timers.resized);
timers.resized = window.setTimeout(setPlayerSize, 50);
};
on.call(player, elements.container, 'enterfullscreen exitfullscreen', event => {
const { target, usingNative } = player.fullscreen;
// Ignore for iOS native
if (!player.isEmbed || target !== elements.container) {
return;
}
const isEnter = event.type === 'enterfullscreen';
// Set the player size when entering fullscreen to viewport size
const { padding, ratio } = setPlayerSize(isEnter);
// Set Vimeo gutter
setGutter(ratio, padding, isEnter);
// If not using native fullscreen, we need to check for resizes of viewport
if (!usingNative) {
if (isEnter) {
on.call(player, window, 'resize', resized);
} else {
off.call(player, window, 'resize', resized);
}
}
});
}
// Listen for media events
+6 -43
View File
@@ -11,6 +11,7 @@ import fetch from '../utils/fetch';
import is from '../utils/is';
import loadScript from '../utils/loadScript';
import { format, stripHTML } from '../utils/strings';
import { setAspectRatio } from '../utils/style';
import { buildUrlParams } from '../utils/urls';
// Parse Vimeo ID from URL
@@ -27,13 +28,6 @@ function parseId(url) {
return url.match(regex) ? RegExp.$2 : url;
}
// Get aspect ratio for dimensions
function getAspectRatio(width, height) {
const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));
const ratio = getRatio(width, height);
return `${width / ratio}:${height / ratio}`;
}
// Set playback state and trigger change (only on actual change)
function assurePlaybackState(play) {
if (play && !this.embed.hasPlayed) {
@@ -51,7 +45,7 @@ const vimeo = {
toggleClass(this.elements.wrapper, this.config.classNames.embed, true);
// Set intial ratio
vimeo.setAspectRatio.call(this);
setAspectRatio.call(this);
// Load the API if not already
if (!is.object(window.Vimeo)) {
@@ -67,22 +61,6 @@ const vimeo = {
}
},
// Set aspect ratio
// For Vimeo we have an extra 300% height <div> to hide the standard controls and UI
setAspectRatio(input) {
const [x, y] = (is.string(input) ? input : this.config.ratio).split(':').map(Number);
const padding = (100 / x) * y;
vimeo.padding = padding;
this.elements.wrapper.style.paddingBottom = `${padding}%`;
if (this.supported.ui) {
const height = 240;
const offset = (height - padding) / (height / 50);
this.media.style.transform = `translateY(-${offset}%)`;
}
},
// API Ready
ready() {
const player = this;
@@ -91,7 +69,7 @@ const vimeo = {
const options = {
loop: player.config.loop.active,
autoplay: player.autoplay,
// muted: player.muted,
muted: player.muted,
byline: false,
portrait: false,
title: false,
@@ -300,8 +278,9 @@ const vimeo = {
// Set aspect ratio based on video size
Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => {
vimeo.ratio = getAspectRatio(dimensions[0], dimensions[1]);
vimeo.setAspectRatio.call(this, vimeo.ratio);
const [width, height] = dimensions;
player.embed.ratio = `${width}:${height}`;
setAspectRatio.call(this, player.embed.ratio);
});
// Set autopause
@@ -405,22 +384,6 @@ const vimeo = {
triggerEvent.call(player, player.media, 'error');
});
// Set height/width on fullscreen
player.on('enterfullscreen exitfullscreen', event => {
const { target } = player.fullscreen;
// Ignore for iOS native
if (target !== player.elements.container) {
return;
}
const toggle = event.type === 'enterfullscreen';
const [x, y] = vimeo.ratio.split(':').map(Number);
const dimension = x > y ? 'width' : 'height';
target.style[dimension] = toggle ? `${vimeo.padding}%` : null;
});
// Rebuild UI
setTimeout(() => ui.build.call(player), 0);
},
+2 -7
View File
@@ -10,6 +10,7 @@ import is from '../utils/is';
import loadImage from '../utils/loadImage';
import loadScript from '../utils/loadScript';
import { format, generateId } from '../utils/strings';
import { setAspectRatio } from '../utils/style';
// Parse YouTube ID from URL
function parseId(url) {
@@ -38,7 +39,7 @@ const youtube = {
toggleClass(this.elements.wrapper, this.config.classNames.embed, true);
// Set aspect ratio
youtube.setAspectRatio.call(this);
setAspectRatio.call(this);
// Setup API
if (is.object(window.YT) && is.function(window.YT.Player)) {
@@ -98,12 +99,6 @@ const youtube = {
}
},
// Set aspect ratio
setAspectRatio() {
const ratio = this.config.ratio.split(':');
this.elements.wrapper.style.paddingBottom = `${100 / ratio[0] * ratio[1]}%`;
},
// API ready
ready() {
const player = this;
+1 -1
View File
@@ -263,7 +263,7 @@ class Plyr {
// Wrap media
if (!is.element(this.elements.container)) {
this.elements.container = createElement('div');
this.elements.container = createElement('div', { tabindex: 0 });
wrap(this.media, this.elements.container);
}
+1
View File
@@ -5,6 +5,7 @@
const browser = {
isIE: /* @cc_on!@ */ false || !!document.documentMode,
isEdge: window.navigator.userAgent.includes('Edge'),
isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),
isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),
isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform),
+40
View File
@@ -0,0 +1,40 @@
// ==========================================================================
// Style utils
// ==========================================================================
import is from './is';
/* function reduceAspectRatio(width, height) {
const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));
const ratio = getRatio(width, height);
return `${width / ratio}:${height / ratio}`;
} */
// Set aspect ratio for responsive container
export function setAspectRatio(input) {
let ratio = input;
if (!is.string(ratio) && !is.nullOrUndefined(this.embed)) {
({ ratio } = this.embed);
}
if (!is.string(ratio)) {
({ ratio } = this.config);
}
const [x, y] = ratio.split(':').map(Number);
const padding = (100 / x) * y;
this.elements.wrapper.style.paddingBottom = `${padding}%`;
// For Vimeo we have an extra <div> to hide the standard controls and UI
if (this.isVimeo && this.supported.ui) {
const height = 240;
const offset = (height - padding) / (height / 50);
this.media.style.transform = `translateY(-${offset}%)`;
}
return { padding, ratio };
}
export default { setAspectRatio };