mpv Media Player
repository·master·Indexed 12 days ago
https://github.com/mpv-player/mpvA highly customizable, command-line media player supporting a vast array of formats and codecs. Designed for power users and developers, it features a robust C API (libmpv), Lua scripting support, and a JSON IPC protocol for reliable automation. Documentation covers compilation via Meson, system requirements for Linux, Windows, and macOS, and guidelines for API and ABI compatibility.
What's inside mpv
- mpv is a free, command-line media player that supports a wide variety of media file formats, audio and video codecs, and subtitle types. It is designed for flexibility and can be extended via user scripts and a C API.
What is the On Screen Controller (OSC)?
masterThe On Screen Controller (OSC) is a minimal GUI integrated with mpv that provides basic mouse-controllability. It is designed to assist new users and enable precise, direct seeking via the mouse. The OSC is enabled by default if mpv was compiled with Lua support.Configure script locations and directory-based scripts
mastermpv supports both single-file scripts and directory-based scripts.
Single File Scripts
- Use the
.luaextension for Lua scripts. - Files with the
.disableextension are ignored by mpv. - The script name (returned by
mp.get_script_name()) is derived by stripping the extension and replacing non-alphanumeric characters with_(e.g.,my-tools.luabecomesmy_tools).
Directory-based Scripts (Recommended for complex scripts)
If you point mpv to a directory (via
--scriptor thescripts/folder), mpv treats the directory as a single script and looks for amain.luafile inside it.Important Rules for Directories:
- Do not place other files or directories starting with
main.in the top level of your script directory (e.g., avoid having bothmain.luaandmain.js). - Use
mp.get_script_directory()to locate the script's path for loading data files or other assets. - mpv appends the script's top-level directory to the Lua
package path, allowing you to use standard Luarequirestatements to import local modules.
- Use the
What are EDL files and how do they work?
masterEDL (Edit Decision List) files allow you to concatenate ranges of video/audio from multiple source files into a single continuous virtual file. Unlike a playlist where files play sequentially, an EDL creates a single virtual timeline.
Each segment in an EDL consists of a source file, a start offset, and a segment length. This allows you to skip parts of files or switch between different files seamlessly as if they were one continuous stream.
# mpv EDL v0 f1.mkv,10,20 f2.mkv f1.mkv,40,10Use Conditional Auto Profiles
masterConditional profiles are applied automatically when a specific condition is met. These conditions are written as Lua expressions in the
profile-condoption.How it works
- If the expression evaluates to truthy, the profile is applied.
- If it evaluates to falsy or errors, the profile is not applied (and is 'unapplied' if it was previously active).
- The condition is re-evaluated whenever any property referenced in the expression changes.
Accessing Properties
- Automatic mapping: Identifiers are treated as properties. Note that
_in an identifier is converted to-(e.g.,playback_time$\rightarrow$playback-time). - Robust access: Use
p.property_nameorget("property-name", default_value)to avoid issues with name collisions.
Reverting Conditional Profiles
To ensure a profile is removed when the condition becomes false, you must set
profile-restore(e.g.,profile-restore=copy).# Make only HD video look funny [something] profile-desc=HD video sucks profile-cond=width >= 1280 hue=-50 # Make only videos containing "youtube" or "youtu.be" in their path brighter [youtube] profile-cond=path:find('youtu%.?be') gamma=20 # Revert profile when entering/leaving fullscreen [something] profile-desc=Mess Up video when entering fullscreen profile-cond=fullscreen profile-restore=copy vf-add=rotate=PI/2License and Copyright requirements
masterAll new code must be licensed under LGPLv2.1+.
Key Rules:
- 100% compatible licenses are allowed.
- Changes to files with more liberal licenses (BSD, MIT, ISC) are assumed to be dual-licensed under LGPLv2.1+ and the original license.
- You must be the exclusive author or acknowledge all authors in the commit message.
- If using 3rd party code, authorship and copyright must be properly acknowledged.
- If working on behalf of an employer who owns the copyright, you must mention this.
- If the code is not LGPLv2.1+, you must mention this.
- Do not add your name to the license header; this is not the project convention.
Manage command lifecycle for asynchronous commands
masterWhen using asynchronous commands via the API (like
mpv_command_async), the command is bound to the context (thempv_handle) that started it.- Completion: Only the
mpv_handlethat started the command receives theMPV_EVENT_COMMAND_REPLYnotification. - Cancellation: Only the specific
mpv_handleused to start the command can abort the running command directly. - Handle Destruction: If the
mpv_handleis destroyed, any still-running asynchronous commands started by it are terminated. - Player Shutdown: If the player is closed, the core may abort all pending async commands automatically during the
MPV_EVENT_SHUTDOWNphase.
- Completion: Only the
Avoid parsing terminal and log output
masterThere are no compatibility guarantees for terminal output or text logged via
MPV_EVENT_LOG_MESSAGEand similar APIs.Warning: Scripts that invoke the mpv CLI and attempt to parse its text output are extremely discouraged. Instead, use the JSON IPC to retrieve state and information reliably.
Compare different video parameter properties
mastermpv provides several related properties for inspecting video state at different stages of the pipeline:
video-dec-params: Exactly likevideo-params, but contains the raw decoder output with no overrides applied.video-params: The video parameters as output by the decoder, including overrides like aspect ratio.video-out-params: The parameters after video filters have been applied. If no filters are used, this matchesvideo-params.video-target-params: The parameters with the target properties that the Video Output (VO) outputs to.dwidth,dheight: The video display size after filters and aspect scaling have been applied. This is equivalent tovideo-out-params/dwandvideo-out-params/dh.
Define and use Profiles
masterProfiles allow you to group settings under a name.
Defining Profiles
In a config file, a profile starts with
[profile-name]. All subsequent options belong to that profile until another profile or[default]is declared.Applying Profiles
- At startup: Use the
--profile=<name>CLI flag. - At runtime: Use the
apply-profile <name>command.
Inspecting Profiles
- List available profiles:
--profile=help - View contents of a profile:
--show-profile=<name>
Profile Restoration
Since
apply-profileis destructive (it overwrites existing values), you can use theprofile-restoreoption to allow reverting to previous states usingapply-profile <name> restore.profile-restoremodes:default: No restoration possible.copy: Backs up old values before applying the profile. Restoring uses this backup.copy-equal: Similar tocopy, but only restores an option if its current value matches the value set by the profile (useful if the user manually changed an option after applying the profile).
# normal top-level option fullscreen=yes # a profile that can be enabled with --profile=big-cache [big-cache] cache=yes demuxer-max-bytes=512MiB demuxer-readahead-secs=20 [network] profile-desc="profile for content over network" force-window=immediate # include other profiles profile=big-cache [reduce-judder] video-sync=display-resample interpolation=yes- At startup: Use the
Understand the mpv JavaScript event loop
masterThe mpv event loop is a continuous cycle that polls and dispatches mpv events, processes timers, and then waits for the next event.
If you need to intercept or debug all events sent to your script, you can implement a custom event loop. mpv will automatically attempt to call a function named
mp_event_loopafter the script loads if it exists.Key components of the loop:
- Event Polling: Uses
mp.wait_event(wait)to wait for events. - Event Dispatching: Uses
mp.dispatch_event(e)to trigger registered handlers (event handlers, property observers, script messages, etc.). - Timer Processing: Uses
mp.process_timers()to execute pending timers. - Idle Observers: Uses
mp.notify_idle_observers()to notify observers when the loop is about to sleep.
function mp_event_loop() { var wait = 0; do { var e = mp.wait_event(wait); dump(e); // there could be a lot of prints... if (e.event != "none") { mp.dispatch_event(e); wait = 0; } else { wait = mp.process_timers() / 1000; if (wait != 0) { mp.notify_idle_observers(); wait = mp.peek_timers_wait() / 1000; } } } while (mp.keep_running); }- Event Polling: Uses
Understand mpv asynchronous events
mastermpv delivers events asynchronously to scripts (Lua) and clients (JSON IPC). The player core continues running while events are being delivered. Most events include a standard set of fields:
event: The name of the event (e.g.,start-file).id: An opaque user value (reply_userdata).error: An error string if the event reports an error. This field is omitted if no error occurred.
Note: While most events are asynchronous, Hooks can be used to enforce synchronous execution for tasks requiring strict coordination.