a shell script for searching, playing, downloading, and keeping track of music from youtube and local files with extensive queue management using fzf, vim, or cli
demo: https://www.reddit.com/r/unixporn/comments/11mxwb0/oc_i_wrote_a_cli_and_keyboard_centric/
FEATURES:
- CLI/keyboard centered
- Add local files/directories
- Search regular youtube or youtube music (kind of… in a round about way. see usage for explanation)
- Select from search results
- Search and add youtube playlists to the queue (or only select songs of playlists)
- Select from past searches in fzf to reduce typing
- Download songs after they have been played a chosen amount of times (and play the download in the future)
- FZF preview of song/playlist details
- Manage the queue from fzf, vim, cli
- Keep track of listen history/amount
- Run commands on song start
- Specify a queue order to iterate through without having to shift entries in the queue file (see usage for -d)
- Communicate with mpv through its ipc socket
- Everything is a plain text file
https://github.com/trizen/pipe-viewer/)) — only tested on a GNU/Linux system
DEPS: fzf, yt-dlp, mpv, socat, gnu coreutils, dash/posix compatible shell, (for playlist search – pipe-viewer(NOT A DEP: accounts of any sort
git clone --depth 1 'https://github.com/unclereeemus/ytmp/'; cd ytmp; chmod +x ytmp run_on_next
(link/move ytmp to your $PATH like) [ln -s|mv] $(pwd)/ytmp /home/$USER/.local/bin/
(if intending to use nvim(‘E’ option)) mv ytmp.vim ~/.config/nvim/
move run_on_next to ~/Music/ytmp/ where it’s looked for by default; if you move it elsewhere,
change the location in the conf file which is also sourced from ~/Music/ytmp/ by default
(change conf path in source if necessary)
lastly, make sure mpv has the proper yt-dlp path in your mpv rc by setting script-opts=ytdl_hook-ytdl_path=
the mpv ipc socket is opened at /tmp/mpvsocketytmp
on first run
on first installing ytmp, there won’t be any history to select from when you enter ytmp so either pass arguements from the cli with ytmp [z]
or to search what’s on the fzf input field press ctrl-x or to background search press ctrl-s / ctrl-z (difference explained in ytmp h
)
ytmp main script; none of the other scripts need to be set up to get it working.
conf for setting ytmp variables/directories. looked for in ~/Music/ytmp/ by default.
run_on_next runs at the start of every song which can be used to keep some consistent settings within mpv (volume, loop, seek, etc). looked for in ~/Music/ytmp/ by default.
ytmp.vim a vim config with useful keybinds relevant to ytmp
ytmpsuite for oneliners or automation of things like toggling lines in run_on_next, selecting queues, creating playlists; some of the lines under ‘tips’ can be found there as well. there is no help option so you’ll have to parse through the code and comments to figure out what does what if you want to use it.
ytmp.gum a wrapper for mpv/ytmp/ytmpsuite to control playback/toggle things in run_on_next and ytmp. there are two modes for this; one is a status line showing currently playing, what’s before and after currently playing, and whether certain things are toggled for mpv/ytmp/ytmpsuite and optionally showing ascii/ansi art – utilizes gum (https://github.com/charmbracelet/gum); another where said certain things are toggled in an fzf menu (would recommend looking through the source for binds).
mightfinduseful a script to play music outside of ytmp either with local files, youtube search, or the ytmp queue file. also dynamically names the mpvsocket so you don’t overwrite an old one.
mpv_socket_commands wrapper for communicating with an mpv socket (see -h)
eww/ contain two eww (https://github.com/elkowar/eww) music widgets. see the readme in it to learn more and see pictures.
termux/ this program ported to termux with some new features missing from the linux version (because i am too lazy to maintain two files; if you want to try out the new features/termux version, the script should just work for linux just makes sure to change the $prefix in the script and add the ipc socket option to mpv if you like)
-
a dmenu wrapper:
cmd="$( printf ' ' | dmenu -p 'which ytmp cmd to run? ' )" && if ( printf "$cmd" | grep -Eq '^( |x.*|s.*|z|l s|v|vv|E|sp.*)+$' ); then setsid -f $TERMINAL -e ytmp $cmd >/dev/null 2>&1; else ytmp $cmd; fi
-
play dmenu selection:
cat "/home/$USER/Music/ytmp/queue" | dmenu -l 15 | cut -d' ' -f1 | xargs -I ,, ytmp P -id ,,
-
you don’t need to use ytmp to make playlists for it. to create a queue file from a youtube playlist you can do
yt-dlp --print id --print title '
or to create a queue file from search results do' | paste -s -d ' n' > file xargs -d 'n' -a
(to read from stdin instead of a file use-I ,, yt-dlp --print id --print title ytsearch:",," | paste -s -d ' n' > file printf '%sn' '
) or to search for playlists from the terminal (requires pipe-viewer):' ' ' ' ' | xargs [without -a option]... search='YOUR_SEARCH'; pipe-viewer --no-interactive -sp --custom-playlist-layout='*VIDEOS*VIDS *TITLE* *URL*' "$search" | fzf --bind='ctrl-a:execute(echo {} | awk "{print $NF}" | xargs -0 -I ",," pipe-viewer --custom-layout="*AUTHOR* *TIME* *TITLE*" --no-interactive ",," | fzf)' | awk '{print $NF}' | xargs -0 -I ',,' yt-dlp --print id --print title ',,' | paste -s -d ' n' > file
(have a look atytmpsuite sp
for a more featureful version with previews and individual song select orytmpsuite pvpl
to automate playlist search and add orytmpsuite scrape
to scrape lists from rym, aoty, discogs) -
convert spotify playlists to something ytmp can use: export the playlist to csv with https://github.com/watsonbox/exportify then run
cut -d'"' --output-delimiter=' ' -f4,8 PLAYLIST.CSV | sed 1d | tr -d '()[]' | xargs -d 'n' -I ',,' yt-dlp --print id --print title ytsearch1:",," | paste -s -d ' n' > file
-
play queue backwards:
while (ytmp -n); do ytmp p; done
-
to sort your play history by how many times you’ve listened to something use
sort -nk2 "/home/$USER/Music/ytmp/played_urls" | less
-
if you wanted to use this for videos instead of music, do a global remove of
--vid=no
and a global replace of--ytdl-format='bestaudio'
with your preference of video and audio quality (like--ytdl-format=bestvideo'[height<=?1080]'+bestaudio
) in the source. further, you could also display the covert art/always pop an mpv window open on the start of each song by doing a global replace of--vid=no
with--cover-art-file=
=?1080]+bestaudiocode>