vimeo/player.js

Autoplay throw error on iOS (webkit)

Closed this issue ยท 14 comments

Expected Behavior

  • After ended event got fired, the next video got loaded & played immediately.

Actual Behavior

  • Works fine on Desktop (safari, chrome) & android (chrome)
  • On iOS devices (safari & chrome), it throws Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
Screenshot 2024-06-21 at 14 31 11

Steps to Reproduce

  • Minimal repro link

Hi @ardasatata - in order to autoplay videos successfully without errors, the player needs to be muted. My recommendation would be to set the following parameters: ?autoplay=1&muted=1.

@rkrishnan8594 Yep, I've tried using those parameters & it works fine on ios, but every time a new video gets loaded users need to adjust their volume.

This is what I'm trying to achieve link simply a sequential video player.
I wonder why it works fine on ios with <video /> element but it doesn't work with vimeo player.js?

I finally removed the Vimeo player from my project, then used the <video /> tag with the hls.js player & loaded the external URL from the files array.
Please fix this @rkrishnan8594 you need to rework js player to be consistent across platforms (especially iOS webkit).

@rkrishnan8594 I'm experiencing the same issue. I believe this was working up until a few weeks ago

On iOS this happens when the user interacts with the browser to play the first video, video ends, ended event is fired, the next video is loaded but a Unhandled Promise Rejection is thrown when it tries to play. I don't believe this is expected behaviour as this happens after the user interacts with the page and like @ardasatata shows in his demo it's not happening with <video /> tags

Hey @ardasatata - the reason why the browser is autopausing playback in the CodePen you shared is that you're setting volume on the user's behalf after loading the second video. When commenting out that line (await player.setVolume(0.5)), I'm able to get successful continuous playback.

@rkrishnan8594 if you look at this codepen (copy of @ardasatata codepen with playinline) the videos load and play one after the other, with audio, without further user interaction both on desktop and mobile (Android and iOS).

If I understand @ardasatata 's issue correctly it is the same as mine, where that behaviour can't be replicated with the Vimeo player on iOS at the moment

Hey @ardasatata - the reason why the browser is autopausing playback in the CodePen you shared is that you're setting volume on the user's behalf after loading the second video. When commenting out that line (await player.setVolume(0.5)), I'm able to get successful continuous playback.

@rkrishnan8594 Just in case you can't replicate it on your ios device,
I even commented on setVolume line.

RPReplay_Final1721835550_480.mov

@rkrishnan8594 it seems the underlying problem is still present. Could we reopen this issue? @ardasatata and I have added some additional details, it'd be great to know at least if this is the expected behaviour in this context

+1 on reopening this issue ๐Ÿ™
It makes sense that the initial video has to be muted to autoplay, but if I unmute that and then load a different video, it should be able to autoplay with sound. @jmorgadosoares's codepen shows that it's generally possible

Hi @rkrishnan8594 - I wanted to check in on this issue as it's been a few weeks since the last update. There is a bit more context from myself and @ardasatata showing the player is not behaving as intended

Appreciate you all have a lot on your plate! Thanks in advance

Hi folks - thanks for your patience on this. I can explain the reason why this behavior changed. Back in June, Vimeo rolled out an update to how player.loadVideo() works that reloads the <iframe> element rather than loading a new video into the existing player runtime and <video> element. This was a necessary change to improve the security of our player. Unfortunately, replacing the <video> element means that any previous interactions a user may have had with the first element are not carried over, and they will need to interact with the element again in order for programmatic volume control to work successfully (otherwise, it will be prevented by the browser).

Thanks for clarifying @rkrishnan8594 that's a shame this behaviour is not achievable on iOS.

Although, if that's the case it's odd that it even works on Android at all, no?

Yeah, it's a bit odd that it's different. It's possible that on Android Chrome, the browser remembers user interactions on the browsing context level or parent page level.

@rkrishnan8594 Thanks for the explanation, it all makes sense now, I knew that it worked fine previously but then it suddenly stopped working around June, well ios webkit can be weird sometimes