No description
  • Go 98.8%
  • Makefile 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Yulqen 8c9aa7017e Add mix yt for YouTube Music search and playback
Search the songs tab with yt-dlp, preview like a local mix, and store
watch URLs in the usual m3u so resume works. mpv uses itag 18 and the
android player client to avoid googlevideo 403s.
2026-08-19 11:40:04 +01:00
cmd/mix Add mix yt for YouTube Music search and playback 2026-08-19 11:40:04 +01:00
internal Add mix yt for YouTube Music search and playback 2026-08-19 11:40:04 +01:00
.gitignore First commit 2026-08-16 17:18:17 +01:00
go.mod First commit 2026-08-16 17:18:17 +01:00
go.sum First commit 2026-08-16 17:18:17 +01:00
Makefile First commit 2026-08-16 17:18:17 +01:00
README.md Add mix yt for YouTube Music search and playback 2026-08-19 11:40:04 +01:00

mix

Generate a random playlist from a local (or NFS) music library, preview it in the terminal, and play it with mpv. Quit halfway through and mix will offer to resume at the same track and timestamp.

Install

make install

Puts the binary in ~/.local/bin/mix. Requires Go 1.25+ and mpv on PATH.

Usage

mix                 # resume an unfinished mix, or generate a new one
mix new             # always generate
mix resume          # resume the current mix
mix list            # archived mixes
mix show [NAME]     # tracks in a mix (current if omitted)
mix play NAME       # play a saved mix (id or name)
mix save [name]     # name the current mix
mix index           # rebuild the file index after you add albums
mix yt QUERY        # search YouTube Music and play

Flags:

-n, --count N              tracks per mix (default 50)
    --root PATH            music library root
    --refresh              rebuild the index before generating
    --allow-repeats-album  allow more than one song from the same album

On generate, mix prints a numbered Artist / Album / Title table and asks [a]ccept [r]eroll [q]uit. Accept writes a timestamped .m3u (never overwritten) and optionally names it, then starts mpv.

YouTube Music

mix yt searches YouTube Music's songs tab (not generic video search), previews the same table, and on accept writes watch URLs into an .m3u. mpv re-extracts those URLs at play time via yt-dlp. The query is all remaining arguments, so you do not need quotes:

mix yt stars of the lid
mix yt -n 5 laufey from the start

Reroll shuffles the search pool (about 40 songs) and shows another n tracks (default 10). Resume, mix play, and mix show work the same as local mixes.

Requires yt-dlp on PATH. YouTube currently 403s audio-only formats; mix tells mpv to use muxed itag 18 and player_client=android. Override in config.toml if that breaks:

ytdl_format = "18"
ytdl_extractor_args = "youtube:player_client=android"

One-off, without mix — quote the search, or the shell splits on spaces and mpv searches for stars (Simply Red, nursery rhymes, …):

mpv --no-video --ytdl-format=18 \
  --ytdl-raw-options-append=extractor-args=youtube:player_client=android \
  'ytdl://ytsearch1:stars of the lid'

ytsearch1: is YouTube video search (full albums often win). Prefer mix yt for actual songs.

Config

Optional ~/.config/mix/config.toml:

music_root = "/srv/nfs/rimsky/music"
count = 50
max_bytes = 83886080
extensions = ["mp3", "m4a", "flac", "ogg", "opus", "wav", "aac"]

Files larger than max_bytes (default 80 MiB) are treated as DJ mixes / films and skipped. Video extensions are never included.

The file index lives in ~/.cache/mix/index.json and is rebuilt only when missing or when you run mix index / --refresh. Playlists live in ~/.local/share/mix/playlists/.

Resume

mpv's own watch-later is per-file and does not restore playlist position, so mix talks to mpv over a local IPC socket and writes ~/.local/share/mix/session.json. A mix is finished only if you listen through the last track; quitting on that track still counts as unfinished.