README: new features, and a Cassette guide for first-timers

Adds the features shipped since the list was written (Identify Track,
Import from URL, andTunes, art sources, New Tracks, merge improvements,
Cassette) without touching the existing lines, and a step-by-step guide
at the end: installing Syncthing, inviting a friend, choosing what to
share, cassetting songs, following playlists and troubleshooting. Icons
and screenshots in docs/cassette/ are rendered from the app's own
painting code against the synthetic dev library.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 22:06:35 -07:00
co-authored by Claude Opus 5.5
parent 87d43f8e0c
commit 051312d91d
11 changed files with 203 additions and 0 deletions
+203
View File
@@ -29,12 +29,25 @@ I have been a mac user for ~34 years. I gave up daily driving mac os in 2021. Af
`Artist/Album/` tree.
- **Undo/redo everything** (Ctrl+Z / Ctrl+Shift+Z) — edits, deletes, reorders.
- Deleting a track sends the file to your desktop **Trash**, never `rm`.
- **Identify Track…** listens to a song (Chromaprint + AcoustID) and proposes
its real title, artist, album and *original* release year — and when the
internet has never heard of it, reads the answer out of the filename.
- **Import from URL…** (File menu) — paste a link and the song is downloaded
(yt-dlp), filed, and handed straight to Identify Track.
- Album art is searched on both iTunes and **Deezer**, can be pasted onto a
whole album's worth of tracks at once, and clicking the blank cover in the
sidebar goes looking for it.
- Right-click any song to **look it up on YouTube**.
- Every song you add is stamped with the day you added it.
**Playlists**
- Regular playlists, **folders**, and **smart playlists** (auto-updating, with a
full rule editor).
- Drag and drop to reorder or insert at a spot; duplicate-aware adds;
copy/cut/paste tracks between playlists.
- Click a selected playlist's name to rename it.
- New libraries start with a **New Tracks** smart playlist (everything added in
the last 3 months).
**Playing**
- mp3, m4a, flac, aac, wav, aiff.
@@ -43,18 +56,34 @@ I have been a mac user for ~34 years. I gave up daily driving mac os in 2021. Af
- Live **spectrum visualizer** — click it to cycle bright / dim / off.
- last.fm scrobbling
- Theming: highlight color, UI scale, and custom colors
- A soft emboss on every button that follows your custom colors.
**Sending music elsewhere**
- **Chromecast**
- **Export a playlist** (File ▸ Export Playlist…) — either a folder of
`Artist - Title.mp3` files plus an `.m3u`, or a self-contained `index.html` you can upload anywhere.
- **Sync a playlist to a Rabbit R1** over MTP, `.m3u` included.
- **andTunes**, a small music player for the Rabbit R1 that LinTunes installs
and fills from the Connections menu — and the plays you rack up on the Rabbit
come back into your library.
**Living on more than one machine**
- The whole library is **plain JSON**, designed to be synced with
[Syncthing](https://syncthing.net). Sync conflicts merge themselves on
startup.
- The version number in the status bar checks for updates (via git) and you can click it to update to the latest version.
- Play counts can never conflict (each machine keeps its own tally), a song you
remove on one machine stays removed, and the merge report only speaks up when
something you'd care about happened.
**Sharing with friends (Cassette)**
- Share parts of your library with a friend — one pasted code connects you,
over [Syncthing](https://syncthing.net), with no server anywhere.
- You choose exactly what each friend can see: the whole library, or just
certain artists, albums, songs and playlists.
- Browse a friend's library and press the little cassette buttons on anything
you'd like; those songs arrive in your library by themselves.
- Follow a friend's playlist and play it right from your own sidebar.
@@ -248,3 +277,177 @@ python3 -m pytest tests/
```
`spec.md` is the original design brief; `tasks*.md` track what's built.
## Sharing music with friends (Cassette)
Cassette lets you and a friend peek at each other's libraries and ask for
songs. There's no server and no account: your two computers talk directly
through a free program called **Syncthing**, and LinTunes just tells Syncthing
what to do. Neither of you can change or delete anything on the other's
computer.
You'll both need LinTunes and Syncthing. You **don't** need to be online at the
same time — things simply finish the next time both computers are on.
### 1. Install and start Syncthing (once)
Open a terminal (see *Never used a terminal?* above) and paste the line for
your distro:
```sh
sudo apt install syncthing # Debian / Ubuntu / Mint
sudo dnf install syncthing # Fedora
```
Then start it, and have it start by itself every time you log in:
```sh
systemctl --user enable --now syncthing
```
To check it's running, open <http://127.0.0.1:8384> in your web browser —
you should see Syncthing's page. You don't have to do anything there; the
default settings (including "global discovery" and "relaying", which let two
computers find each other across the internet) are exactly right.
> **Already using Syncthing to keep your library on two of your own
> computers?** Great — nothing changes. Only one of your computers handles
> friends; LinTunes asks which the first time (see below), and songs it brings
> in reach your other computers the usual way.
### 2. Connect with a friend
One of you **invites**, the other **pastes**. It doesn't matter who.
**If you're inviting:** in LinTunes choose **Connections ▸ Share Library with a
Friend…**. The very first time, LinTunes asks *"Use this computer for sharing
with friends?"* — say **Yes**. You'll get an **invite code**: a long line
starting with `LTC1.` Press **Copy Code** and send it to your friend however you
like (text, email, chat). Each code works for **one** friend, once.
**If you were sent a code:** choose **Connections ▸ Add Friend Library…**,
paste the whole code into the box, and press **Connect**.
That's it. When the two computers have found each other, you'll see
**"*Name* is now connected."** at the bottom of the window. This can take a
minute — or, if the other computer is off, however long until it's back on.
You can see how it's going any time in **Connections ▸ Sync Settings…**: pick
your friend in the list on the left. Invites nobody has used yet are listed on
the **General** page, with a **Cancel Invite** button each.
### 3. Choose what your friend can see
**Nothing is shared until you say so.** In **Connections ▸ Sync Settings…**,
click your friend's name on the left. Below their connection status are two
sections:
- **Library** — tick the artists, albums or songs your friend may ask for, or
tick **Share whole library** for everything (including songs you add later).
- **Playlists** — tick the playlists to share, or **Share all playlists**.
A shared playlist brings its songs along: they show up ticked and greyed in
the Library section (hover one to see which playlist is holding it there).
**Select All** and **Select None** do what they say — and if you click one by
accident, just press **Cancel**: nothing is saved until you press **OK**.
Want everyone to see the same thing? On the **General** page, tick **Share the
same selection with all friends** and choose there instead.
Sharing something doesn't send it. Your friend only receives what they ask
for.
### 4. Browse a friend's library and ask for songs
Once you have a friend, a small **▾** appears on the right end of the
**Library** button:
<img src="docs/cassette/library-selector.png" alt="The Library button with the ▾ friend selector on its right" width="216">
Click the **▾** and pick your friend. The button turns light purple and shows
their library's name — you're now looking at what they've shared with you:
<img src="docs/cassette/friend-library-button.png" alt="The Library button in friend mode, purple, reading Sam's Library" width="216">
![Browsing a friend's library](docs/cassette/friend-mode.png)
It works just like your own library, except nothing plays (the songs aren't on
your computer yet). Instead, every artist, album and song has a little
**cassette button**:
| Button | What it means |
|---|---|
| <img src="docs/cassette/cassette-off.png" width="28" alt="cassette button, not pressed"> | Not asked for. Click it to ask your friend for this. |
| <img src="docs/cassette/cassette-on.png" width="28" alt="cassette button, pressed"> | Asked for — this song is on its way to you. Click again to change your mind. |
| <img src="docs/cassette/cassette-partial.png" width="28" alt="cassette button, partly pressed"> | Some of this artist's or album's songs are asked for. Click to ask for all of them. |
Pressing the button on an **artist** or **album** asks for every song under it.
Along the bottom of the window:
- **Hide tracks I have** hides songs you already own. Songs that are *probably*
the same as one of yours (same artist and title, different album or length)
stay visible in light grey so you can decide.
- The **size** of what you've asked for, next to your free space. It turns
**orange** if it would leave so little space that Syncthing pauses, and
**red** if it won't fit at all.
- **Save and Close** sends your list to your friend and takes you back to your
own library. **Cancel** forgets the changes. (Leaving any other way with
changes asks *"Save changes?"* first.)
The songs you asked for arrive in your library **by themselves**, filed by
artist and album like anything you'd add yourself, with *"3 songs arrived from
Sam."* at the bottom of the window. They come with their names, album info and
artwork — but not your friend's play counts or ratings.
### 5. Follow a friend's playlist
In a friend's library, their shared playlists are listed on the left, each
with a UFO. Click a playlist's **UFO** to follow it:
| Icon | What it means |
|---|---|
| <img src="docs/cassette/ufo-not-followed.png" width="28" alt="grey outline UFO"> | Not following. Click the UFO to follow this playlist. |
| <img src="docs/cassette/ufo-followed.png" width="28" alt="purple UFO"> | Following. Click again to stop. |
Press **Save and Close**, and the playlist appears in **your** sidebar with a
purple UFO, and plays like any other playlist:
![A followed playlist in the sidebar](docs/cassette/followed-playlist.png)
- Songs that are still on their way show in grey; they become playable as they
arrive. The bottom of the window says when your friend's folder last synced.
- A followed playlist's songs are **kept separate from your library** — you get
to listen without them filling up your collection. Like one? Right-click the
column headings, turn on **Cassette**, and press its cassette button to add
it to your library.
- Right-click a followed playlist in the sidebar and choose **Unfollow** to let
it go (its songs are cleaned up afterwards).
Two choices per friend, in **Sync Settings** on their page:
- Show followed playlists **mixed in with yours**, or grouped **in a folder
with their name**.
- **Keep their songs separate** (the default), or **add them to your library**
automatically.
### If something isn't working
Sync Settings always says what's going on in plain words and what to do next.
The common ones:
- **"Syncthing isn't running"** — run `systemctl --user start syncthing`, then
press **Retry** on the General page.
- **"Can't reach Syncthing's API"** — press **Read from Syncthing** on the
General page. (Or copy the key from Syncthing's page at
<http://127.0.0.1:8384>: **Actions ▸ Settings ▸ General ▸ API Key**.)
- **"Waiting for *Name*'s computer"** for a long time — both computers need to
be on with Syncthing running, and your friend needs to have opened LinTunes
once since you pasted the code. If it never connects, the code may already
have been used: ask for a new one.
- **"That code isn't valid"** — part of the code got lost when it was copied.
It's one long line starting with `LTC1.`; ask your friend to send it again.
- **"This invite has already been used"** — codes work once. Ask for a new one.
To stop sharing with someone, open their page in Sync Settings and press
**Remove Friend…**. Songs you already brought into your library stay.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB