mpvremote/DEVLOG.md

3.7 KiB

Development Log

This file records the app's architecture and the implementation choices made to improve startup and queue responsiveness. It describes intended behavior; no formal performance benchmark has been run.

Architecture

  • mpvremote/config.py is the central settings module. It defines the mpv IPC socket path, supported video extensions, key bindings, app version, and media directory. The media directory defaults to ~/Videos; an override is read from ~/.config/mpvremotemedia and can be edited in Settings.
  • mpvremote/mpv_client.py sends JSON commands to mpv over its Unix-domain IPC socket and decodes JSON responses.
  • mpvremote/views.py contains the curses views:
    • MainView provides playback controls and status.
    • PlaylistView displays and edits mpv's current playlist.
    • QueueView searches the configured media library and queues files.
    • SettingsView edits the media-directory setting.
    • AboutView displays app information and key bindings.
  • mpvremote/app.py initializes curses, constructs the views, owns the media cache and scan worker, and coordinates drawing and input in the application loop.
  • mpvremote/__init__.py exports App and SOCKET. Running python3 -m mpvremote loads the package and enters mpvremote/__main__.py. The entry point handles --help, checks that the configured socket exists, then uses curses.wrapper to set up and restore the terminal. The app enables keypad mode and handles input through its getch() loop.

Startup and media scanning

The initial recursive media scan runs on a background worker instead of blocking App initialization. The worker scans immediately and waits 120 seconds between subsequent scans. An event marks completion of the first scan. If Queue is opened before that scan completes, it displays a scanning message and populates automatically when the scan publishes its results.

The scan commits an immutable tuple of entries containing the display name, absolute path, and a pre-normalized casefold() name. Cache replacement and version increments happen under a lock. get_videos_with_version() returns the snapshot and version together; get_videos() retains the simpler (name, path) interface for other callers.

Responsiveness changes

Escape-key decoding

After curses initializes, the app requests a 50 ms Escape-sequence delay using curses.set_escdelay(), when the platform supports it. This reduces the wait when Escape is pressed while retaining a short interval for distinguishing Escape from terminal key sequences such as arrows.

Queue filtering and rendering

QueueView caches its indexed media snapshot and filtered results. Filtering runs only when the search query or media-cache version changes; rendering does not rescan or refilter the list. While Queue is active, the event loop uses a 100 ms input timeout and calls the view's update hook, allowing completed background scans to appear without requiring a keypress. Other views continue to wait for input normally.

User-level installation

The root Makefile provides install, verify, and uninstall targets. Installation copies the package beneath ~/.local/share/mpvremote and creates an executable ~/.local/bin/mpvremote wrapper that sets PYTHONPATH and runs python3 -m mpvremote. It does not edit shell startup files; it prints a PATH instruction when needed. The verification target runs the installed launcher with --help, which does not require mpv to be running.

Known performance limits

The main view still retrieves playback status properties synchronously through mpv IPC. Those requests have not been batched or moved to a background poller; they remain a possible area for future profiling and optimization.