Open NathanBowers opened 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...
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
I've been testing on a Pixel 3 (Android 9.0, Chrome) and consistently have this issue too
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.
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.
Use ?mute=1
in iframe src?
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.
Same issue using Kiwi Browser on Android (which is a fork of Android Chromium)
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?
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.
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
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.
@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?
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.
can anyone confirm adding mute=1
works?
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.
Hello! Did someone find a fix for this issue? c.c. @paulirish
Hello @paulirish,
I just created this pull request that fix the double tap issue on Mobile among other things.
Looking forward to your feedback 👍
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
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.
Any plan on creating a new tag/release, so it's easier for people to use the updated version through a cdn?
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.
Hello! I have the same problem. Did you find a solution?