Interface: MpvClient
Defined in: packages/player/src/specs/mpv-client.nitro.ts:293
A thin, complete binding over one mpv_handle (one mpv_create() core).
One instance == one player core; create as many as you need via
createMpvClient(). There is no singleton and no shared state between
instances.
All methods except destroy throw if the client has already been
destroyed. Thrown messages are prefixed with a machine-readable tag —
[mpv:disposed] for use-after-destroy, [mpv:<errno>] for mpv errors —
so the TypeScript layer can map them onto the typed error taxonomy.
Extends
HybridObject<{android:"c++";ios:"c++"; }>
Properties
name
readonly name: string;
Defined in: node_modules/react-native-nitro-modules/lib/typescript/HybridObject.d.ts:52
The HybridObject's name.
Inherited from
HybridObject.name
Methods
attachVideoOutput()
attachVideoOutput(handle: UInt64): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:588
Reserved for the future video plugin. Always throws [mpv:unsupported]
in the audio core.
Parameters
| Parameter | Type |
|---|---|
handle | UInt64 |
Returns
void
clearResolvedSources()
clearResolvedSources(): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:562
Forget every resolution. The next hook asks JavaScript again.
Returns
void
command()
command(args: string[]): Promise<void>;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:337
Run an mpv command (mpv_command_async).
Resolves on MPV_EVENT_COMMAND_REPLY with no error, rejects with mpv's
error string otherwise.
Parameters
| Parameter | Type |
|---|---|
args | string[] |
Returns
Promise<void>
completeResolution()
completeResolution(
logical: string,
resolved: string | undefined,
ttlMs: number
): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:578
Answer a SourceResolutionRequest.
A successful answer is cached (so the play-time on_load pass for the same
entry replays it verbatim — mpv compares the pre- and post-hook URLs
byte-for-byte to decide whether the prefetched stream can be reused) and
releases a matching play-time hold. undefined means "could not resolve":
nothing is cached and the hook continues unrewritten, letting mpv fail the
load on its own terms.
Parameters
| Parameter | Type | Description |
|---|---|---|
logical | string | The uri of the request being answered. |
resolved | string | undefined | The concrete URL, or undefined. |
ttlMs | number | How long a successful answer stays cached. |
Returns
void
destroy()
destroy(): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:329
Stop the event loop and tear the core down. Idempotent.
mpv_terminate_destroy (which blocks) runs on a detached background
thread; this call only joins the event thread. Pending command()
promises reject with [mpv:disposed]. Every other method throws
afterwards — it never crashes.
Returns
void
detachVideoOutput()
detachVideoOutput(): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:593
Reserved for the future video plugin. Always throws [mpv:unsupported]
in the audio core.
Returns
void
dispose()
dispose(): void;
Defined in: node_modules/react-native-nitro-modules/lib/typescript/HybridObject.d.ts:94
Disposes any resources this HybridObject might hold natively,
and releases this HybridObject's NativeState.
After calling (), this object can no longer be used.
Eagerly disposing a HybridObject could be beneficial for a queue-/handler-architecture
where a bunch of Hybrid Objects are allocated, and later deallocated once a callback (e.g. a render function)
completes.
Returns
void
Note
It is NOT required to call () manually, as the JavaScript
Garbage Collector automatically disposes and releases any resources when needed.
It is purely optional to eagerly-, and manually-, call () here - use with caution!
Inherited from
HybridObject.dispose
equals()
equals(other: HybridObject<{
android: "c++";
ios: "c++";
}>): boolean;
Defined in: node_modules/react-native-nitro-modules/lib/typescript/HybridObject.d.ts:79
Returns whether this HybridObject is the same object as other.
While two HybridObjects might not be equal when compared with ==, they might still
hold the same underlying HybridObject, in which case equals(other)
will return true.
Parameters
| Parameter | Type |
|---|---|
other | HybridObject<{ android: "c++"; ios: "c++"; }> |
Returns
boolean
Example
const hybridA = SomeModule.getExistingHybridInstance()
const hybridB = SomeModule.getExistingHybridInstance()
console.log(hybridA.equals(hybridB)) // true
Inherited from
HybridObject.equals
getChapters()
getChapters(): ChapterEntry[];
Defined in: packages/player/src/specs/mpv-client.nitro.ts:416
Read the current entry's chapter-list in one MPV_FORMAT_NODE
round-trip.
[] when the entry has no chapters or mpv reports the property unavailable
(nothing loaded); the two are indistinguishable to a caller and mean the
same thing.
Returns
Remarks
Same trade as getPlaylistEntries, for the same reason. mpv also
exposes every field as a scalar sub-property (chapter-list/count,
chapter-list/N/title, chapter-list/N/time), so this could be pure
TypeScript — at 2N + 1 blocking round-trips into mpv's core, which for a
300-chapter audiobook is 601 of them, each of which "[has] to wait until
the playback core is ready […] unbounded time" (mpv/client.h). One node
read is constant and, because mpv builds the node under its own lock, it is
also the only coherent answer.
The node is walked in place and freed before this returns; nothing is retained natively.
getPlaylistEntries()
getPlaylistEntries(): PlaylistEntry[];
Defined in: packages/player/src/specs/mpv-client.nitro.ts:393
Read mpv's whole playlist in one MPV_FORMAT_NODE round-trip.
[] when the playlist is empty or mpv reports the property unavailable
(an idle core); the two are indistinguishable to a caller and mean the same
thing.
Returns
Remarks
This exists for the same reason getPropertyMap does, one level up.
The alternative is playlist-count + playlist/N/filename per entry —
N + 1 blocking round-trips into mpv's core for a list the core builds
atomically under its own lock anyway. mpv's own header warns that a
synchronous read "[has] to wait until the playback core is ready, which
currently can take an unbounded time" (mpv/client.h), so the fix is to make
the number of reads small and constant, not to make each one faster. It
is also what makes the answer coherent: a walk can interleave with a
playlist-move and return two different generations of the queue stitched
together, whereas one node read cannot.
The node is walked in place and freed before this returns; nothing is retained natively.
getPropertyBool()
getPropertyBool(name: string): boolean | undefined;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:344
Read a property as a flag. undefined if currently unavailable.
Parameters
| Parameter | Type |
|---|---|
name | string |
Returns
boolean | undefined
getPropertyMap()
getPropertyMap(name: string): Record<string, string> | undefined;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:369
Read a property whose value is a map of strings — one MPV_FORMAT_NODE
read, not a walk.
undefined when the property is currently unavailable or is not a map;
the two are indistinguishable to a caller and mean the same thing ("no map
to give you"), so they are not distinguished.
Members that are not strings are skipped rather than coerced. The one
property this exists for — metadata — is documented as a map of strings,
and inventing a rendering for an int or a byte array would be a guess
baked into a typed API.
Parameters
| Parameter | Type |
|---|---|
name | string |
Returns
Record<string, string> | undefined
Remarks
This is the reason it exists: metadata used to be assembled from
metadata/list/count + metadata/list/N/key + metadata/list/N/value,
i.e. 2N + 1 blocking round-trips into mpv's core, issued from inside
the event-batch handler at a track boundary — the exact instant mpv's core
is least able to answer (it is joining an opener thread). A 20-tag FLAC
cost 41 of them. mpv's own header warns that a synchronous read "[has] to
wait until the playback core is ready, which currently can take an
unbounded time" (mpv/client.h), so the fix is to make the number of them
small and constant, not to make each one faster.
getPropertyNumber()
getPropertyNumber(name: string): number | undefined;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:342
Read a property as a double. undefined if currently unavailable.
Parameters
| Parameter | Type |
|---|---|
name | string |
Returns
number | undefined
getPropertyString()
getPropertyString(name: string): string | undefined;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:340
Read a property as a string. undefined if currently unavailable.
Parameters
| Parameter | Type |
|---|---|
name | string |
Returns
string | undefined
getRawHandle()
getRawHandle(): UInt64;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:598
The mpv_handle* as a uintptr_t, for the future video plugin to build
an mpv_render_context on. Throws if not initialized or destroyed.
Returns
UInt64
initialize()
initialize(options: Record<string, string>): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:319
Apply pre-init options and start the core (mpv_initialize).
Audio-only defaults (vid=no, force-window=no, idle=yes,
audio-display=no) are applied natively before options, so callers can
override them. Keys are mpv option names, values mpv option strings.
The reserved key log-level is not passed to mpv as an option; it is the
argument to mpv_request_log_messages (default warn).
Also registers the two load hooks (on_load and the forks'
on_prefetch_load) — always, not on demand. The fork's guarantee that a
prefetch behaves exactly like stock mpv holds only while the hook name has
no client at all, so "register it later, when a resolver arrives" would
change the timing of the very boundary it is meant to observe. Registered
up front the handler is a pass-through until something arms it, costing one
immediate mpv_hook_continue per load boundary. See
setPrefetchStartedListener and installSourceResolver.
Throws if already initialized, already destroyed, or if mpv rejects an option / fails to initialize.
Parameters
| Parameter | Type |
|---|---|
options | Record<string, string> |
Returns
void
installSourceResolver()
installSourceResolver(timeoutMs: number): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:535
Arm the load-hook handler.
The hooks themselves (on_load, and on_prefetch_load on rn-media
binaries) are registered by initialize, always — see the note there.
This call only stores the hold budget and switches the handler from
pass-through to resolving; uninstallSourceResolver switches it back.
Parameters
| Parameter | Type | Description |
|---|---|---|
timeoutMs | number | How long a play-time on_load miss may hold mpv's core while JavaScript resolves. 0 disables holding entirely, i.e. only the pre-warmed cache is ever consulted. |
Returns
void
observeProperty()
observeProperty(name: string, format: MpvFormat): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:429
Observe name, delivering kind: 'property' events in the given format.
Observing an already-observed name replaces the previous observation.
Parameters
| Parameter | Type |
|---|---|
name | string |
format | MpvFormat |
Returns
void
setEventBatchListener()
setEventBatchListener(onEventBatch: (events: MpvEvent[]) => boolean): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:449
Register the (single) batched event listener.
Delivery is batched and coalesced natively: the first event after an idle period schedules one flush onto the JS thread, and every event queued until that flush completes rides along in it (property changes for the same name collapse to the latest value; discrete events never collapse).
The listener MUST return true to keep receiving batches; returning
false detaches it. The return value is not cosmetic — Nitro only hands
C++ a completion Promise for callbacks that return a value (a => void
callback becomes a fire-and-forget std::function<void(...)>), and that
completion signal is what bounds the number of in-flight JS hops.
Calling this again replaces the previous listener.
Parameters
| Parameter | Type |
|---|---|
onEventBatch | (events: MpvEvent[]) => boolean |
Returns
void
setPrefetchStartedListener()
setPrefetchStartedListener(onPrefetchStarted: (event: PrefetchStartedEvent) => void): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:519
Register the (single) prefetch listener. Pass before initialize.
Like setSourceResolutionListener this returns nothing and applies no back-pressure: nothing in mpv waits on it (the hook has already been continued by the time it is called), so there is no completion clock to keep.
Calling this again replaces the previous listener.
Parameters
| Parameter | Type |
|---|---|
onPrefetchStarted | (event: PrefetchStartedEvent) => void |
Returns
void
setPropertyBool()
setPropertyBool(name: string, value: boolean): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:423
Set a property from a flag. Throws on mpv error.
Parameters
| Parameter | Type |
|---|---|
name | string |
value | boolean |
Returns
void
setPropertyNumber()
setPropertyNumber(name: string, value: number): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:421
Set a property from a double. Throws on mpv error.
Parameters
| Parameter | Type |
|---|---|
name | string |
value | number |
Returns
void
setPropertyString()
setPropertyString(name: string, value: string): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:419
Set a property from a string. Throws on mpv error.
Parameters
| Parameter | Type |
|---|---|
name | string |
value | string |
Returns
void
setResolvedSource()
setResolvedSource(
logical: string,
resolved: string,
ttlMs: number
): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:559
Pre-seed the resolution cache, so a load hook never has to ask.
This is the whole point of the design: a cache hit inside a hook is a map lookup plus one property write, with no JavaScript anywhere near mpv's core.
Parameters
| Parameter | Type | Description |
|---|---|---|
logical | string | The URL as it appears in mpv's playlist. |
resolved | string | What mpv should open instead. |
ttlMs | number | How long the answer stays valid. <= 0 stores nothing. |
Returns
void
setSourceResolutionListener()
setSourceResolutionListener(onRequest: (request: SourceResolutionRequest) => void): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:505
Register the (single) source-resolution listener. Pass before installSourceResolver.
Unlike the other two listeners this one returns nothing: there is no back-pressure to apply, because the answer comes back through completeResolution rather than through a completion promise.
Calling this again replaces the previous listener.
Parameters
| Parameter | Type |
|---|---|
onRequest | (request: SourceResolutionRequest) => void |
Returns
void
setVisualizerListener()
setVisualizerListener(onCapture: (capture: VisualizerCapture) => boolean): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:491
Register the (single) visualizer listener. Pass before startVisualizer.
As with setEventBatchListener, the listener MUST return true to
keep receiving captures; returning false detaches it. The returned
completion promise is the back-pressure clock — exactly one capture is in
flight at a time, and ticks that arrive while JavaScript is still busy are
dropped rather than queued, because a stale spectrum has no value.
Calling this again replaces the previous listener.
Parameters
| Parameter | Type |
|---|---|
onCapture | (capture: VisualizerCapture) => boolean |
Returns
void
startVisualizer()
startVisualizer(
fftSize: number,
fps: number,
waveform: boolean
): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:468
Arm mpv's PCM tap and start delivering analysed windows.
Restarts cleanly when already running, which is what lets a second subscriber widen the shared native parameters without a gap.
Parameters
| Parameter | Type | Description |
|---|---|---|
fftSize | number | Transform length; a power of two in [64, 16384]. |
fps | number | Delivery rate in [1, 60]. This is the render rate: new spectral content arrives no faster than the audio device consumes chunks (~20-45 Hz on Android), and the TypeScript smoothing is what turns one into the other. |
waveform | boolean | Also deliver time-domain samples. |
Returns
void
Throws
[visualizer:unavailable] when the linked libmpv has no pcm-tap
property, i.e. it was not built from the rn-media forks. Same error, same
code path, on both platforms.
stopVisualizer()
stopVisualizer(): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:477
Stop sampling and disarm mpv's tap. Idempotent.
After this, mpv frees its ring and the audio thread's tap path is a single atomic load per device chunk — the feature genuinely costs nothing when nobody is looking.
Returns
void
toString()
toString(): string;
Defined in: node_modules/react-native-nitro-modules/lib/typescript/HybridObject.d.ts:64
Returns a string representation of the given HybridObject.
Unless overridden by the HybridObject, this will return the name of the object.
Returns
string
Example
const hybridA = SomeModule.getExistingHybridInstance()
console.log(hybridA.toString()) // [HybridObject HybridA]
Inherited from
HybridObject.toString
uninstallSourceResolver()
uninstallSourceResolver(): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:546
Disarm the handler and drop every cached resolution. Idempotent, and safe to call while a hook is parked: the hold is released immediately.
The hooks stay registered (mpv has no unregister call — "Currently, hooks
can't be removed explicitly", mpv/client.h), so what is left is an
unrewritten immediate continue. PrefetchStartedEvent keeps being
delivered, because observing a prefetch does not depend on resolving one.
Returns
void
unobserveProperty()
unobserveProperty(name: string): void;
Defined in: packages/player/src/specs/mpv-client.nitro.ts:431
Stop observing name. No-op if it was not observed.
Parameters
| Parameter | Type |
|---|---|
name | string |
Returns
void