Skip to main content

Interface: PlayerOptions

Defined in: packages/player/src/player.ts:440

Options for Player.create.

Extended by

Properties

cacheSecs?

readonly optional cacheSecs?: number;

Defined in: packages/player/src/player.ts:479

How far ahead the demuxer may read on a network stream, in seconds (mpv's cache-secs).

Defaults to DEFAULT_CACHE_SECS (30 s) — a deliberate override of mpv's own 1000-hour default; read that constant's docs for the reasoning and the trade-off. Must be a finite number >= 0, which is mpv's own range for the option (M_RANGE(0, DBL_MAX), demux/demux.c, mpv 0.35.1).

A raw mpvOptions['cache-secs'] still wins over this.


createClient?

readonly optional createClient?: MpvClientFactory;

Defined in: packages/player/src/player.ts:622

Override how the underlying MpvClient is created.

Production code never sets this; it exists so tests (and, later, the video plugin) can supply their own client. When omitted, the real Nitro HybridObject is loaded lazily — which is why nothing outside this default path imports react-native-nitro-modules.


gaplessAudio?

readonly optional gaplessAudio?: GaplessAudioMode;

Defined in: packages/player/src/player.ts:521

Whether the audio device is kept open across a playlist entry change, which is what makes a transition gapless (mpv's gapless-audio).

Left unset, mpv's own default 'weak' applies: gapless whenever consecutive entries decode to the same output format, and a device reopen — a short gap — when they do not. See GaplessAudioMode for each value's cost, and why this library deliberately does not force 'yes'.

Orthogonal to prefetchPlaylist: this one keeps the output alive, that one opens the next input early. On a network queue you generally want both, because a device that never closed still runs dry if the next entry's first packets have not arrived.

A raw mpvOptions['gapless-audio'] still wins over this.


logLevel?

readonly optional logLevel?: PlayerLogLevel;

Defined in: packages/player/src/player.ts:457

mpv log verbosity. Defaults to mpv's warn.


loop?

readonly optional loop?: LoopMode;

Defined in: packages/player/src/player.ts:550

Initial repeat behaviour.


mpvOptions?

readonly optional mpvOptions?: Readonly<Record<string, string>>;

Defined in: packages/player/src/player.ts:455

Raw mpv options applied before mpv_initialize().

Audio-only defaults (vid=no, force-window=no, idle=yes, audio-display=no) are applied natively first, and this library's own option defaults (user-agent, see DEFAULT_USER_AGENT, and cache-secs, see DEFAULT_CACHE_SECS) are merged underneath this map — so anything here wins over all of them.

Remarks

Option order is not preserved (the native layer takes a map), so profile and include — whose effect depends on where they appear — are not supported here. Set them with setProperty* after creation instead.


muted?

readonly optional muted?: boolean;

Defined in: packages/player/src/player.ts:546

Initial mute state.


networkReconnect?

readonly optional networkReconnect?: NetworkReconnectOptions;

Defined in: packages/player/src/player.ts:537

FFmpeg's native HTTP reconnection, on by default. See NetworkReconnectOptions — including exactly what it covers, what it deliberately does not, and why one FFmpeg option is left off.

A raw mpvOptions['stream-lavf-o'] replaces it wholesale.


now?

readonly optional now?: () => number;

Defined in: packages/player/src/player.ts:627

Clock used for position projection and event timestamps. Defaults to Date.now. Injected by tests.

Returns

number


prefetchPlaylist?

readonly optional prefetchPlaylist?: boolean;

Defined in: packages/player/src/player.ts:503

Open the next playlist entry while the current one is finishing, so a gapless transition does not have to pay for a fresh network connection (mpv's prefetch-playlist, default no).

Remarks

Quoting mpv 0.35.1 options.rst verbatim, because this option trades correctness for latency and callers should opt in with their eyes open:

This merely opens the URL of the next playlist entry as soon the current URL is fully read. […] This can give subtly wrong results if per-file options are used, or if options are changed in the time window between prefetching start and next file played. This can occasionally make wrong prefetching decisions. For example, it can't predict whether you go backwards in the playlist, and assumes you won't edit the playlist.

So: if your app mutates the queue (playlist.move, playlist.remove, playlist.shuffle) or seeks backwards through it while a track is ending, mpv may have already opened — and paid for — the wrong entry. It also does not prefill the cache; only the current entry's data is cached.

A raw mpvOptions['prefetch-playlist'] still wins over this.


rate?

readonly optional rate?: number;

Defined in: packages/player/src/player.ts:548

Initial playback rate.


replayGain?

readonly optional replayGain?: ReplayGainOptions;

Defined in: packages/player/src/player.ts:529

Loudness normalisation from the file's ReplayGain tags. See ReplayGainOptions; change it later with Player.setReplayGain.

Raw mpvOptions['replaygain*'] entries still win over this.


resolverTimeoutMs?

readonly optional resolverTimeoutMs?: number;

Defined in: packages/player/src/player.ts:605

How long a play-time resolution may hold mpv's core while the resolver answers, in milliseconds. Defaults to DEFAULT_RESOLVER_TIMEOUT_MS (10 s); 0 means never hold, i.e. only pre-resolved URIs are ever rewritten.

Must be a finite number >= 0.

Remarks

This budget is spent between entries, with the new entry not yet open and the previous one already ended — there is no audio of the new track to starve. It is not spent on the prefetch path, which never waits at any value: that hook fires mid-track over live audio with only the device buffer behind it, so a cache miss there is answered by letting mpv continue immediately and warming the cache for the play-time pass.

On timeout the logical URI is used unchanged, mpv fails the load on its own terms, and the failure arrives as an ordinary typed error event.

What the hold actually parks. The wait happens on the native event thread — the same thread that drains mpv's event queue — so for its duration nothing crosses into JavaScript: no property changes, and no command replies. A play()/seekTo()/command() Promise issued while an unresolved play-time load is in flight therefore does not settle until the resolution completes or this budget expires. The player is not wedged (the hold is bounded and mpv resumes normally afterwards), but a UI that awaits one of those Promises will look stalled for up to this long.

The mitigation is the design's main path, not a workaround: resolve-ahead answers the current and next entries as the queue moves, typically a whole track before mpv asks, so a hit costs a native map lookup and this path stays cold. Keep your resolver deterministic (see SourceResolver) so the answers stay cacheable, and lower this value if your app would rather fail a load fast than have its transport Promises wait.

Waiting off the event thread — parking a dedicated waiter and letting mpv_wait_event keep draining — was considered and deliberately deferred: it means a second synchronisation object, a hook continuation issued from a thread that did not receive the hook, and a new class of ordering bug, all to improve a path that resolve-ahead is designed to make rare. It is recorded in the as-built spec as the known cost of the simpler design rather than pretended away.


resolverTtlMs?

readonly optional resolverTtlMs?: number;

Defined in: packages/player/src/player.ts:613

How long one resolved URL stays usable, in milliseconds. Defaults to DEFAULT_RESOLVER_TTL_MS (10 min).

Must be a finite number >= 0. A 0 disables caching entirely, which also disables prefetching for resolved sources — see SourceResolver.


retry?

readonly optional retry?: RetryOptions;

Defined in: packages/player/src/player.ts:542

Re-attempt a failed entry before letting the queue advance past it. See RetryOptions.


sourceResolver?

readonly optional sourceResolver?: SourceResolver;

Defined in: packages/player/src/player.ts:561

Turn the logical URIs in your queue into the URLs mpv actually opens — signed CDN links, transcode sessions, anything that cannot be written down ahead of time.

Setting it here rather than calling Player.setSourceResolver after create() means it is installed before anything can be loaded, so the very first entry is resolved ahead of time like every other one. See SourceResolver for the determinism requirement.


userAgent?

readonly optional userAgent?: string;

Defined in: packages/player/src/player.ts:467

HTTP User-Agent for network playback. Defaults to DEFAULT_USER_AGENT rather than mpv's own libmpv, because real streaming hosts blocklist the literal string libmpv (observed on-device: a Shoutcast DNAS v2 server returning 401 Unauthorized for exactly User-Agent: libmpv while accepting any other value, including timbre/0.1 (libmpv)). A raw mpvOptions['user-agent'] still wins over this option.


volume?

readonly optional volume?: number;

Defined in: packages/player/src/player.ts:544

Initial volume in 0..1.