This is a simple web extension (for Chrome and Firefox) which helps open any video in the currently open tab in the mpv player.
The extension itself shares a lot of code with the one from the awesome iina, while the (bare) native binary is written in Go (this is a rewrite from C++).
- Installation
- Configuration
- The
mpv://protocol - Playlist and
enqueuefunctionality - Player support
- Supported protocols
- Troubleshooting and tips
Installation
Compiled binaries and packed extensions can be found in the releases page.
To build and install open-in-mpv and the mpv:// protocol handler, just run
$ sudo make install
$ make install-protocol
Configuration
The configuration file has to be named config.yml and can be placed in the same folder as the executable or in:
| Windows | Linux/BSDs | MacOS | ||
|---|---|---|---|---|
| System level configuration | C:\ProgramData\open-in-mpv\ |
/etc/xdg/open-in-mpv/ |
/Library/Application Support/open-in-mpv/ |
|
| User level configuration | C:\Users\<User>\AppData\Roaming\ |
${HOME}/.config/open-in-mpv/ |
${HOME}/Library/Application Support/open-in-mpv/ |
The user level configuration will always override the system level one.
The configuration file has the following structure:
fake: # open_in_mpv.Player name: # string executable: # string fullscreen: # string pip: # string enqueue: # string new_window: # string needs_ipc: # true | false supported_protocols: # []string flag_overrides: # map[string]string
See the default configuration or the example below
And the open_in_mpv.Player object is defined as follows:
| Key | Example value | Description |
|---|---|---|
name |
mpv |
Full name of the video player; not used internally |
executable |
mpv |
The player's binary path/name (doesn't need full path if already in $PATH) |
fullscreen |
"--fs" |
Flag override to open the player in fullscreen (can be empty) |
pip |
"--pip" |
Flag override to open the player in picture-in-picture mode (can be empty) |
enqueue |
"--enqueue" |
Flag override to add the video to the player's queue (can be empty) |
new_window |
"--new-window" |
Flag override to force open a new player window with the video (can be empty) |
needs_ipc |
false |
Controls whether the player needs IPC communication (only generates mpv-compatible JSON commands, used for enqueing videos) |
supported_protocols |
["http", "https"] |
An arbitrary whitelist of protocols the player supports. See the relevant section |
flag_overrides |
"*": "--mpv-%s" |
Defines arbitrary text overrides for command line flags (see below) |
Flag overrides
The configuration for a player can contain overrides for command line flags defined in the web extension's configuration page, so not to make a different player crash/not start because the flags are not accepted. With the correct overrides any kind of flag passed in the URL by the extension will either be ignored or replaced with a pattern/prefix/suffix so that it becomes valid for the player in use.
"*": matches anything and will take precedence over any other override- e.g. the pair
"*": ""will void all flags
- e.g. the pair
"flag": matches the flag--flag- e.g. the pair
"--foo": "--bar"will replace--foowith--bar
- e.g. the pair
"%s": is replaced with the original flag without any leading dash- e.g. the pair
"--foo": "--%s-bar"will replace--foowith--foo-bar
- e.g. the pair
Note: command line options with parameters such as
--foo=barare considered as a whole, single flag
Celluloid, for example, expects all mpv-related command line flags to be prefixed with --mpv-, so its configuration will contain the following overrides:
flag_overrides: "*": "--mpv-%s"
Example
This is a full example of a fictitious player definition in the configuration file:
players: fake: name: fake-player executable: fakeplayer fullscreen: "--fs" pip: "--ontop --no-border --autofit=384x216 --geometry=98\\%:98\\%" enqueue: "--enqueue" new_window: "" needs_ipc: true supported_protocols: - http - https - ftp - ftps flag_overrides: "*": "--mpv-options=%s"
The mpv:// protocol
open-in-mpv install-protocol will create a custom xdg-open desktop file with a scheme handler for the mpv:// protocol. This lets xdg-open call open-in-mpv with an encoded URI, so that it can be parsed and the information can be relayed to mpv - this logic follows how iina parses and opens custom URIs with the iina:// protocol on Mac. install-protocol.sh has the same functionality.
Please note that this specification is enforced quite strictly, as the program will error out when at least one of the following conditions is true:
- The protocol is not
mpv:// - The method/path is not
/open - The query is empty
The table below is a simple documentation of the URL query keys and values used to let the open-in-mpv executable what to do.
| Key | Example value | Description |
|---|---|---|
url |
https%3A%2F%2Fyoutu.be%2FdQw4w9WgXcQ |
The actual file URL to be played, URL-encoded |
full_screen |
1 |
Controls whether the video is played in fullscreen mode |
pip |
1 |
Simulates a picture-in-picture mode (only works with mpv for now) |
enqueue |
1 |
Adds a video to the queue (see below) |
new_window |
1 |
Forcibly starts a video in a new window even if one is already open |
player |
celluloid |
Starts any supported video player (see Player support) |
flags |
--vo%3Dgpu |
Custom command options and flags to be passed to the video player, URL-encoded |
Playlist and enqueue functionality
For enqueue to work properly with any mpv-based player (provided it supports mpv's IPC), the player has to read commands from a socket. This can be achieved by adding the following line to the video player's configuration (usually $HOME/.config/mpv/mpv.conf for mpv).
input-ipc-server=/tmp/mpvsocketPlayer support
Supported players are defined in config.yml, where the struct Player (see config.go) defines supported functionality and command line flag overrides. To request support for a player you're welcome to open a new issue or a pull request or just add your own in your configuration file.
Supported protocols
Since opening an arbitrary URL with a shell command can cause remote code execution on the host machine (for example by loading arbitrary .so files on a player by using special schemes), only protocols/schemes explicitly specified in the configuration will be processed by the native binary without errors. Defaults to ["http", "https"] if empty. There is also no special instructions parsing or catch-all values.
Troubleshooting and tips
This section will be updated with tips and tricks coming mainly from the issues and community.
Setting a working directory for the called player
- Abstract: in Windows, if the player and/or
yt-dlpare installed as root, the player fails silently becauseyt-dlp(which is being ran as the current user) cannot write to its own directory - Links: issue #13
- Solution: pass the
--paths temp:%TMP%argument toyt-dlpto make it use a temporary directory instead of writing to the installation directory
Additional setup for AppArmor (and similar) hardened distros (Ubuntu, Debian, Fedora, etc.)
Some distros have AppArmor (Ubuntu/Debian), SELinux (Fedora) enabled by default. This can lead to the browser being unable to launch the helper binary. For Ubuntu and derivatives you need to edit the AppArmor profile for Firefox located at /etc/apparmor.d/usr.bin.firefox by adding the path to the open-in-mpv helper binary and providing it with execute rights.
# Rule for open-in-mpv helper
/path/to/the/helper/open-in-mpv Uxr,

