paulirish / lite-youtube-embed

A faster youtube embed.
https://paulirish.github.io/lite-youtube-embed/
Other
5.68k stars 260 forks source link

Fix double tap issue on Mobile #90

Closed dantovbein closed 1 year ago

dantovbein commented 3 years ago

What is done

Fix double tap issue on Mobile 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 performance because the library is not being fetched at the same time that the page is being loaded. You can validate against the two attached reports below.

Lighthouse

The reports are almost the same, in fact, you can see on the first screenshot that the video placeholder is being shown more faster than the previous implementation.

This is the audit related to the new implementation /variants/solo:

Screenshot 2021-07-14 at 08 07 47

This is the audit related to the previous implementation /variants/solo: Screenshot 2021-07-14 at 08 11 22

oxyc commented 2 years ago

Tested it out and it's not working with safari on iOS

Edit: seems it worked while you had it muted

dantovbein commented 2 years ago

HI Oskar,

Which version of iOS have you tested it out on?

On Wed, 21 Jul 2021 at 20:05, Oskar Schöldström @.***> wrote:

Tested it out and it's not working with safari on iOS

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/paulirish/lite-youtube-embed/pull/90#issuecomment-884553058, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVPE5GA62P7WGJ4CRL47RLTY5HEJANCNFSM5ALIGC2Q .

-- Dan Tovbein

oxyc commented 2 years ago

iOS 14.6

GP-Dan-Tovbein commented 2 years ago

iOS 14.6

@oxyc I tested on IOs 14.6 Safari and works fine 🤔

Screenshot 2021-07-29 at 14 26 34

vucurovicmarko commented 2 years ago

Fixed dobule tap issue on mobile with this PR, but now multiple videos won't play on the same page.

philwolstenholme commented 2 years ago

Does this definitely work in iOS and for non-muted videos? I've tried a similar approach to this in the past and didn't get anywhere close to it working. I've not tried this PR but it doesn't look different from the code I tried that didn't work on mobile devices.

If we look at https://developers.google.com/youtube/iframe_api_reference#Autoplay_and_scripted_playback we can see this quote:

The HTML5 <video> element, in certain mobile browsers (such as Chrome and Safari), only allows playback to take place if it's initiated by a user interaction (such as tapping on the player). Here's an excerpt from Apple's documentation:

"Warning: To prevent unsolicited downloads over cellular networks at the user’s expense, embedded media cannot be played automatically in Safari on iOS — the user always initiates playback."

Due to this restriction, functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments.

This PR uses playVideo(); and in my experience, that isn't enough to reliably avoid the double-tap issue for unmuted videos on iOS.


The only hack I found to get around this issue on mobile was to have the iframe element always on the page but set to be pretty much invisible (opacity: 0.01 with CSS) with a custom cover image behind it. We also had to load the iframe API JS, then have an onStateChange event listener that made the iframe fully visible (opacity: 1) once the iframe has been clicked on and the video was playing. This allowed us to use a custom cover image and avoid double taps on mobile, but it didn't have any of the performance benefits as the iframe element had to exist on the page and the YouTube iframe API JS also had to be loaded before the video could be interacted with. It was also very buggy, resulted in a video playing with audio but no picture if the JS failed, and if the user clicked part of the 'invisible' iframe that didn't result in playback (e.g. the bottom part of the video where the volume, fullscreen, link to YouTube, Chromecast etc buttons are) then weird things happened that the users weren't expecting 👎

legendofmi commented 2 years ago

Does this definitely work in iOS and for non-muted videos? I've tried a similar approach to this in the past and didn't get anywhere close to it working. I've not tried this PR but it doesn't look different from the code I tried that didn't work on mobile devices.

If we look at https://developers.google.com/youtube/iframe_api_reference#Autoplay_and_scripted_playback we can see this quote:

The HTML5 <video> element, in certain mobile browsers (such as Chrome and Safari), only allows playback to take place if it's initiated by a user interaction (such as tapping on the player). Here's an excerpt from Apple's documentation:

"Warning: To prevent unsolicited downloads over cellular networks at the user’s expense, embedded media cannot be played automatically in Safari on iOS — the user always initiates playback."

Due to this restriction, functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments.

This PR uses playVideo(); and in my experience, that isn't enough to reliably avoid the double-tap issue for unmuted videos on iOS.

The only hack I found to get around this issue on mobile was to have the iframe element always on the page but set to be pretty much invisible (opacity: 0.01 with CSS) with a custom cover image behind it. We also had to load the iframe API JS, then have an onStateChange event listener that made the iframe fully visible (opacity: 1) once the iframe has been clicked on and the video was playing. This allowed us to use a custom cover image and avoid double taps on mobile, but it didn't have any of the performance benefits as the iframe element had to exist on the page and the YouTube iframe API JS also had to be loaded before the video could be interacted with. It was also very buggy, resulted in a video playing with audio but no picture if the JS failed, and if the user clicked part of the 'invisible' iframe that didn't result in playback (e.g. the bottom part of the video where the volume, fullscreen, link to YouTube, Chromecast etc buttons are) then weird things happened that the users weren't expecting 👎

You are right. I tested this solution on iPadOS Safari and it still requires double tapping. However, it does work on MacOS Safari which wasn't working before, so I would say it's still an improvement.