Skip to content

Extend permission-policy negotiation for media/video widgets (fullscreen, presentation/Cast, remote-playback, PiP, encrypted-media) #757

Description

@lukaskroepfl

We built a video-streaming MCP App to see how far video can go inside a widget: a Bitmovin player with VOD, live, DRM, and a Netflix-style browse UI. A lot of it already works. MSE, Web Workers, WASM, muted autoplay, and EME/DRM (Widevine) all run fine in the sandbox.

@Isalomon asked me on Discord to write up the use cases and requirements, so here they are.

Two mechanisms already cover part of this, and I want to be clear I'm building on them rather than proposing something from scratch:

  • Display modes (fullscreen / pip) resize the host container.
  • Permission-policy negotiation grants camera, microphone, geolocation, clipboard-write, since those were what people asked for so far.

The request is to add the media features to that same negotiation list, plus fix one specific gap in the fullscreen display mode.

Use cases

1. Fullscreen that fills the display

Video wants the whole screen for couch or TV viewing, with the host and OS chrome out of the way. We used the host fullscreen display mode instead of calling the Fullscreen API ourselves. What we measured is that the widget only grew to the host browser viewport, roughly 1280×1272 in our setup, and never reached the 2560×1440 monitor. That makes sense: from a windowed browser tab the display mode can't grow past the window itself. Only the Fullscreen API can take over the physical screen.

So for real fullscreen video we'd need one of two things: the fullscreen display mode able to reach true screen fill, or fullscreen added to the permission negotiation so the app can call requestFullscreen(). The second one is the reliable path for our case.

2. Casting to a TV

Users expect to send a stream to a Chromecast. In our widget the Cast sender SDK loads and chrome.cast.isAvailable returns true, but CastContext.getCastState() stays at NO_DEVICES_AVAILABLE and no receiver ever shows up, because the frame has no allow="presentation". I checked this with a real Chromecast on the same network in a normal Chrome window, and the result is identical whether the player runs at the top level or inside an iframe. The only difference is the missing permission.

Adding presentation (and remote-playback for the Remote Playback API) to the negotiation would cover this. One caveat worth raising early: presentation only helps if the host runtime actually has a Media Router. If that isn't guaranteed across hosts, a host-mediated handoff might be the more robust design, where the app passes a stream URL plus DRM info and start position to the host, and the host owns the device picker and the cast session.

3. Picture-in-Picture

Let someone keep watching while they do something else in the host. This needs picture-in-picture.

4. DRM / encrypted-media

Widevine playback works today, which suggests encrypted-media is already granted or EME is running same-origin. I'd like it to become an explicit, negotiable feature so DRM content behaves the same across hosts rather than depending on current behavior.

5. Autoplay with sound

Muted autoplay works. Adding autoplay would let a user-initiated play start with sound.

Proposed shape

Extend the existing permission-policy negotiation (the same path as camera / microphone / geolocation) with fullscreen, presentation, remote-playback, picture-in-picture, encrypted-media, and autoplay, each behind the consent surface where that fits. Most of these are extra tokens on the allow list and don't need new architecture. Casting is the one that may need more thought because of the runtime dependency.

Repro

We have a small capability-probe widget that live-tests EME key systems, MSE-in-worker, fullscreen confinement, Presentation and Remote Playback availability, and autoplay policy. Happy to share it if a reproducible harness would help with scoping.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions