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
Merged

Conversation

paulirish
Copy link
Owner

hopefully fixing #6
inspired by #90

See #6 (comment) for some context and details

Thanks @dantovein for kicking off this approach. you'll see a lot of similarities to #90.

I originally wanted to avoid loading this JS. (it's 300kb), but since the iframe JS is already 1MB, it seems fairly reasonable to add another 30%. :/
(god how i wish the typical iframe payload was smaller. alas.)


Seeking feedback on this approach!

Also happy for folks to test this. It seems to fix the double-tap/non-autoplay bug 95% of the time. Test pages: https://lite-youtube-embed-git-ytapi-paulirish.vercel.app/

paulirish and others added 6 commits July 14, 2021 11:28
Currently, you must to double tab a video and is very annoying for the users.

Fetch YouTube API script on demand
The client fetch the YouTube API Library only when the user click a placeholder video by the first time.

It doesn't use iframes directly
iframes are using internally through the YouTube API Library

Keep the performance stunning
It doesn't impact to the perfomance because the library is not being fetched at the same time that the page is being loaded
// 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)

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.

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.

@@ -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)

@paulirish
Copy link
Owner Author

paulirish commented Oct 28, 2022

The bug that Andy Davies mentioned at #perfnow is 95% fixed by this PR but....

From #6 (comment) ..

Thanks for the YT API merge.

It’s now working with one click/tap on almost all browsers except ipadOS Safari (and most likely iOS, but I don’t have an iPhone to test). Tested and worked well on Firefox Desktop, Chrome Desktop, Safari Desktop and Chrome mobile.

I don't have an ipad sadly.. anyone wanna pair up with me to sort this out?

@simevidas
Copy link

https://lite-youtube-embed-git-ytapi-paulirish.vercel.app/

On iPhone, I have to tap the play button twice to play the video.

@nucliweb
Copy link

Ey @paulirish, you can test it with iOS Simulator

If you add the event onStateChange we can see the states

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

Sreenshots

1

2

3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants