Interface: UsePlayerOptions
Defined in: packages/player/src/hooks/usePlayer.ts:8
Options for usePlayer.
Extends
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.
Inherited from
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.
Inherited from
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.
Inherited from
logLevel?
readonly optional logLevel?: PlayerLogLevel;
Defined in: packages/player/src/player.ts:457
mpv log verbosity. Defaults to mpv's warn.
Inherited from
loop?
readonly optional loop?: LoopMode;
Defined in: packages/player/src/player.ts:550
Initial repeat behaviour.
Inherited from
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.
Inherited from
muted?
readonly optional muted?: boolean;
Defined in: packages/player/src/player.ts:546
Initial mute state.
Inherited from
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.
Inherited from
PlayerOptions.networkReconnect
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
Inherited from
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.
Inherited from
PlayerOptions.prefetchPlaylist
rate?
readonly optional rate?: number;
Defined in: packages/player/src/player.ts:548
Initial playback rate.
Inherited from
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.
Inherited from
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.
Inherited from
PlayerOptions.resolverTimeoutMs
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.
Inherited from
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.
Inherited from
setup?
readonly optional setup?: (player: Player) => void | Promise<void>;
Defined in: packages/player/src/hooks/usePlayer.ts:15
Run once, right after the player is created and before it is handed to
the component — the place to load() an initial source.
A rejected promise is reported through UsePlayerResult.error.
Parameters
| Parameter | Type |
|---|---|
player | Player |
Returns
void | Promise<void>
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.
Inherited from
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.
Inherited from
volume?
readonly optional volume?: number;
Defined in: packages/player/src/player.ts:544
Initial volume in 0..1.