[webkit-dev] Questions about concurrent <video> playback restrictions on Mobile Safari.
Yury Yarashevich
yura.yaroshevich at gmail.com
Wed Apr 30 07:01:33 PDT 2025
Hi Jean-Yves,
Thanks for the quick and detailed response, and for the helpful links.
> Are you referring to audible video elements requiring a user gesture for
playback to start?
To clarify, I’m aware of the standard autoplay policies and user gesture
requirements for unmuted playback, and I agree that those are
well-documented and expected.
What I’m describing appears to be a distinct issue - not about autoplay
initiation, but about ongoing playback being unexpectedly paused by the
browser after it has already started, particularly when multiple unmuted
<video> elements are playing concurrently. This happens even after a proper
user gesture and successful play() call.
> I’m not aware of any such restrictions.
After capturing logs and digging into the WebKit source code, I found that
the restriction I’m referring to is implemented as follows::
1. The `ConcurrentPlaybackNotPermitted` policy is enforced only on iOS,
which explains why there’s no issue on macOS (I haven’t tested on iPad).
Source code:
https://github.com/WebKit/WebKit/blob/45d0c14d08a78058a88d16460f1fbc10946634c0/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm#L85
2. The logic that iterates over all media elements and enforces pause is
here:
https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp#L292-L300
3. The implementation of the "can play concurrently" check, which
effectively disallows concurrent playback of audible media unless the
source is a MediaStream, is here:
https://github.com/WebKit/WebKit/blob/45d0c14d08a78058a88d16460f1fbc10946634c0/Source/WebCore/platform/audio/PlatformMediaSession.cpp#L377-L390
4. There are also tests that explicitly verify that calling play() on one
video element pauses all others:
a)
https://github.com/WebKit/WebKit/blob/main/LayoutTests/media/video-concurrent-playback-expected.txt
;
b)
https://github.com/WebKit/WebKit/blob/main/LayoutTests/media/video-multiple-concurrent-playback-expected.txt
.
To demonstrate the issue, I’ve created a test page:
https://mstyura.github.io/webkit-issues/audible-video-concurrent-playback/index.html
It contains 4 HLS video elements and two buttons: “Play All” and “Pause
All.”
Clicking “Play All” results in only one video playing effectively.
Repeating the action multiple times shows that behavior is
non-deterministic.
There’s also a “workaround mode” that starts all videos muted. In that
case, all 4 videos initially play—but later WebKit sometimes detects
concurrent playback (during media element time updates from
HTMLMediaElement::updatePlayState
https://github.com/WebKit/WebKit/blob/156848f5d55261b92551457dec064ff946ca45b9/Source/WebCore/html/HTMLMediaElement.cpp#L6398)
and starts pausing them again.
This leads to the observed ping-pong effect between JavaScript and WebKit.
Demo source:
https://github.com/mstyura/WebKit-Issues/blob/main/audible-video-concurrent-playback/index.html
My question is:
Is this behavior still considered desirable in 2025, especially given that
developers can bypass it with more complex (but less power-efficient)
workarounds like WebCodecs + <canvas> or/and VideoTrackGenerator +
AudioContext.createMediaStreamDestination()?
Thanks again for your time and insights!
On Wed, Apr 30, 2025 at 2:28 PM Jean-Yves Avenard <
jean-yves.avenard at apple.com> wrote:
>
>
> On 30 Apr 2025, at 9:57 pm, Yury Yarashevich via webkit-dev <
> webkit-dev at lists.webkit.org> wrote:
>
> Hi WebKit team,
>
> I’m curious about the original rationale behind the restriction that
> prevents concurrent playback of multiple <video> elements. Was it
> primarily introduced to save battery life?
>
>
> I’m not aware of any such restrictions.
>
> Here is a test page that will literally let you play hundreds of video
> elements at the same time.
>
> It works on any Apple devices: iPhone, iPad, Vision Pro, Mac .
>
> In practice, this behavior appears to have unintended side effects.
> There’s a reproducible issue where playback can be started with the video
> muted and then immediately unmuted, effectively bypassing the restriction.
> However, this often results in videos being randomly paused later—sometimes
> very frequently—leading to a “play/pause ping-pong” between Safari/WebKit
> and JavaScript restarting playback. This erratic behavior may actually
> *increase* battery consumption, despite appearing to work smoothly from
> the user’s perspective.
>
> Are you referring to audible video elements requiring a user gesture for
> playback to start?
>
> This behaviour isn’t erratic and is well defined and and up to know I
> thought it was well understood. For an audible element to play, the user
> needs to first interact with the video element such as clicking on the
> video or its controls.
> This behaviour is even defined through HTML5 specifications including how
> you can detect if the User Agent will allow video to start autoplaying
> without a user gesture.
>
> Similar policies are implemented by other user agents such as Firefox and
> Chrome.
> There’s an article on MDN on how to deal with them
> [image: mdn-social-share.d893525a4fb5fb1f67a2.png]
>
> Autoplay guide for media and Web Audio APIs - Media technologies on the
> web | MDN
> <https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Autoplay>
> developer.mozilla.org
> <https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Autoplay>
> <https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Autoplay>
>
> Here is a more WebKit-focus article
> Auto-Play Policy Changes for macOS
> <https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/>
> webkit.org
> <https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/>
> [image: apple-touch-icon-precomposed.png]
> <https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/>
> <https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/>
>
>
> Here is a similar article written by the Chrome team on the same topic
>
> [image: liam-neeson-will-find-a2c50097288a9.jpeg]
>
> Autoplay policy in Chrome | Blog | Chrome for Developers
> <https://developer.chrome.com/blog/autoplay/>
> developer.chrome.com <https://developer.chrome.com/blog/autoplay/>
> <https://developer.chrome.com/blog/autoplay/>
> Here is the HTML5 specifications related to this matter
>
> HTML Standard
> <https://html.spec.whatwg.org/multipage/media.html#eligible-for-autoplay>
> spec.whatwg.org
> <https://html.spec.whatwg.org/multipage/media.html#eligible-for-autoplay>
> <https://html.spec.whatwg.org/multipage/media.html#eligible-for-autoplay>
> <https://html.spec.whatwg.org/multipage/media.html#eligible-for-autoplay>
>
> Even if this workaround is eventually blocked, developers who rely on
> concurrent playback (e.g., outside of WebRTC contexts) will turn to more
> complex solutions, such as decoding video and audio using WebCodecs or/and
> WebAssembly, and rendering via <canvas> and AudioContext. While
> technically feasible, these approaches are likely to be significantly less
> power-efficient than simply allowing multiple <video> elements to play
> concurrently.
> Another similarly inefficient workaround would be to synthesize a
> MediaStream using the VideoTrackGenerator API and
> AudioContext.createMediaStreamDestination().
>
> Lastly, another issue is that creating a MediaElementSource from a <video> element
> and routing its audio through a shared AudioContext also does not disable
> the playback restriction—whereas it *is* disabled when the <video> element
> itself is muted. This feels inconsistent and may point to a separate bug.
>
> Could you please clarify the motivation behind this restriction, and
> whether there are any plans to revisit or improve its behavior?
>
>
> I believe I answered this question above, and through the various links
> provided.
>
>
> Cheers
> JY
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20250430/48ab751d/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mdn-social-share.d893525a4fb5fb1f67a2.png
Type: image/png
Size: 71650 bytes
Desc: not available
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20250430/48ab751d/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: apple-touch-icon-precomposed.png
Type: image/png
Size: 16691 bytes
Desc: not available
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20250430/48ab751d/attachment-0003.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: liam-neeson-will-find-a2c50097288a9.jpeg
Type: image/jpeg
Size: 39054 bytes
Desc: not available
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20250430/48ab751d/attachment-0001.jpeg>
More information about the webkit-dev
mailing list