Skip to content

Native subtitle rendition (AVMediaSelection / WebVTT) so subtitles survive PiP, AirPlay & external display #55

Description

@edde746

What should the engine do?

Optionally emit the active subtitle as a native HLS subtitle rendition (#EXT-X-MEDIA:TYPE=SUBTITLES → WebVTT, served by HLSLocalServer from the already-decoded cues) and expose it through the legible AVMediaSelectionGroup, so AVPlayer renders the subtitle itself. That is the only way subtitles can survive Picture-in-Picture, AirPlay, and external-display playback, where a host-drawn overlay never appears.

Motivating media or use case

Scenario: a tvOS/iOS client playing any title with an embedded or sidecar text subtitle (e.g. an MKV with an embedded ASS dialogue track, or a .srt/.vtt sidecar) where the user turns on Picture-in-Picture, AirPlay, or connects an external display.

Today: subtitles are surfaced to the host as decoded cues ($subtitleCues + the preserveASSMarkup/assHeader host-render contract from #30/#48) and the host paints them with swift-ass renderer. That works inline, but the overlay is a sibling layer outside the AVPlayerItem's video output, so subtitles disappear the moment playback moves to PiP / AirPlay / external display.

Why a host can't fix this itself (so this has to live in the engine):

  • A host overlay view (or AVPlayerViewController.contentOverlayView) is not shown in PiP by AVKit,
    and isn't sent over AirPlay / to an external display.
  • The AssVideoComposition CoreImage videoComposition route can't be used either — CIFilter video
    compositions are unsupported on HLS assets
    , and the engine plays the loopback media.m3u8 /
    master.m3u8. So there is no host-side path to get rendered subtitles into the frames AVPlayer emits.

The only thing the OS renders in PiP/AirPlay is what lives inside the AVPlayerItem — i.e. a native
legible selection. This also lines up with the AVMediaSelection wiring is a tracked follow-up note in
AetherEngine.subtitleCues's doc comment; VideoSegmentProvider.masterClosedCaptions is currently
"NONE" and there's no EXT-X-MEDIA:TYPE=SUBTITLES rendition.

Area

Public API surface

Host app / integration context

No response

Would you be willing to open a PR?

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions