[webkit-dev] Questions about concurrent <video> playback restrictions on Mobile Safari.
Jer Noble
jer.noble at apple.com
Wed May 14 13:48:57 PDT 2025
Hi Yury,
This is a longstanding policy whose intent was to match the overall system behavior where multiple apps are prevented from playing audible content simultaneously.
While it is true that, originally, all video+audio playback required that playback to take place in fullscreen mode. But since fullscreen mode itself was something of a singleton, that mechanism already prevented multiple video elements from playing simultaneously.
I am sympathetic to the video conferencing use case to allow multiple MediaStream-backed video elements to play simultaneously. However, IMO relaxing this policy for all video elements with no opt-in would lead to some pretty terrible behavior on unsophisticated web sites.
All that said, we’re currently investigating the idea of assigning particular AudioSessions to individual HTMLMediaElements. When multiple elements share a single AudioSession, that seems to be a good signal that those media elements can play simultaneously. Let’s figure out if that kind of more declarative, opt-in approach can solve the video conferencing use case.
-Jer
> On May 13, 2025, at 5:12 AM, Yury Yarashevich <yura.yaroshevich at gmail.com> wrote:
>
> Hi Eric Carlson, Jer Noble,
>
> Could you please join the discussion to help assess whether the restriction on concurrent playback of multiple <video> elements with audio is still necessary on iOS?
>
> I’ve traced the origin of this restriction back to Bug 126780 <https://bugs.webkit.org/show_bug.cgi?id=126780>, which was addressed in this commit <https://github.com/WebKit/WebKit/commit/5ae5b76ad011a7ed3bd964184b268c672a61fdcc> by Eric Carlson in January 2014. Unfortunately, the bug description doesn’t clearly explain what was meant by “Some platforms do not allow more than one <video> element to play concurrently,” so the exact rationale remains unclear.
>
> Later, in October 2016, inline playback via <video> on iOS was introduced (blog post <https://webkit.org/blog/6784/new-video-policies-for-ios/>) through this commit <https://github.com/WebKit/WebKit/commit/99efb5e8e4efa797684804f65a4eeec119096f7c> by Jer Noble. However, the concurrent playback restriction for multiple audible videos still remains in effect on iOS.
>
> After digging through the history, the original motivation behind this restriction is still not fully clear. One possible explanation is that, prior to the introduction of playsinline, video playback on iOS was always fullscreen - so automatically pausing other videos might have made sense to avoid background playback. But in today’s usage patterns, this seems more like a concern for the web application to manage rather than something enforced by the platform.
>
> This restriction has repeatedly caused issues in scenarios such as WebRTC-based video conferencing, as noted in the bug tracker. While WebRTC is one example, my primary interest is in supporting concurrent playback of multiple <video> elements delivering audio/video over LL-HLS. In such cases, this restriction still applies and leads to playback interruptions - even though technically there are no hard constraints that should prevent smooth, simultaneous playback.
>
> So I’d like to ask: if there are no longer any technical or policy reasons to enforce this restriction, could it be reconsidered and potentially lifted?
>
> If it’s decided that this restriction is no longer needed, I’d be happy to begin working on a patch to lift it.
>
> Thanks for your time and consideration!
>
>
>
> On Wed, Apr 30, 2025 at 4:01 PM Yury Yarashevich <yura.yaroshevich at gmail.com <mailto:yura.yaroshevich at gmail.com>> wrote:
>> 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 <mailto: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 <mailto: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
>>> <mdn-social-share.d893525a4fb5fb1f67a2.png>
>>> Autoplay guide for media and Web Audio APIs - Media technologies on the web | MDN
>>> developer.mozilla.org
>>> <https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Autoplay>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>
>>> Here is a more WebKit-focus article
>>> Auto-Play Policy Changes for macOS
>>> webkit.org
>>> <apple-touch-icon-precomposed.png>
>>> <https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/>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/> <apple-touch-icon-precomposed.png> <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
>>>
>>> <liam-neeson-will-find-a2c50097288a9.jpeg>
>>> Autoplay policy in Chrome | Blog | Chrome for Developers
>>> developer.chrome.com
>>> <https://developer.chrome.com/blog/autoplay/>Autoplay policy in Chrome | Blog | Chrome for Developers <https://developer.chrome.com/blog/autoplay/>
>>> developer.chrome.com <https://developer.chrome.com/blog/autoplay/>Here is the HTML5 specifications related to this matter
>>>
>>> HTML Standard
>>> spec.whatwg.org
>>>
>>> <https://html.spec.whatwg.org/multipage/media.html#eligible-for-autoplay>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>
>>>> 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/20250514/e7d3d0d4/attachment.htm>
More information about the webkit-dev
mailing list