Skip to content

Simple web extension to open videos in mpv

License

Notifications You must be signed in to change notification settings

Baldomo/open-in-mpv

Folders and files

NameName
Last commit message
Last commit date

Latest commit

author
Leonardo Baldin
Dec 26, 2024
0c642f3 · Dec 26, 2024

History

47 Commits
Jan 9, 2023
Dec 21, 2024
Dec 26, 2024
Jul 28, 2021
Jan 9, 2023
Dec 21, 2024
Jul 28, 2021
Jul 25, 2019
Dec 25, 2024
Aug 26, 2024
May 12, 2023
Aug 26, 2024
Jul 28, 2021
May 6, 2024
May 6, 2024
Jul 28, 2021
Aug 26, 2024
Aug 26, 2024

Repository files navigation

open-in-mpv


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

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
  • "flag": matches the flag --flag
    • e.g. the pair "--foo": "--bar" will replace --foo with --bar
  • "%s": is replaced with the original flag without any leading dash
    • e.g. the pair "--foo": "--%s-bar" will replace --foo with --foo-bar

Note: command line options with parameters such as --foo=bar are 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/mpvsocket

Player 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-dlp are installed as root, the player fails silently because yt-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 to yt-dlp to make it use a temporary directory instead of writing to the installation directory