trav 663d5e5a08 v0.1.4: playback-control provenance log
LinTunes has spontaneously resumed playback for ~4s (then paused) four
times while trav was away — suspected phantom media-key events from the
Audioengine USB DAC's HID 'keyboard', but the pathway (MPRIS vs the
focused-window key filter) is unproven. Every control path now drops a
timestamped line in ~/.cache/lintunes/control-events.log: MPRIS Player
methods, the media-key eventFilter (with source input device where the
compositor exposes it), and Player.toggle_play/pause with position. New
lintunes/eventlog.py, 1MB rotation, never raises; conftest autouse
fixture keeps tests off the real log file.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 18:09:21 -04:00
2026-06-26 21:12:01 -04:00
2026-06-26 21:12:01 -04:00
2026-06-26 21:12:01 -04:00

LinTunes

LinTunes

an mp3 library manager and player for linux. Absolutely no guarantees, if it wrecks your itunes library or wipes your harddrive that's on you (maybe just have your LLM of choice review the software for bugs and vulns?).

Features

  • can import an iTunes 12 (untested on other versions) library, including smart playlists (auto-updating, editable, marked with a ❧)
  • runs on several machines off one Syncthing-synced library (see below)

How it works

  • Your music files are never moved or rewritten (except when you edit tags).
  • The library lives as plain JSON files (library.json + one file per playlist) in a directory you choose — designed to be synced with Syncthing; sync conflicts are merged automatically on startup (play counts take the max, edits take the newest, playlists take the union).
  • Playback via Qt Multimedia/FFmpeg (mp3, m4a, flac). Media keys work through MPRIS. Scrobbling to last.fm is optional (Edit → Preferences).

Why

I have been a mac user for ~34 years. I gave up daily driving mac os in 2020. I figured Apple

but my music library even some tracks I got from napster all the way back in 2000 (I have since paid for!!)

Installing

LinTunes needs four Python packages — PyQt6 (with its QtMultimedia module), mutagen, numpy, requests — plus the FFmpeg codecs for Qt Multimedia so audio actually plays. Nothing compiles; get the deps whichever way fits your distro:

  • pip — simplest where your distro allows it; also puts a lintunes command in ~/.local/bin:
    pip install -e .
    
  • Debian/Ubuntu — system pip is locked down (the externally-managed-environment / PEP 668 error), so install the deps from apt and skip pip entirely:
    sudo apt install python3-pyqt6 python3-pyqt6.qtmultimedia \
                     python3-mutagen python3-numpy python3-requests
    
    (If python3-pyqt6.qtmultimedia isn't found, apt search python3-pyqt6 and grab the multimedia one.) There's no lintunes command this way — run it with python3 -m lintunes.main.
  • venv — isolated:
    python3 -m venv .venv && .venv/bin/pip install -e .
    
    Run with .venv/bin/lintunes. One caveat: the dock launcher (see App icon) uses the system python, which can't see a venv's packages — so for the icon to work, edit the installed lintunes.desktop's Exec= line to the absolute venv path (…/lintunes/.venv/bin/lintunes %F).

You never strictly need pip or the lintunes command. As long as those four deps import, python3 -m lintunes.main from the checkout runs the app — which is exactly what the desktop launcher does. The FFmpeg codecs come from qt6-qtmultimedia built with ffmpeg (Fedora: RPM Fusion; Debian/Ubuntu: pulled in by python3-pyqt6.qtmultimedia). Without them the UI runs but tracks won't play.

Running it

# one-time import from iTunes (XML: File ▸ Library ▸ Export Library in iTunes 12.x)
python3 -m lintunes.main --import-xml "iTunes Library.xml" \
    --music-root "/path/to/iTunes Media" \
    --data-dir /path/to/library-data --save-config
python3 -m lintunes.main            # run the app (uses the saved config)

(Installed with pip? Type lintunes instead of python3 -m lintunes.main.)

LinTunes looks best with Century Gothic installed (~/.local/share/fonts/); if it's missing, you'll be asked to pick a font on first run.

The desktop launcher runs LinTunes with no --data-dir, so it always uses whatever is saved in ~/.config/lintunes/config.json — point that config wherever you want and the dock icon follows.

Running on a second machine (Syncthing)

Keep the data dir (which holds library.json, the playlists, and preferences.json) inside your Syncthing-shared music folder, so the music and the library travel together. Track paths are stored relative to the data dir, so the library resolves correctly no matter where each machine mounts the shared folder — you never edit anything inside the library to move it.

~/.config/lintunes/config.json is per-machine (it is not synced), so on a new machine you just tell LinTunes where the synced folder landed:

# 1. get the code, then install the deps (see "Installing" above: pip / apt / venv)
git clone ssh://git@git.autonomic.zone:2222/trav/lintunes.git
cd lintunes

# 2. let Syncthing finish replicating the music folder, then point the config at
#    THIS machine's paths and launch — no re-import, the data is already synced:
python3 -m lintunes.main --data-dir  "/path/to/synced/music/lintunes" \
                         --music-root "/path/to/synced/music/iTunes Media" \
                         --save-config

# 3. install the launcher + icon, then pin it (see "App icon" below)
bash packaging/install-desktop.sh

(Step 2 just writes data_dir + music_root into ~/.config/lintunes/config.json — you can also create that file by hand. After it's saved, every launch, including the dock icon, uses the synced library automatically.)

Keys

Space play/pause · ←/→ previous/next · Ctrl+B column browser · Ctrl+I get info · Ctrl+, preferences · Ctrl+C/Ctrl+X/Ctrl+V copy/cut/paste tracks · double-click sidebar art for a big art window

App icon

packaging/install-desktop.sh installs the launcher entry and icon for your user (lets you pin LinTunes to the GNOME dash). The icon is just a file — replace packaging/lintunes.png (256×256 PNG) and re-run the script to use your own. GNOME caches icons, so if the old one lingers, log out and back in.

Unpinning from the dash does not uninstall LinTunes — it's still in the GNOME app grid (open Activities and search "LinTunes"). Right-click it there → Pin to Dash to get it back.

Development

python3 -m pytest tests/

spec.md is the original design brief; tasks*.md track what's built.

Description
No description provided
Readme 1.1 MiB
Languages
Python 99.7%
Shell 0.3%