An open API service indexing awesome lists of open source software.

https://github.com/baldomo/open-in-mpv

Simple web extension to open videos in mpv
https://github.com/baldomo/open-in-mpv

chrome-extension firefox-extension golang mpv video

Last synced: 19 days ago
JSON representation

Simple web extension to open videos in mpv

Awesome Lists containing this project

README

        

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](https://mpv.io).

The extension itself shares a lot of code with the one from the awesome [iina](https://github.com/iina/iina), while the (bare) native binary is written in Go (this is a rewrite from C++).

- [Installation](#installation)
- [Configuration](#configuration)
- [Flag overrides](#flag-overrides)
- [Example](#example)
- [The `mpv://` protocol](#the-mpv-protocol)
- [Playlist and `enqueue` functionality](#playlist-and-enqueue-functionality)
- [Player support](#player-support)
- [Supported protocols](#supported-protocols)
- [Troubleshooting and tips](#troubleshooting-and-tips)

### Installation
> Compiled binaries and packed extensions can be found in the [releases page](https://github.com/Baldomo/open-in-mpv/releases).

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\\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:

```yaml
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](config.yml) or the [example](#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](#supported-protocols) |
| `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](#the-mpv-protocol) 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:

```yaml
flag_overrides:
"*": "--mpv-%s"
```

#### Example

This is a full example of a fictitious player definition in the configuration file:

```yaml
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](#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).

```conf
input-ipc-server=/tmp/mpvsocket
```

### Player support
Supported players are defined in `config.yml`, where the struct `Player` ([see `config.go`](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](https://en.wikipedia.org/wiki/List_of_URI_schemes)), only protocols/[schemes](https://en.wikipedia.org/wiki/List_of_URI_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