MediaByteOpener

fun interface MediaByteOpener

Opens the other addresses that media read through a MediaByteSource refers to.

An HLS playlist names more bytes than its own: its variant playlists, its segments and its encryption keys. FFmpeg asks for each of them by address, and open answers with the bytes at that address. Pass an opener to the byte-source MediaSource.open together with the playlist's url, so that the relative addresses in the playlist resolve against it.

  • An address arrives absolute, for example https://cdn.example/live/seg-12.ts.

  • An AES-128 segment arrives as the address of its encrypted bytes. The key arrives through this opener too, and KiteFFmpeg decrypts the segment itself.

  • A live playlist asks for its own address again each time it reloads.

  • A data: address never arrives. FFmpeg reads the bytes inside it itself.

  • A byte source that came through a redirect says where it came from in MediaByteSource.location, and the addresses inside it resolve against that.

  • A byte source it returns is never asked for MediaByteSource.takeTags, because FFmpeg reads no tags from one.

The addresses come from the media, and the media is untrusted input. FFmpeg does not check the scheme of an address when a source has an opener, so the opener decides which addresses open. Open only the schemes and hosts you expect, and return null for every other address.

Threading and blocking follow MediaByteSource. Calls arrive on the thread that drives the demuxer, one at a time, and open may block, for example on a network request. A null or an exception fails that one address. FFmpeg's HLS demuxer then logs the failure and moves to the next segment, and a failure during the open fails the open.

Lifetime. The MediaSource owns every byte source that open returns. FFmpeg closes each one when it has read what it needs, and the rest close with the MediaSource.

On the web, callbacks are synchronous. In a Worker or Node, open, MediaByteSource.read and MediaByteSource.seek may perform synchronous I/O. Each child is read on demand with bounded scratch storage, without a whole-resource size cap, and remains owned until FFmpeg closes it or the parent closes. Known and unknown lengths, forward-only sources and changing MediaByteSource.size follow the same contract as the other backends. No callback may return a promise or suspend.

On a browser page, callbacks must answer from bytes already available. Each child is still staged whole into the codec module's memory, up to 512 MiB, and closed straight away. A finite source of unknown length is staged to EOF within that bound. Use a Worker for streaming or synchronous range requests. The backend does not perform HTTP requests or choose their policy.

Functions

Link copied to clipboard
abstract fun open(url: String): MediaByteSource?

The bytes at url, or null to refuse the address.