How to Control mpv Media Player with a JavaScript Plugin?

This article provides a step-by-step guide on how to write a custom JavaScript plugin to control the mpv media player using its built-in JavaScript API. You will learn how to set up your scripting environment, interact with mpv’s key bindings, manipulate player properties, and respond to real-time playback events. By the end of this guide, you will be able to create automation scripts to customize your media playback experience.

Setting Up Your mpv JavaScript Environment

Unlike many modern applications that require complex build tools, mpv includes a built-in MuJS JavaScript interpreter. This allows you to write standard JavaScript files (.js) and run them directly.

To get started, you need to place your script in the correct configuration directory so mpv can load it automatically on startup:

Simply create a text file named my-plugin.js in this folder, and mpv will execute it whenever the player launches.

Binding Keys to Custom Functions

The core of most mpv plugins is mapping keyboard shortcuts to specific actions. The API provides the mp.add_key_binding() function to handle this. It takes three arguments: the key name, a unique identifier string, and the function to execute.

function helloWorld() {
    mp.osd_message("Hello from your custom plugin!");
}

// Binds the 'Ctrl+h' key to trigger the helloWorld function
mp.add_key_binding("ctrl+h", "hello_shortcut", helloWorld);

When you press Ctrl+h, mpv will display a brief On-Screen Display (OSD) message acknowledging the command.

Interacting with Player Properties

To control playback, you must read or modify mpv’s internal properties, such as volume, speed, or time position. The API utilizes mp.get_property() and mp.set_property() for these interactions.

The following example demonstrates how to create a custom toggle that speeds up video playback:

var fastSpeed = false;

function toggleSpeed() {
    if (!fastSpeed) {
        mp.set_property("speed", 2.0); // Double playback speed
        mp.osd_message("Speed: 2x");
        fastSpeed = true;
    } else {
        mp.set_property("speed", 1.0); // Reset to normal speed
        mp.osd_message("Speed: 1x");
        fastSpeed = false;
    }
}

mp.add_key_binding("j", "toggle_speed", toggleSpeed);

Listening to Playback Events

An advanced plugin often needs to react automatically to changes in the player’s state without user intervention. You can achieve this by registering observers with mp.observe_property().

This code snippet listens for changes in the track title and logs it to the terminal console whenever a new file begins playing:

function onTitleChange(name, value) {
    if (value) {
        mp.msg.info("Now playing: " + value);
    }
}

// Observe the 'media-title' property and trigger the callback on change
mp.observe_property("media-title", "string", onTitleChange);

By combining key bindings, property manipulation, and event observers, you can build powerful automated workflows tailored to your specific media consumption needs.