Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use YT player API to force autoplay, resolving double-tap bug #109

Merged
merged 10 commits into from
Sep 11, 2022
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ <h3>View isolated demos:</h3>
<li><a href="./variants/pe.html">lite-youtube-embed - progressively enhanced</a>
<li><a href="./variants/custom-poster-image.html">lite-youtube-embed - custom poster image</a>
<li><a href="./variants/params.html">lite-youtube-embed - with parameters</a></li>
<li><a href="./variants/multiple-embeds.html">lite-youtube-embed - multiple embeds on same page</a>
<li><a href="./variants/yt.html">normal youtube embed</a>
</ul>
</body>
Expand Down
50 changes: 49 additions & 1 deletion src/lite-yt-embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ class LiteYTEmbed extends HTMLElement {
// TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time
// We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003
this.addEventListener('click', this.addIframe);


// Chrome & Edge have no problem with the basic YouTube Embed with ?autoplay=1
// However Safari and Firefox do not successfully track the user gesture of clicking through the creation/loading of the iframe,
// so they don't autoplay automatically. Instead we must load an additional 300KB (ungz) of JS for the YT Player API
// TODO: chrome android seems to also need this
this.needsYTApiForAutoplay = navigator.vendor.includes('Apple') || navigator.userAgent.includes('Firefox');
Copy link
Owner Author

@paulirish paulirish Nov 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i figure ill have to change this to be some other sniff. don't think there's a good "feature detect" that's equivalent to failing to successfully autoplay. so yeah.. we'll do a UA sniff of some sort.

but this'll need to also include chrome android as well. and perhaps more.

some testing required:

has problems with autoplay on https://lite-youtube-embed-git-master-paulirish.vercel.app/

ios safari
desktop safari
firefox android
chrome android
edge mobile (probably.. untested)

no problems

desktop chrome
desktop firefox
desktop edge (on mac)

}

// // TODO: Support the the user changing the [videoid] attribute
Expand Down Expand Up @@ -95,12 +102,53 @@ class LiteYTEmbed extends HTMLElement {
LiteYTEmbed.preconnected = true;
}

addIframe() {
fetchYTPlayerApi() {
Copy link
Owner Author

@paulirish paulirish Nov 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alsoo wondering if there's a lazy way to attach... #82 hmmm!

EDIT: see also #146 (comment)

if (window.YT || (window.YT && window.YT.Player)) return;

this.ytApiPromise = new Promise((res, rej) => {
var el = document.createElement('script');
el.src = 'https://www.youtube.com/iframe_api';
el.async = true;
el.onload = _ => {
YT.ready(res);
};
el.onerror = rej;
this.append(el);
});
}

async addYTPlayerIframe(params) {
this.fetchYTPlayerApi();
await this.ytApiPromise;

const videoPlaceholderEl = document.createElement('div')
this.append(videoPlaceholderEl);

const paramsObj = Object.fromEntries(params.entries());
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im a little scared this newish feature will pose problems with various people's tsc/acorn/estree versions, if they're too old. but hopefully its fine.


new YT.Player(videoPlaceholderEl, {
width: '100%',
videoId: this.videoId,
playerVars: paramsObj,
events: {
'onReady': event => {
event.target.playVideo();
}
}
});
}

async addIframe(){
if (this.classList.contains('lyt-activated')) return;
this.classList.add('lyt-activated');

const params = new URLSearchParams(this.getAttribute('params') || []);
params.append('autoplay', '1');
params.append('playsinline', '1');
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


if (this.needsYTApiForAutoplay) {
return this.addYTPlayerIframe(params);
}

const iframeEl = document.createElement('iframe');
iframeEl.width = 560;
Expand Down
25 changes: 25 additions & 0 deletions variants/multiple-embeds.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>lite-youtube-embed</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../src/lite-yt-embed.css" />
</head>
<body>
<h1>multiple embeds</h1>

<lite-youtube videoid="ogfYd705cRs" playlabel="Play: Keynote (Google I/O '18)"></lite-youtube>


<lite-youtube videoid="n57U2_-3NLQ" playlabel="Play: Chrome Dev Summit 2021 recap"></lite-youtube>


<script src="../src/lite-yt-embed.js"></script>

<!-- <script>
// Simulate duplicate iframe problem. https://github.com/paulirish/lite-youtube-embed/issues/92
document.body.addEventListener('click', e => e.target.click());
</script> -->
</body>
</html>
4 changes: 0 additions & 4 deletions variants/solo.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,5 @@ <h1><code>lite-youtube</code> custom element</h1>

<script src="../src/lite-yt-embed.js"></script>

<!-- <script>
// Simulate duplicate iframe problem. https://github.com/paulirish/lite-youtube-embed/issues/92
document.body.addEventListener('click', e => e.target.click());
</script> -->
</body>
</html>
6 changes: 3 additions & 3 deletions variants/yt.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
</head>
<body>

<h3>typical iframe embed</h3>
<h1>typical iframe embed</h1>
<iframe
width="560"
height="315"
width="720"
height="405"
src="https://www.youtube.com/embed/ogfYd705cRs"
frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
Expand Down