Background playback and media controls
Playback can continue when the viewer switches tab or app or locks the phone, and the stream shows in the OS media controls: the Android media notification, the iPhone lock screen and Chrome's media button. Both are on by default with every decoder, including webcodecs.
import { Vindral } from "@vindral/web-sdk"
const instance = new Vindral({
url: "https://lb.cdn.vindral.com",
channelId: "...",
backgroundPlayEnabled: true, // default: keep playing while the page is hidden
mediaSessionEnabled: true, // default: show the stream in the OS media controls
mediaSessionMetadata: {
title: "Live stream",
artwork: [{ src: "https://example.com/artwork.png", sizes: "512x512" }],
},
})
Options
| Option | Default | Behavior |
|---|---|---|
backgroundPlayEnabled | true | false disconnects while hidden and reconnects on return. Replaces the deprecated iosBackgroundPlayEnabled. |
mediaSessionEnabled | true | Shows the stream in the OS media controls and routes their play and pause to the SDK. |
mediaSessionMetadata | Page metadata | Title, artist, album and artwork, read once at construction. |
Option names across integration surfaces
| Core Web SDK | vindral-player attribute | Embed / QoS query string |
|---|---|---|
backgroundPlayEnabled | background-play-enabled | core.backgroundPlayEnabled |
mediaSessionEnabled | media-session-enabled | core.mediaSessionEnabled |
mediaSessionMetadata | title and poster | player.title and core.poster |
<vindral-player
url="https://lb.cdn.vindral.com"
channel-id="..."
title="Live stream"
poster="https://example.com/artwork.png">
</vindral-player>
Background audio
Desktop Chrome and Safari keep audio with every decoder. Audio on phones after an app switch or lock, with the stream unmuted:
| Decoder | Android Chrome | iPhone Safari |
|---|---|---|
mse (default) | Some phones pause it; resume from the media controls. | iOS pauses the video when the viewer leaves Safari or locks the phone, unless it is in PiP; resume from the lock screen. |
webcodecs or wasm | Continues. | Continues. PiP and native fullscreen need streamToMediaElementEnabled: true. |
The decoder is set with the decoders option; see WebCodecs & Offscreen Renderer.
While the page is hidden
| Situation | Behavior |
|---|---|
backgroundPlayEnabled: false | Disconnects; reconnects on return. |
pause(), or pause from the media controls | Disconnects at once; playing again reconnects. |
| Muted and not in PiP, or paused by the browser | Disconnects within 15 seconds; reconnects on return. |
Media controls
The stream shows in the controls while it is unmuted, and play and pause there reach the SDK. With several instances on a page, one owns the controls, normally the last to start playing unmuted.
| Goal | Options |
|---|---|
| Keep an instance out of the controls | mediaSessionEnabled: false on that instance |
| Run your own Media Session handlers | mediaSessionEnabled: false, and call play() and pause() from the handlers |
Set them only with mediaSessionEnabled: false; handlers set later replace the SDK's. With your own handlers, mse still shows the browser's controls; webcodecs and wasm show none in Chrome and desktop Safari, and on iPhone without streamToMediaElementEnabled the audio stops under lock; see Limitations.
Limitations
| Platform | Setup | Limitation |
|---|---|---|
| iPhone | DRM | DRM always uses mse on every platform; on iPhone that means the audio keeps playing in the background only in Picture-in-Picture. |
| iPhone | webcodecs or wasm with both streamToMediaElementEnabled and mediaSessionEnabled off | The audio stops when the phone locks and needs a tap to resume. The SDK emits needs user input: show an unmute control, as vindral-player does with its mute button. |
| iPhone | webcodecs or wasm with streamToMediaElementEnabled: true | After a long pause from the lock screen, iOS suspends the page and the lock-screen controls disappear; reopen Safari to resume. |
| iPhone | webcodecs or wasm with streamToMediaElementEnabled: true, in native fullscreen | After locking, the lock-screen controls show a play button while the audio plays. |
| Android | webcodecs or wasm, page hidden | Another app's audio, an alarm or unplugged headphones pause playback and remove the media controls; with webcodecs, so does a pause from the controls. Resume from the page. |
Testing with the QoS client
Open a link in the QoS client, unmute, then lock the phone or open PiP. In its settings, backgroundPlayEnabled is the Enable Background Play toggle; the other two options are query string only.
- Background audio and media controls: the defaults with the
webcodecsdecoder - No media controls:
core.mediaSessionEnabled=false - No background playback:
core.backgroundPlayEnabled=false, leaving the page stops playback and returning reconnects
Decode Performance shows the active decoder and Media Session in Playback shows whether this player owns the controls.