### Accessing mpv properties Source: https://context7.com/stremio/libmpv2-rs/llms.txt Demonstrates setting and getting various mpv properties including numeric, boolean, string, and complex types like MpvNode. ```rust use libmpv2::{Mpv, Result}; use libmpv2::mpv_node::MpvNode; use std::collections::HashMap; fn main() -> Result<()> { let mpv = Mpv::new()?; mpv.command("loadfile", &["video.mp4", "replace"])?; // Set numeric properties mpv.set_property("volume", 80i64)?; mpv.set_property("speed", 1.5f64)?; // Set boolean properties mpv.set_property("mute", false)?; mpv.set_property("loop-file", true)?; // Set string properties mpv.set_property("sub-visibility", "yes".to_string())?; // Get properties with specific types let volume: i64 = mpv.get_property("volume")?; let duration: f64 = mpv.get_property("duration").unwrap_or(0.0); let paused: bool = mpv.get_property("pause").unwrap_or(false); let filename: String = mpv.get_property("filename").unwrap_or_default(); println!("Volume: {}, Duration: {:.2}s, Paused: {}, File: {}", volume, duration, paused, filename); // Get complex properties as MpvNode let playlist: MpvNode = mpv.get_property("playlist")?; if let Some(items) = playlist.array() { for item in items { if let Some(map_iter) = item.map() { let map: HashMap<_, _> = map_iter.collect(); if let Some(MpvNode::String(filename)) = map.get("filename") { println!("Playlist item: {}", filename); } } } } Ok(()) } ``` -------------------------------- ### Create and Use Basic Mpv Instance Source: https://context7.com/stremio/libmpv2-rs/llms.txt Initializes a basic mpv instance with default settings, sets volume, loads a media file, and retrieves the current playback position. Ensure the media file path is correct. ```rust use libmpv2::{Mpv, Result}; fn main() -> Result<()> { // Create a basic mpv instance with default settings let mpv = Mpv::new()?; // Set initial volume mpv.set_property("volume", 50i64)?; // Load and play a media file mpv.command("loadfile", &["path/to/video.mp4", "replace"])?; // Get current playback position let position: f64 = mpv.get_property("time-pos").unwrap_or(0.0); println!("Current position: {:.2}s", position); Ok(()) } ``` -------------------------------- ### Core API: Mpv::new Source: https://context7.com/stremio/libmpv2-rs/llms.txt Creates a new mpv instance with default settings, initializing the mpv core for media playback. Allows setting initial properties and loading media. ```APIDOC ## Mpv::new ### Description Creates a new mpv instance with default settings. This initializes the mpv core and prepares it for media playback. The default settings can be viewed by running `mpv --show-profile=libmpv`. ### Method Rust function call ### Endpoint N/A (Rust function) ### Parameters None directly for `Mpv::new`, but properties can be set after creation. ### Request Example ```rust use libmpv2::{Mpv, Result}; fn main() -> Result<()> { // Create a basic mpv instance with default settings let mpv = Mpv::new()?; // Set initial volume mpv.set_property("volume", 50i64)?; // Load and play a media file mpv.command("loadfile", &["path/to/video.mp4", "replace"])?; // Get current playback position let position: f64 = mpv.get_property("time-pos").unwrap_or(0.0); println!("Current position: {:.2}s", position); Ok(()) } ``` ### Response #### Success Response (200) Returns a `Result` where `Ok(Mpv)` contains the initialized mpv instance. #### Response Example ```rust // On success, `mpv` variable holds the Mpv instance. let mpv = Mpv::new()?; ``` ``` -------------------------------- ### Initialize RenderContext for OpenGL Source: https://context7.com/stremio/libmpv2-rs/llms.txt Sets up a render context for custom OpenGL video output. Requires the 'render' feature and setting the 'vo' property to 'libmpv'. ```rust use libmpv2::{Mpv, Result}; use libmpv2::render::{ RenderContext, RenderParam, RenderParamApiType, OpenGLInitParams }; use std::ffi::c_void; // Function to get OpenGL procedure addresses (implementation depends on windowing library) fn get_proc_address(ctx: &(), name: &str) -> *mut c_void { // In a real application, use your windowing library's function: // - SDL2: video.gl_get_proc_address(name) // - GLFW: glfw.get_proc_address(name) // - glutin: context.get_proc_address(name) std::ptr::null_mut() } fn main() -> Result<()> { let mut mpv = Mpv::with_initializer(|init| { // Must use "libmpv" video output for custom rendering init.set_property("vo", "libmpv")?; Ok(()) })?; // Create render context with OpenGL parameters let render_context = RenderContext::new( unsafe { mpv.ctx.as_mut() }, vec![ RenderParam::ApiType(RenderParamApiType::OpenGl), RenderParam::InitParams(OpenGLInitParams { get_proc_address, ctx: (), // Context passed to get_proc_address }), ], )?; mpv.command("loadfile", &["video.mp4", "replace"])?; // render_context is now ready for use in render loop Ok(()) } ``` -------------------------------- ### Send Commands to Mpv Instance Source: https://context7.com/stremio/libmpv2-rs/llms.txt Demonstrates various commands that can be sent to an mpv instance to control playback, manage playlists, seek, and adjust playback state. Ensure correct command arguments are used. ```rust use libmpv2::{Mpv, Result}; fn main() -> Result<()> { let mpv = Mpv::new()?; // Load a file and start playing mpv.command("loadfile", &["video.mp4", "replace"])?; // Append another file to the playlist mpv.command("loadfile", &["video2.mp4", "append"])?; // Seek forward 30 seconds mpv.command("seek", &["30", "relative"])?; // Seek to absolute position (60 seconds from start) mpv.command("seek", &["60", "absolute"])?; // Go to next item in playlist mpv.command("playlist-next", &["force"])?; // Go to previous item in playlist mpv.command("playlist-prev", &["force"])?; // Pause playback mpv.command("set", &["pause", "yes"])?; // Resume playback mpv.command("set", &["pause", "no"])?; // Stop playback mpv.command("stop", &[])?; Ok(()) } ``` -------------------------------- ### Loading mpv configuration Source: https://context7.com/stremio/libmpv2-rs/llms.txt Loads an external configuration file from an absolute path before initiating playback. ```rust use libmpv2::{Mpv, Result}; fn main() -> Result<()> { let mpv = Mpv::new()?; // Load a custom mpv configuration file mpv.load_config("/home/user/.config/mpv/mpv.conf")?; // Now play with the loaded configuration mpv.command("loadfile", &["video.mp4", "replace"])?; Ok(()) } ``` -------------------------------- ### Create Mpv Instance with Custom Initializer Source: https://context7.com/stremio/libmpv2-rs/llms.txt Creates an mpv instance using a custom initializer function to set properties like video output and hardware decoding before full initialization. This is crucial for options that must be set early. ```rust use libmpv2::{Mpv, MpvInitializer, Result}; fn main() -> Result<()> { // Create mpv with custom initialization let mpv = Mpv::with_initializer(|init: MpvInitializer| { // Set video output to null (audio only) or libmpv (for custom rendering) init.set_property("vo", "null")?; // Configure hardware acceleration init.set_property("hwdec", "auto")?; // Set default volume before initialization init.set_property("volume", 75i64)?; Ok(()) })?; // Now use the configured mpv instance mpv.command("loadfile", &["https://example.com/stream.mp4", "replace"])?; Ok(()) } ``` -------------------------------- ### Create a custom protocol with Protocol::new Source: https://context7.com/stremio/libmpv2-rs/llms.txt Implements custom URI schemes by defining open, close, read, seek, and size callbacks. Requires the 'protocols' feature and involves unsafe FFI operations. ```rust use libmpv2::{Mpv, Result}; use libmpv2::protocol::Protocol; use std::fs::File; use std::io::{Read, Seek, SeekFrom}; fn main() -> Result<()> { // Define protocol callback functions fn open(_user_data: &mut (), uri: &str) -> File { // Strip protocol prefix "filereader://" let path = &uri[13..]; File::open(path).expect("Failed to open file") } fn close(_file: Box) { println!("Stream closed"); } fn read(file: &mut File, buf: &mut [i8]) -> i64 { let buf = unsafe { std::mem::transmute::<&mut [i8], &mut [u8]>(buf) }; file.read(buf).unwrap_or(0) as i64 } fn seek(file: &mut File, offset: i64) -> i64 { file.seek(SeekFrom::Start(offset as u64)).unwrap_or(0) as i64 } fn size(file: &mut File) -> i64 { file.metadata().map(|m| m.len() as i64).unwrap_or(-1) } // Create the protocol (unsafe due to FFI) let protocol = unsafe { Protocol::new( "filereader".into(), // Protocol name (), // User data passed to open() open, close, read, Some(seek), // Optional seek support Some(size), // Optional size reporting ) }; let mpv = Mpv::new()?; // Register the protocol let proto_ctx = mpv.create_protocol_context(); proto_ctx.register(protocol)?; // Use the custom protocol mpv.command("loadfile", &["filereader:///path/to/video.mp4", "replace"])?; std::thread::sleep(std::time::Duration::from_secs(10)); Ok(()) } ``` -------------------------------- ### Core API: Mpv::with_initializer Source: https://context7.com/stremio/libmpv2-rs/llms.txt Creates an mpv instance with a custom initializer function. This allows setting properties and options before mpv is fully initialized, which is crucial for options that must be set early. ```APIDOC ## Mpv::with_initializer ### Description Creates an mpv instance with a custom initializer function that can set properties and options before mpv is fully initialized. This is essential for options that must be set before initialization, such as video output configuration. ### Method Rust function call ### Endpoint N/A (Rust function) ### Parameters - `initializer` (Fn(MpvInitializer) -> Result<()>): A closure that takes an `MpvInitializer` and returns a `Result<()>`. Inside this closure, properties can be set using `init.set_property()`. ### Request Example ```rust use libmpv2::{Mpv, MpvInitializer, Result}; fn main() -> Result<()> { // Create mpv with custom initialization let mpv = Mpv::with_initializer(|init: MpvInitializer| { // Set video output to null (audio only) or libmpv (for custom rendering) init.set_property("vo", "null")?; // Configure hardware acceleration init.set_property("hwdec", "auto")?; // Set default volume before initialization init.set_property("volume", 75i64)?; Ok(()) })?; // Now use the configured mpv instance mpv.command("loadfile", &["https://example.com/stream.mp4", "replace"])?; Ok(()) } ``` ### Response #### Success Response (200) Returns a `Result` where `Ok(Mpv)` contains the initialized mpv instance configured by the initializer function. #### Response Example ```rust // On success, `mpv` variable holds the Mpv instance. let mpv = Mpv::with_initializer(|init| Ok(init))?; ``` ``` -------------------------------- ### Mpv::load_config Source: https://context7.com/stremio/libmpv2-rs/llms.txt Loads an mpv configuration file from an absolute path. ```APIDOC ## Mpv::load_config ### Description Loads an mpv configuration file. The path must be absolute and point to a valid mpv config file. ### Method Rust Method Call ### Parameters #### Request Body - **path** (String) - Required - Absolute path to the mpv configuration file. ``` -------------------------------- ### Implement Event-Driven Playback Source: https://context7.com/stremio/libmpv2-rs/llms.txt Demonstrates concurrent playback control and event observation using crossbeam for thread management. Requires the crossbeam crate for scope-based threading. ```rust use libmpv2::{events::*, mpv_node::MpvNode, Format, Mpv, Result}; use std::{collections::HashMap, thread, time::Duration}; fn main() -> Result<()> { // Create mpv with null video output (audio only or for testing) let mpv = Mpv::with_initializer(|init| { init.set_property("vo", "null")?; Ok(()) })?; mpv.set_property("volume", 50i64)?; // Create event context and observe properties let mut ev_ctx = EventContext::new(mpv.ctx); ev_ctx.disable_deprecated_events()?; ev_ctx.observe_property("volume", Format::Int64, 1)?; ev_ctx.observe_property("time-pos", Format::Double, 2)?; ev_ctx.observe_property("demuxer-cache-state", Format::Node, 3)?; // Spawn playback control thread let mpv_ref = &mpv; crossbeam::scope(|scope| { // Control thread scope.spawn(move |_| { mpv_ref.command("loadfile", &["video.mp4", "append-play"]).unwrap(); thread::sleep(Duration::from_secs(3)); mpv_ref.set_property("volume", 75i64).unwrap(); thread::sleep(Duration::from_secs(5)); mpv_ref.command("seek", &["30", "relative"]).unwrap(); thread::sleep(Duration::from_secs(5)); mpv_ref.command("playlist-next", &["force"]).unwrap(); }); // Event handling thread scope.spawn(move |_| { loop { match ev_ctx.wait_event(60.0) { Some(Ok(Event::PropertyChange { name, change, .. })) => { match (name, change) { ("volume", PropertyData::Int64(v)) => { println!("Volume: {}", v); } ("time-pos", PropertyData::Double(t)) => { println!("Position: {:.1}s", t); } ("demuxer-cache-state", PropertyData::Node(node)) => { if let Some(ranges) = extract_seekable_ranges(node) { println!("Seekable: {:?}", ranges); } } _ => {} } } Some(Ok(Event::EndFile(reason))) => { println!("Playback ended: {:?}", reason); break; } Some(Ok(Event::Shutdown)) => { println!("mpv shutdown"); break; } Some(Ok(event)) => { println!("Event: {:?}", event); } Some(Err(e)) => { eprintln!("Error: {:?}", e); } None => {} } } }); }).unwrap(); Ok(()) } fn extract_seekable_ranges(node: MpvNode) -> Option> { let map: HashMap<_, _> = node.map()?.collect(); let ranges = map.get("seekable-ranges")?.clone().array()?; Some(ranges.filter_map(|r| { let m: HashMap<_, _> = r.map()?.collect(); Some((m.get("start")?.f64()?, m.get("end")?.f64()?)) }).collect()) } ``` -------------------------------- ### Handle libmpv2 Errors Source: https://context7.com/stremio/libmpv2-rs/llms.txt Demonstrates how to handle various error types provided by the libmpv2 library, including raw mpv errors, null pointers, invalid UTF-8, version mismatches, and file loading errors. ```rust use libmpv2::{Mpv, Error, Result}; fn main() { match Mpv::new() { Ok(mpv) => { // Handle property access errors match mpv.get_property::("nonexistent-property") { Ok(value) => println!("Value: {}", value), Err(Error::Raw(code)) => { eprintln!("mpv error code: {}", code); } Err(Error::Null) => { eprintln!("Null pointer error"); } Err(Error::InvalidUtf8) => { eprintln!("Invalid UTF-8 in string"); } Err(Error::VersionMismatch { linked, loaded }) => { eprintln!("API version mismatch: linked={}, loaded={}", linked, loaded); } Err(Error::Loadfile { error }) => { eprintln!("File loading error: {:?}", error); } } // Handle command errors if let Err(e) = mpv.command("loadfile", &["nonexistent.mp4", "replace"]) { eprintln!("Command failed: {:?}", e); } } Err(e) => { eprintln!("Failed to create mpv: {:?}", e); } } } ``` -------------------------------- ### Core API: Mpv::command Source: https://context7.com/stremio/libmpv2-rs/llms.txt Sends a command to the mpv instance to control playback, manage playlists, seek, and perform other media operations. Arguments are passed as string slices. ```APIDOC ## Mpv::command ### Description Sends a command to the mpv instance. Commands control playback, manage playlists, seek, and perform other media operations. Arguments are passed as string slices. ### Method Rust function call ### Endpoint N/A (Rust function) ### Parameters - **command** (string slice): The name of the command to execute (e.g., "loadfile", "seek", "set"). - **args** (slice of string slices): Arguments for the command. ### Request Example ```rust use libmpv2::{Mpv, Result}; fn main() -> Result<()> { let mpv = Mpv::new()?; // Load a file and start playing mpv.command("loadfile", &["video.mp4", "replace"])?; // Append another file to the playlist mpv.command("loadfile", &["video2.mp4", "append"])?; // Seek forward 30 seconds mpv.command("seek", &["30", "relative"])?; // Seek to absolute position (60 seconds from start) mpv.command("seek", &["60", "absolute"])?; // Go to next item in playlist mpv.command("playlist-next", &["force"])?; // Go to previous item in playlist mpv.command("playlist-prev", &["force"])?; // Pause playback mpv.command("set", &["pause", "yes"])?; // Resume playback mpv.command("set", &["pause", "no"])?; // Stop playback mpv.command("stop", &[])?; Ok(()) } ``` ### Response #### Success Response (200) Returns a `Result<()>` indicating success or failure of the command execution. #### Response Example ```rust // On success, the command is executed. mpv.command("loadfile", &["video.mp4", "replace"])?; ``` ``` -------------------------------- ### Protocol::new Source: https://context7.com/stremio/libmpv2-rs/llms.txt Creates a custom protocol for handling custom URI schemes (e.g., `myprotocol://path`). Requires the `protocols` feature. The protocol handles open, close, read, seek, and size operations. ```APIDOC ## Protocol::new ### Description Creates a custom protocol for handling custom URI schemes (e.g., `myprotocol://path`). Requires the `protocols` feature. The protocol handles open, close, read, seek, and size operations. ### Method `Protocol::new` ### Parameters - `protocol_name` (String) - The name of the protocol (e.g., "filereader"). - `user_data` (&mut ()) - User data passed to the `open` callback. - `open` (fn(&mut ()) -> File) - Callback function for opening a stream. - `close` (fn(Box)) - Callback function for closing a stream. - `read` (fn(&mut File, &mut [i8]) -> i64) - Callback function for reading data from the stream. - `seek` (Option i64>) - Optional callback function for seeking within the stream. - `size` (Option i64>) - Optional callback function for getting the stream size. ### Request Example ```rust fn open(_user_data: &mut (), uri: &str) -> File { let path = &uri[13..]; File::open(path).expect("Failed to open file") } fn close(_file: Box) { println!("Stream closed"); } fn read(file: &mut File, buf: &mut [i8]) -> i64 { let buf = unsafe { std::mem::transmute::<&mut [i8], &mut [u8]>(buf) }; file.read(buf).unwrap_or(0) as i64 } fn seek(file: &mut File, offset: i64) -> i64 { file.seek(SeekFrom::Start(offset as u64)).unwrap_or(0) as i64 } fn size(file: &mut File) -> i64 { file.metadata().map(|m| m.len() as i64).unwrap_or(-1) } let protocol = unsafe { Protocol::new( "filereader".into(), (), open, close, read, Some(seek), Some(size), ) }; let mpv = Mpv::new()?; let proto_ctx = mpv.create_protocol_context(); proto_ctx.register(protocol)?; mpv.command("loadfile", &["filereader:///path/to/video.mp4", "replace"])?; ``` ### Response - `Protocol` - A new protocol context. - `Result<()>` - Indicates success or failure of protocol registration. ``` -------------------------------- ### Handling mpv events Source: https://context7.com/stremio/libmpv2-rs/llms.txt Implements an event loop using EventContext to process playback events with a specified timeout. ```rust use libmpv2::{Mpv, Format, Result}; use libmpv2::events::{Event, EventContext, PropertyData}; use std::thread; use std::time::Duration; fn main() -> Result<()> { let mpv = Mpv::with_initializer(|init| { init.set_property("vo", "null")?; Ok(()) })?; let mut ev_ctx = EventContext::new(mpv.ctx); ev_ctx.disable_deprecated_events()?; // Start playback mpv.command("loadfile", &["video.mp4", "replace"])?; // Event loop loop { // Wait up to 1 second for an event match ev_ctx.wait_event(1.0) { Some(Ok(Event::StartFile)) => { println!("Started loading file"); } Some(Ok(Event::FileLoaded)) => { println!("File loaded successfully"); } Some(Ok(Event::PlaybackRestart)) => { println!("Playback started/restarted"); } Some(Ok(Event::Seek)) => { println!("Seek operation completed"); } Some(Ok(Event::EndFile(reason))) => { println!("File ended with reason: {:?}", reason); break; } Some(Ok(Event::Shutdown)) => { println!("mpv is shutting down"); break; } Some(Ok(event)) => { println!("Other event: {:?}", event); } Some(Err(e)) => { eprintln!("Event error: {:?}", e); } None => { // No event available, timeout reached } } } Ok(()) } ``` -------------------------------- ### Render video frames with RenderContext::render Source: https://context7.com/stremio/libmpv2-rs/llms.txt Executes frame rendering to an OpenGL framebuffer within the render loop. Call report_swap after rendering to improve timing. ```rust use libmpv2::render::{RenderContext, RenderParam, OpenGLInitParams, RenderParamApiType}; use libmpv2::Mpv; use std::ffi::c_void; fn render_loop(render_context: &RenderContext, window_width: i32, window_height: i32) { // Render to the default framebuffer (FBO 0) // flip=true because OpenGL has Y-up coordinates, video has Y-down render_context.render::<()>( 0, // FBO ID (0 = default backbuffer) window_width, // Framebuffer width window_height, // Framebuffer height true, // Flip Y coordinate ).expect("Failed to render frame"); // Report that frame was displayed (improves timing) render_context.report_swap(); } ``` -------------------------------- ### Error Handling Source: https://context7.com/stremio/libmpv2-rs/llms.txt Overview of the error types provided by the library, including libmpv errors, UTF-8 conversion errors, and version mismatches. ```APIDOC ## Error Handling ### Description The library provides a comprehensive error type that covers libmpv errors, UTF-8 conversion errors, and version mismatches. ### Error Types - **Error::Raw(code)** - libmpv specific error code. - **Error::Null** - Null pointer error. - **Error::InvalidUtf8** - Invalid UTF-8 encountered in string conversion. - **Error::VersionMismatch** - API version mismatch between linked and loaded libraries. - **Error::Loadfile** - Error occurred during file loading. ``` -------------------------------- ### Observe properties with EventContext Source: https://context7.com/stremio/libmpv2-rs/llms.txt Registers property observation with specific formats and IDs, then processes changes via the event loop. ```rust use libmpv2::{Mpv, Format, Result}; use libmpv2::events::{Event, EventContext, PropertyData}; use libmpv2::mpv_node::MpvNode; use std::collections::HashMap; fn main() -> Result<()> { let mpv = Mpv::with_initializer(|init| { init.set_property("vo", "null")?; Ok(()) })?; let mut ev_ctx = EventContext::new(mpv.ctx); ev_ctx.disable_deprecated_events()?; // Observe various properties with unique IDs ev_ctx.observe_property("volume", Format::Int64, 1)?; ev_ctx.observe_property("time-pos", Format::Double, 2)?; ev_ctx.observe_property("pause", Format::Flag, 3)?; ev_ctx.observe_property("demuxer-cache-state", Format::Node, 4)?; mpv.command("loadfile", &["video.mp4", "replace"])?; loop { match ev_ctx.wait_event(10.0) { Some(Ok(Event::PropertyChange { name, change, reply_userdata })) => { match (name, change) { ("volume", PropertyData::Int64(vol)) => { println!("Volume changed to: {}", vol); } ("time-pos", PropertyData::Double(pos)) => { println!("Position: {:.2}s", pos); } ("pause", PropertyData::Flag(paused)) => { println!("Paused: {}", paused); } ("demuxer-cache-state", PropertyData::Node(node)) => { // Parse complex cache state if let Some(map_iter) = node.map() { let map: HashMap<_, _> = map_iter.collect(); println!("Cache state: {:?}", map.keys().collect::>()); } } _ => println!("Property {} changed (id={})", name, reply_userdata), } } Some(Ok(Event::EndFile(_))) => break, Some(Ok(_)) => {} Some(Err(e)) => eprintln!("Error: {:?}", e), None => {} } } // Stop observing by ID ev_ctx.unobserve_property(1)?; ev_ctx.unobserve_property(2)?; Ok(()) } ``` -------------------------------- ### Set Render Update Callback Source: https://context7.com/stremio/libmpv2-rs/llms.txt Sets a callback to be invoked when a new video frame is ready. This is useful for triggering redraws in your render loop. Avoid calling mpv APIs or performing heavy work within the callback. ```rust use libmpv2::{Mpv, Result}; use libmpv2::render::{RenderContext, RenderParam, RenderParamApiType, OpenGLInitParams}; use std::sync::mpsc; use std::ffi::c_void; fn get_proc_address(_: &(), _: &str) -> *mut c_void { std::ptr::null_mut() } fn main() -> Result<()> { let mut mpv = Mpv::with_initializer(|init| { init.set_property("vo", "libmpv")?; Ok(()) })?; let mut render_context = RenderContext::new( unsafe { mpv.ctx.as_mut() }, vec![ RenderParam::ApiType(RenderParamApiType::OpenGl), RenderParam::InitParams(OpenGLInitParams { get_proc_address, ctx: (), }), ], )?; let (tx, rx) = mpsc::channel(); // Set callback for frame updates render_context.set_update_callback(move || { // Signal render thread that a new frame is available // IMPORTANT: Don't call mpv APIs or do heavy work here! let _ = tx.send(()); }); mpv.command("loadfile", &["video.mp4", "replace"])?; // In render thread: loop { // Wait for frame notification if rx.recv().is_err() { break; } // Call update() to prepare the frame let flags = render_context.update()?; // Check if rendering is needed if flags & libmpv2::render::mpv_render_update::Frame != 0 { // Render the frame render_context.render::<()>(0, 1920, 1080, true)?; // Swap buffers (depends on your windowing library) render_context.report_swap(); } } Ok(()) } ``` -------------------------------- ### EventContext::set_wakeup_callback Source: https://context7.com/stremio/libmpv2-rs/llms.txt Sets a callback that is invoked when new events are available. The callback runs on foreign threads and must return quickly without calling mpv APIs. ```APIDOC ## set_wakeup_callback ### Description Sets a callback that is invoked when new events are available. The callback runs on foreign threads and must return quickly without calling mpv APIs. ### Parameters #### Path Parameters - **callback** (Fn) - Required - The closure to execute when events are available. ``` -------------------------------- ### Mpv::set_property / Mpv::get_property Source: https://context7.com/stremio/libmpv2-rs/llms.txt Methods to set or retrieve mpv playback properties such as volume, speed, and file information with type-safe access. ```APIDOC ## Mpv::set_property / Mpv::get_property ### Description Sets or gets mpv property values. Properties control various aspects of playback including volume, speed, position, and many other settings. The generic types allow type-safe property access. ### Method Rust Method Call ### Parameters #### Request Body - **name** (String) - Required - The name of the mpv property to access. - **value** (T) - Required - The value to set for the property (for set_property). ``` -------------------------------- ### RenderContext::set_update_callback Source: https://context7.com/stremio/libmpv2-rs/llms.txt Sets a callback that is invoked when a new video frame is ready, allowing for efficient integration with render loops. ```APIDOC ## RenderContext::set_update_callback ### Description Sets a callback that's invoked when a new video frame is ready. Use this to trigger redraws in your render loop. Note: Do not call mpv APIs or perform heavy work inside this callback. ### Parameters #### Request Body - **callback** (Fn) - Required - A closure to be executed when a new frame is available. ``` -------------------------------- ### Set wakeup callback for event notification Source: https://context7.com/stremio/libmpv2-rs/llms.txt Configures a callback to signal when events are available, allowing non-blocking event processing. The callback must not invoke mpv APIs. ```rust use libmpv2::{Mpv, Result}; use libmpv2::events::EventContext; use std::sync::mpsc; use std::thread; fn main() -> Result<()> { let mpv = Mpv::with_initializer(|init| { init.set_property("vo", "null")?; Ok(()) })?; let (tx, rx) = mpsc::channel(); let mut ev_ctx = EventContext::new(mpv.ctx); // Set wakeup callback to notify main thread ev_ctx.set_wakeup_callback(move || { // IMPORTANT: Don't call mpv APIs here! // Just signal that events are available let _ = tx.send(()); }); mpv.command("loadfile", &["video.mp4", "replace"])?; // Wait for wakeup signal, then process events loop { // Block until wakeup callback signals if rx.recv().is_err() { break; } // Process all available events while let Some(result) = ev_ctx.wait_event(0.0) { match result { Ok(libmpv2::events::Event::EndFile(_)) => return Ok(()), Ok(event) => println!("Event: {:?}", event), Err(e) => eprintln!("Error: {:?}", e), } } } Ok(()) } ``` -------------------------------- ### OpenGL Render API Source: https://context7.com/stremio/libmpv2-rs/llms.txt APIs for custom OpenGL rendering, allowing video frames to be rendered to your own OpenGL framebuffer. ```APIDOC ## OpenGL Render API ### RenderContext::new Creates a render context for custom OpenGL rendering. Requires the `render` feature. This allows rendering video frames to your own OpenGL framebuffer. ### Method `RenderContext::new` ### Parameters - `mpv_ctx` (*mut mpv_ctx) - A mutable pointer to the MPV context. - `params` (Vec) - A vector of `RenderParam` to configure the context. - `RenderParam::ApiType(RenderParamApiType)` - Specifies the rendering API type (e.g., `OpenGl`). - `RenderParam::InitParams(OpenGLInitParams)` - OpenGL-specific initialization parameters. - `get_proc_address` (*const c_void) - Function pointer to retrieve OpenGL function addresses. - `ctx` (*mut c_void) - User-defined context passed to `get_proc_address`. ### Request Example ```rust use libmpv2::{Mpv, Result}; use libmpv2::render::{ RenderContext, RenderParam, RenderParamApiType, OpenGLInitParams }; use std::ffi::c_void; fn get_proc_address(ctx: &(), name: &str) -> *mut c_void { // Implementation depends on windowing library std::ptr::null_mut() } fn main() -> Result<()> { let mut mpv = Mpv::with_initializer(|init| { init.set_property("vo", "libmpv")?; Ok(()) })?; let render_context = RenderContext::new( unsafe { mpv.ctx.as_mut() }, vec![ RenderParam::ApiType(RenderParamApiType::OpenGl), RenderParam::InitParams(OpenGLInitParams { get_proc_address, ctx: (), }), ], )?; mpv.command("loadfile", &["video.mp4", "replace"])?; Ok(()) } ``` ### Response - `RenderContext` - A new render context for OpenGL. - `Result<()>` - Indicates success or failure of context creation. ``` ```APIDOC ### RenderContext::render Renders a video frame to an OpenGL framebuffer. Call this in your render loop when a new frame is available. ### Method `RenderContext::render` ### Parameters - `fbo_id` (u32) - The OpenGL Frame Buffer Object (FBO) ID. Use 0 for the default framebuffer. - `width` (i32) - The width of the framebuffer. - `height` (i32) - The height of the framebuffer. - `flip` (bool) - Whether to flip the Y coordinate (true for OpenGL's Y-up vs video's Y-down). ### Request Example ```rust use libmpv2::render::RenderContext; fn render_loop(render_context: &RenderContext, window_width: i32, window_height: i32) { render_context.render( 0, // FBO ID (0 = default backbuffer) window_width, // Framebuffer width window_height, // Framebuffer height true, // Flip Y coordinate ).expect("Failed to render frame"); render_context.report_swap(); } ``` ### Response - `Result<()>` - Indicates success or failure of rendering. ``` -------------------------------- ### EventContext::wait_event Source: https://context7.com/stremio/libmpv2-rs/llms.txt Waits for an mpv event with a specified timeout. ```APIDOC ## EventContext::wait_event ### Description Waits for an mpv event with a timeout. Returns None if no event is available, Some(Ok(Event)) for successful events, or Some(Err(...)) for errors. Use timeout of 0 for polling. ### Method Rust Method Call ### Parameters #### Request Body - **timeout** (f64) - Required - Time in seconds to wait for an event. ``` -------------------------------- ### Enable and disable specific events Source: https://context7.com/stremio/libmpv2-rs/llms.txt Manages event subscriptions by enabling or disabling specific event types via the EventContext. ```rust use libmpv2::{Mpv, Result}; use libmpv2::events::{EventContext, mpv_event_id}; fn main() -> Result<()> { let mpv = Mpv::new()?; let ev_ctx = EventContext::new(mpv.ctx); // Disable deprecated events (recommended) ev_ctx.disable_deprecated_events()?; // Enable all non-deprecated events ev_ctx.enable_all_events()?; // Or selectively enable/disable specific events ev_ctx.enable_event(mpv_event_id::Seek)?; ev_ctx.enable_event(mpv_event_id::PlaybackRestart)?; ev_ctx.disable_event(mpv_event_id::Tick)?; // Disable all events (for manual control) ev_ctx.disable_all_events()?; Ok(()) } ``` -------------------------------- ### EventContext::observe_property Source: https://context7.com/stremio/libmpv2-rs/llms.txt Observes a specific mpv property for changes. When the property changes, a PropertyChange event is generated. ```APIDOC ## observe_property ### Description Observes a property for changes. When the property changes, a PropertyChange event is generated. The format parameter specifies the expected data type. ### Parameters #### Path Parameters - **name** (string) - Required - The name of the property to observe. - **format** (Format) - Required - The expected data type of the property. - **reply_userdata** (u64) - Required - A unique ID used to identify the property change event. ``` -------------------------------- ### EventContext::enable_event / disable_event Source: https://context7.com/stremio/libmpv2-rs/llms.txt Controls which events are received by the event context. ```APIDOC ## enable_event / disable_event ### Description Controls which events are received. Some events are enabled by default while others require explicit enabling. ### Parameters #### Path Parameters - **event_id** (mpv_event_id) - Required - The specific event ID to enable or disable. ``` -------------------------------- ### Mpv::get_internal_time Source: https://context7.com/stremio/libmpv2-rs/llms.txt Retrieves the internal mpv time in microseconds. ```APIDOC ## Mpv::get_internal_time ### Description Returns mpv's internal time in microseconds. This has an arbitrary offset and never goes backwards. Safe to call at any time. ``` -------------------------------- ### Measuring internal time Source: https://context7.com/stremio/libmpv2-rs/llms.txt Retrieves the internal mpv clock in microseconds to measure elapsed time for operations. ```rust use libmpv2::{Mpv, Result}; fn main() -> Result<()> { let mpv = Mpv::new()?; let time_before = mpv.get_internal_time(); // ... perform operations ... let time_after = mpv.get_internal_time(); let elapsed_us = time_after - time_before; println!("Operation took {} microseconds", elapsed_us); Ok(()) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.