paulirish / lite-youtube-embed

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

The double-tap / mobile issue. Autoplay doesn't consistently work #6

Open NathanBowers opened 4 years ago

NathanBowers commented 4 years ago
  1. 1st tap to render the actual YouTube embed
  2. 2nd tap to play the actual YouTube embed
paulirish commented 4 years ago

Interesting.

I've seen this sometimes on Android Chrome but not consistently.

AFAIK, it's due to the user gesture requirement. The browser is supposed to allow video autoplay if its coming from a user gesture (like a click).

In our case, a user gesture triggers the creation of an iframe, with loads an HTML document, which has a <video autoplay> element. Because there's two async hops here, the browser may lose track of the attached user gesture.

This requires some debugging to figure out if our behavior or impl can be improved.


Update Nov 2021. I've done a bit more research...

emolr commented 4 years ago

Just my 2 cents here :)

Videos won't autoplay on IOS and IpadOS if the video has sound. So autoplay will most probably only work if the video is muted.

Maybe it's possible to do a hack which will start the video, and when the video is playing unmute the sounds

spacedawwwg commented 4 years ago

I've been testing on a Pixel 3 (Android 9.0, Chrome) and consistently have this issue too

hteumeuleu commented 4 years ago

I made a similar plugin for WordPress five years ago and had the same issue. I'm interested to know if there's a solution for this.

fregante commented 4 years ago

The moment you add some delay between the tap and the video.play() call you lost the window of opportunity for the "user gesture" required for audio playback.

In cases like this, the delay is caused by the deferred loading of the iframe.

The only way to fix it, is to load the iframe as soon as possible instead of after the tap; this way the time between tap and video.play() will be minimal and the browser will allow the playback.

mihdan commented 4 years ago

Use ?mute=1 in iframe src?

Garbee commented 4 years ago

One way we could possibly handle this is use an IntersectionObserver on the videos. When they're within some delta, pop the iframe in. This means videos that are initially above the fold (or very close) will load in right away waiting for the gesture. But any other still lazily load so on sites displaying many videos it would immediately saturate network operations trying to initialize all the iframes.

Slightly wasteful since if a user never starts the video, the network space goes unused. But that's the trade-off on mobile where gesture interaction is enforced in areas like this.

geekysrm commented 3 years ago

Same issue using Kiwi Browser on Android (which is a fork of Android Chromium)

valignatev commented 3 years ago

It also happens with me in Firefox, but on Desktop PC. Here's my setup:

              <lite-youtube
                videoid="id here"
                style="background-image: url('url_here')"
                params="autoplay=0"
              >
              </lite-youtube>

This video from examples requires two clicks to play as well, for example: https://paulirish.github.io/lite-youtube-embed/variants/pe.html

upd removing params="autoplay=0" makes video play after a single click, but it injects two iframes instead of one and they both play. Hmm, should I report that as a separate issue?

westonruter commented 3 years ago

It would be great if the browser would allow videos to autoplay in an iframe if the user had indicated that intent by clicking/tapping on an element in the parent window within the past ~5 seconds or so. This intent could also be restricted based on whether the tap had originated under the parentNode of that iframe (i.e. on the facade element which got replaced with the iframe). Otherwise, if an iframe is loaded without such intent, then the restriction preventing autoplaying videos could be retained as now.

remotay commented 3 years ago

Is there any solution to this? Loading heavy youtube embeds like this is best practices. Google Pagespeed even links to Dev which links directly to your solution for reducing page speed, but its strange that on mobile there seems to be no way around requiring 2 clicks

Garbee commented 3 years ago

As I said before, the best work-around is to use an intersection observer. If the node is in view or reasonably near it, go ahead and swap in the iframe. That can be done by calling element.addIframe(). That way when the user clicks or taps it is on the iframe itself and not another element before the iframe existed.

This detail is a mobile browser pattern aimed at improving user interactions on the web. It is unlikely to change in that space and work-arounds on the front to prevent a double tap in this scenario are likely to be patched.

If Paul decides that the component should do the observer internally, then in the upgrade notes it will be called out that if you're doing this then you can stop.

westonruter commented 3 years ago

@Garbee If using an intersection observer to replace the facade with an iframe, what's the real difference with just using a regular iframe with loading=lazy in the first place?

Garbee commented 3 years ago

The difference with the loading attribute is, browser support: https://caniuse.com/loading-lazy-attr . Also possibly other side effects, not sure how positioning is handled with those. Could possibly cause layout recalc in the right conditions. I'd need to do some testing on that to verify.

fchengpc commented 3 years ago

can anyone confirm adding mute=1 works?

kevinfarrugia commented 3 years ago

can anyone confirm adding mute=1 works?

Adding params="mute=1" (or directly in the iframe src) is muting the video as expected (on desktop & mobile) but it still requires two taps to play on touch devices for me.

dantovbein commented 3 years ago

Hello! Did someone find a fix for this issue? c.c. @paulirish

dantovbein commented 3 years ago

Hello @paulirish,

I just created this pull request that fix the double tap issue on Mobile among other things.

Looking forward to your feedback 👍

paulirish commented 2 years ago

I've updated an earlier comment of mine with some additional research: https://github.com/paulirish/lite-youtube-embed/issues/6#issuecomment-555135068

also i retitled this issue, so it's more canonical.

and i've put up a PR that may hopefully address this: https://github.com/paulirish/lite-youtube-embed/pull/109

legendofmi commented 2 years ago

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.

comzeradd commented 1 year ago

Any plan on creating a new tag/release, so it's easier for people to use the updated version through a cdn?

PWaddict commented 1 year ago

Hello!

Testing the demo page on Instagram in-app browser it needs double-tap. On Facebook in-app browser works fine. Tested on Android device.

ljs19923 commented 1 year ago

Hello! I have the same problem. Did you find a solution?