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

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

Open
NathanBowers opened this issue Nov 16, 2019 · 24 comments
Open

Comments

@NathanBowers
Copy link

  1. 1st tap to render the actual YouTube embed
  2. 2nd tap to play the actual YouTube embed
@paulirish
Copy link
Owner

paulirish commented Nov 18, 2019

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
Copy link

emolr commented Nov 18, 2019

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
Copy link
Contributor

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

@hteumeuleu
Copy link

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
Copy link

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
Copy link

mihdan commented Aug 1, 2020

Use ?mute=1 in iframe src?

@Garbee
Copy link
Contributor

Garbee commented Aug 3, 2020

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
Copy link

geekysrm commented Nov 2, 2020

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

@valignatev
Copy link

valignatev commented Apr 7, 2021

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
Copy link

westonruter commented Apr 28, 2021

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
Copy link

remotay commented May 11, 2021

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
Copy link
Contributor

Garbee commented May 11, 2021

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
Copy link

@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
Copy link
Contributor

Garbee commented May 12, 2021

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
Copy link

fchengpc commented Jun 9, 2021

can anyone confirm adding mute=1 works?

@kevinfarrugia
Copy link

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
Copy link

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

@dantovbein
Copy link

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 paulirish changed the title On iPad iOS 13.2.2 it takes two taps to play the video The double-tap / mobile issue. Autoplay doesn't consistently work Nov 29, 2021
@paulirish
Copy link
Owner

I've updated an earlier comment of mine with some additional research: #6 (comment)

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

and i've put up a PR that may hopefully address this: #109

@legendofmi
Copy link

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
Copy link

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

@PWaddict
Copy link

PWaddict commented Nov 28, 2022

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
Copy link

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

@brandonpeat
Copy link

Bumping this one. I'm seeing the same thing as discussed in #149: works great on desktop PC, desktop Mac, and mobile Android -- but not mobile iOS, which requires double-tap to play. Issue seems to be device/OS-level as all browsers on each device behave identically.

It looks like there have been commits in the past that have apparently solved this, but as the issue is still present I'm guessing Apple did some update in the interim that made this a problem again.

A fix is outside my wheelhouse, but any chance we can get smarter folks than I to take another look at this? Thanks!

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

No branches or pull requests