Expand description
§mpv-engine
Toolkit-agnostic core for embedding libmpv: handle lifecycle, commands, properties, typed playback events, and render seams. Extracted from two independent embedders — a GTK4 app (GLArea direct-to-FBO) and an iced widget (side-context + readback/GPU export) — after their engine layers converged on the same shape.
What belongs here is decided by one rule: a quirk lives in this crate if its consumer-facing interface survives the upstream fix; anything whose shape would change with a toolkit’s API belongs in that toolkit’s adapter crate. See README for the seam map and roadmap.
The playback surface covers what a player UI consumes: transport
(load — immediate, paused, or deferred until a render context
attaches (Engine::load_when_ready) — pause/seek/stop), the mixer
set (volume/mute/speed), typed
lifecycle events (PlaybackEvent — including seek-completion for
scrubber snap and end reasons for playlist logic), and push-based
property observation (Engine::observe) for state that polling
can’t track well (duration becoming known, external pause flips, buffering,
video dimensions). Everything else goes through the property/command
escape hatches — which speak crate-owned types (PropertyValue,
the sealed PropertyGet), so the underlying binding’s traits never
enter this crate’s public API.
Two render backends share one attach slot: OpenGL
(Engine::attach_gl_render / Engine::render_gl) and software
(Engine::attach_sw_render / Engine::render_sw, RGBA into a
caller buffer, no GL anywhere). Engine::attached_render reports
which one is live (RenderKind), and the render-update callback
fixed at attach can be replaced afterwards
(Engine::set_render_update_callback) for shells whose real
closure only exists once the engine is shared. GL attach takes
GlRenderOptions
to fix the shell’s render-loop discipline: whether render_gl blocks
until the frame’s target time (right for a toolkit paint handler,
wrong on a compositor thread), and mpv’s advanced control (which
obligates Engine::render_update after every update callback). Event delivery is pull-based
(Engine::pump_events) with an optional push signal
(Engine::set_wakeup_callback) for shells that don’t want a
polling timer.
Quirks this crate owns so consumers don’t have to rediscover them:
LC_NUMERIC=Cforced beforempv_create(toolkits setlocale behind your back; mpv’s number parsing breaks under comma-decimal locales).- Render context freed strictly before the mpv handle — structural
since rsmpv 0.2 (the context co-owns the core) — and, for OpenGL,
only with the GL context current: an obligation
Engine::attach_gl_rendercarries as itsunsafecontract (seeEngine::detach_render). - Commands pass pre-tokenized argument arrays (
mpv_command), so paths with spaces/quotes need no escaping — pinned by a regression test. - Errored end-of-file surfaces as a typed
PlaybackEvent::Failedcarrying the rawmpv_errorcode (for integrators mapping to their own error copy) and a diagnostic message (mpv’smpv_error_stringtext plus the numeric code). - The update callback’s threading contract (mpv render thread, plus one synchronous call at registration) is documented at the seam.
No toolkit dependencies, no git dependencies, no main-loop opinions:
events are pumped, and the update callback is Send + Sync —
bridging to a main loop is the shell’s job, because that part is
toolkit-shaped.
Structs§
- Engine
- One embedded mpv player core.
- Engine
Builder - Configures and creates an
Engine. Properties set here are applied beforempv_initialize, which some options require. - GlRender
Options - Attach-time knobs for the OpenGL backend
(
Engine::attach_gl_render). The default is mpv’s stock behavior — right for a toolkit paint handler (GTK GLArea); shells whose render loop must not stall override per field. Attach-time on purpose: frame pacing is a property of the shell’s render loop, not of any single frame. - Observe
Id - Handle returned by
Engine::observe: tags that observation’sPropertyChangedevents and cancels it viaEngine::unobserve.
Enums§
- EndReason
- Why playback ended (mpv’s
mpv_end_file_reason). - Error
- Everything this crate’s fallible calls can return.
- Playback
Event - Playback lifecycle notifications drained by
Engine::pump_events. - Property
Format - Wire format for
Engine::observe— picks whichPropertyValuevariant change notifications carry (mpv coerces where it can). - Property
Value - Owned property value delivered by
PropertyChanged. - Render
Kind - Which render backend is attached — what
Engine::attached_renderreports.
Traits§
- Property
Get - Types a property can be read as:
bool,i64,f64,String. Sealed to the formats mpv’s property API speaks — the binding’s own conversion traits are deliberately not part of this crate’s API, so a binding major bump can’t be a breaking change here.
Type Aliases§
- Proc
Address Fn - Resolves GL symbols for mpv. Called during context creation (and possibly later render calls), so it must stay alive for the context’s lifetime — rsmpv keeps it boxed inside the context.
- Result
- Shorthand for results carrying this crate’s
Error.