171 lines
5.6 KiB
Markdown
171 lines
5.6 KiB
Markdown
# mpvremote
|
|
|
|
A Python 3 curses TUI that acts as a TV-style remote control for a running
|
|
[mpv](https://mpv.io/) instance, driven over its UNIX-socket IPC interface.
|
|
|
|
Any device that can connect to your MPV machine via SSH and run a curses TUI
|
|
in an SSH shell — a phone, a laptop, a potato with a terminal — can be a
|
|
remote controller for your MPV. No X forwarding, no web server, no extra
|
|
dependencies: just SSH in and drive your media player from the couch.
|
|
|
|
## How it works
|
|
|
|
mpv exposes a JSON IPC interface when launched with `--input-ipc-server`.
|
|
mpvremote connects to that socket, polls playback properties (title, position,
|
|
volume, loop state, ...) and sends commands (seek, pause, queue, ...) — the
|
|
same interface mpv's own scripting API uses, but from a terminal UI.
|
|
|
|

|
|
|
|
## Requirements
|
|
|
|
- Python 3.6+ (standard library only — no pip installs)
|
|
- mpv running with IPC enabled
|
|
- Terminal with curses support (any Linux SSH session)
|
|
|
|
## Quick start
|
|
|
|
On the MPV machine, launch mpv with the IPC socket:
|
|
|
|
```bash
|
|
mpv --input-ipc-server=/tmp/mpv-socket video.mkv
|
|
```
|
|
|
|
Or make it permanent in `mpv.conf`:
|
|
|
|
```
|
|
input-ipc-server=/tmp/mpv-socket
|
|
```
|
|
|
|
Then, from any device, SSH in and run the remote from the repo root:
|
|
|
|
```bash
|
|
ssh user@mpv-machine
|
|
cd mpvremote
|
|
python3 -m mpvremote
|
|
```
|
|
|
|
### Install for your user
|
|
|
|
Install a launcher and module copy under `~/.local` without root privileges:
|
|
|
|
```bash
|
|
make install
|
|
```
|
|
|
|
If `~/.local/bin` is not already on your `PATH`, add this line to your shell
|
|
startup file (for example, `~/.bashrc`) and open a new shell:
|
|
|
|
```bash
|
|
export PATH="$HOME/.local/bin:$PATH"
|
|
```
|
|
|
|
Verify the installation and print command-line usage with:
|
|
|
|
```bash
|
|
make verify
|
|
mpvremote --help
|
|
```
|
|
|
|
Remove the user-level installation with `make uninstall`. Set `PREFIX` to
|
|
install under a different directory.
|
|
|
|
## Configuration
|
|
|
|
The IPC socket and video extensions are set in `mpvremote/config.py`. The media
|
|
directory defaults to `~/Videos` and can be changed in the app's Settings view
|
|
(`x`). The selected path is stored in `~/.config/mpvremotemedia`.
|
|
|
|
| Setting | Default | Description |
|
|
|--------------|--------------------|---------------------------------------|
|
|
| `SOCKET` | `/tmp/mpv-socket` | Path to mpv's IPC socket |
|
|
| `VIDEO_EXTS` | `mp4 mkv avi webm` | File extensions treated as video |
|
|
|
|
## Keybindings
|
|
|
|
### Main view (the remote)
|
|
|
|
| Key | Action |
|
|
|---------|----------------------------|
|
|
| `Space` | Pause / resume |
|
|
| `h`/`l`, `←`/`→` | Seek -10s / +10s |
|
|
| `j`/`k`, `↓`/`↑` | Volume -5 / +5 |
|
|
| `s` | Cycle subtitles |
|
|
| `n`/`p` | Next / previous track |
|
|
| `r` | Toggle loop current file |
|
|
| `R` | Toggle loop playlist |
|
|
| `e` | Playlist view |
|
|
| `o` | Queue view |
|
|
| `x` | Settings (media directory) |
|
|
| `a` | About page and controls |
|
|
| `q` | Quit |
|
|
|
|
### Playlist view
|
|
|
|
| Key | Action |
|
|
|----------------|--------------------------|
|
|
| `Up`/`Down` | Navigate |
|
|
| `Enter` | Skip to selected item |
|
|
| `Del`/`d` | Remove selected item |
|
|
| `Esc`/`q`/`←` | Back to main view |
|
|
|
|
### Queue view
|
|
|
|
| Key | Action |
|
|
|--------------|-------------------------------------|
|
|
| type | Incremental search of `MEDIA_DIR` |
|
|
| `Up`/`Down` | Navigate |
|
|
| `Enter` | Queue selected video (append-play) |
|
|
| `Backspace` | Delete search character |
|
|
| `Esc` | Clear search / back to main view |
|
|
|
|
## Status bar
|
|
|
|
The top status bar shows the current playback state:
|
|
|
|
```
|
|
> Playing | 1:23 / 5:00 | L:F+P | My Video Title | Vol: 50
|
|
```
|
|
|
|
| Segment | Meaning |
|
|
|----------------|-------------------------------------------------------------|
|
|
| `> Playing` | Playback state (`\|\| Paused` when paused) |
|
|
| `1:23 / 5:00` | Current position / duration |
|
|
| `L:F+P` | Loop state (see below) |
|
|
| Title | Media title of the current file |
|
|
| `Vol: 50` | Volume level |
|
|
|
|
Loop indicators:
|
|
|
|
| Indicator | Meaning |
|
|
|-----------|----------------------------------|
|
|
| `L:--` | No looping |
|
|
| `L:F` | Current file loops |
|
|
| `L:P` | Playlist loops |
|
|
| `L:F+P` | Both file and playlist looping |
|
|
|
|
## Views
|
|
|
|
- **Main** — the remote: playback controls with a scrolling feedback log
|
|
- **Playlist** — the current mpv playlist; skip to or remove entries
|
|
- **Queue** — search your media library and append videos to the playlist
|
|
|
|
The media library in `MEDIA_DIR` is scanned at startup and rescanned in the
|
|
background every 2 minutes, so newly added files show up without a restart.
|
|
|
|
## Project layout
|
|
|
|
```
|
|
mpvremote/
|
|
├── mpvremote/
|
|
│ ├── __init__.py # Package exports
|
|
│ ├── __main__.py # Entry point: socket check + curses bootstrap
|
|
│ ├── app.py # App shell: drawing, colors, views, media rescan
|
|
│ ├── config.py # Socket path, media dir, extensions, key bindings
|
|
│ ├── mpv_client.py # Minimal mpv JSON IPC client (AF_UNIX socket)
|
|
│ └── views.py # MainView, PlaylistView, QueueView
|
|
```
|
|
|
|
## License
|
|
|
|
GPLv3
|