-
Notifications
You must be signed in to change notification settings - Fork 5
/
ytmpsuite
149 lines (135 loc) · 9.99 KB
/
ytmpsuite
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/sh
conf="/home/$USER/Music/ytmp/conf"
. $conf
linetogstatus () {
line="$1"
( grep -qx "$1" "$run_on_next" ) && index="$( grep -nx "$1" "$run_on_next" | cut -d':' -f1 | xargs -I ',' echo ',+1' | bc )" && ( sed -n "${index}p" "$run_on_next" | grep -q '^# ' && echo "OFF" || echo "ON" )
sed -n "${index}p" "$run_on_next"
}
linetog () {
( grep -qx "$1" "$run_on_next" ) && index="$( grep -nx "$1" "$run_on_next" | cut -d':' -f1 | xargs -I ',' echo ',+1' | bc )"; ( sed -n "${index}p" "$run_on_next" | grep -q '^# ' ) && ( sed -i "${index}s/^# //" "$run_on_next"; echo "ON" ) || ( sed -i "${index}s/^/# /" "$run_on_next"; echo "OFF" )
sed -n "${index}p" "$run_on_next"
}
case "$1" in
k) mpv_socket_commands e quit st /tmp/mpvsocketytmp ;;
0) mpv_socket_commands cc seek 0 absolute st /tmp/mpvsocketytmp ;;
# play a random song once
r) ytmp e $(seq $(grep -c '' "$queue") | shuf -n1) ;;
# if `ytmp -r` (which uses `shuf`) isn't random enough
-r)
pgrep -f 'ytmp (-d|-r)+|ytmpsuite (qs|qn|-r)+' | grep -v $$ | xargs kill >/dev/null 2>&1
while (ytmp -n); do
min=1; max="$( grep -c '' "$queue" )"; rand=$(( RANDOM % ( $max - $min + 1 ) + $min )); ytmp e $rand
done
;;
-kd) pkill -f 'ytmpsuite (qsn|qs|qn|-r)+' ;;
# comment/uncomment the line following the comment # LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT
tm) linetog '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT MASTER' ;;
gtm) linetogstatus '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT MASTER' ;;
on) [ "$( ytmpsuite g"$2" | head -1 )" = 'OFF' ] && ytmpsuite $2 ;;
off) [ "$( ytmpsuite g"$2" | head -1 )" = 'ON' ] && ytmpsuite $2 ;;
gto) for f in t T t1 t2 tm; do ytmpsuite g"$f" | paste -s -d ' \n'; done ;;
tao|to) for f in t T t1 t2 tm; do [ "$( ytmpsuite g"$f" | head -1 )" = 'ON' ] && ytmpsuite $f >/dev/null 2>&1; done ;;
# toggle master (smartly) only if one of t1/t2 are on; otherwise off
tms)
if [ $( ytmpsuite gt1 | head -1 ) = 'ON' ] || [ $( ytmpsuite gt2 | head -1 ) = 'ON' ]; then
if [ "$( ytmpsuite gtm | head -1 )" != 'ON' ]; then ytmpsuite tm; fi
else
if [ "$( ytmpsuite gtm | head -1 )" != 'OFF' ]; then ytmpsuite tm; fi
fi
;;
t1) linetog '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT 1'; ytmpsuite tms ;;
gt1) linetogstatus '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT 1' ;;
t2) linetog '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT 2'; ytmpsuite tms ;;
gt2) linetogstatus '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT 2' ;;
t) linetog '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT' ;;
gt) linetogstatus '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT' ;;
T) linetog '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT ALT' ;;
gT) linetogstatus '# LINE BELOW IS TOGGLED BY AN EXTERNAL SCRIPT ALT' ;;
# select queue in file browser (xplr prints selection to stdout)
q) xplr "$prefix/playlists" | xargs -r -I ',,' sed -i "s@^queue=.*@queue=\",,\"@" $conf ;;
# select queue with fzf
fq) fd -t f . "$prefix/playlists" | fzf --height 65% --preview='echo {}; cat {}' --preview-window='bottom,65%' | xargs -r -I ',,' sed -i "s@^queue=.*@queue=\",,\"@" $conf; ytmp -kr && setsid -f ytmp -r >/dev/null 2>&1; ytmp -kd && setsid -f ytmp -d >/dev/null 2>&1; ;;
# set queue with $2
sq) sed -i "s@^queue=.*@queue=\"$2\"@" $conf; ytmp -kr && setsid -f ytmp -r >/dev/null 2>&1; ytmp -kd && setsid -f ytmp -d >/dev/null 2>&1; ;;
# change queue to $prefix/queue
oq) sed -i "s@^queue=.*@queue=\"$prefix/queue\"@" $conf; ytmp -kr && setsid -f ytmp -r >/dev/null 2>&1; ytmp -kd && setsid -f ytmp -d >/dev/null 2>&1; ;;
# comment queue var
cq) sed -i "s@^queue=.*@#&@" $conf ;;
# print queue file path
pq) grep -x 'queue=.*' "$conf" ;;
lq) lf "$prefix/playlists" ;;
# remove all *** in the queue
ra) sed -i '/\*\*\*$/s/\*\*\*//g' "$queue" ;;
pv) grep '^vol=.*' "$run_on_next" ;;
pvc) sed -n 's/^vol=//p' "$run_on_next" ;;
l) sed -i "s;^vol=.*$;vol=${2};" "$run_on_next" ;;
oc) nvim "$conf" ;;
or) nvim "$run_on_next" ;;
# set vol var in $run_on_next
sv) [ -z "$2" ] && printf '' | dmenu | xargs -r -I ',,' sed -i 's@^vol=.*$@vol=,,@' "$run_on_next" || sed -i "s/^vol=.*$/vol=${2}/" "$run_on_next" ;;
# set mpv volume to $var in $run_on_next
ev) mpv_socket_commands s volume $( grep '^vol=.*' "$run_on_next" | sed 's/vol=//' ) st /tmp/mpvsocketytmp ;;
cv) [ -z "$2" ] && printf '' | dmenu | xargs -r -I ',,' mpv_socket_commands s volume ',,' st /tmp/mpvsocketytmp || mpv_socket_commands s volume "$2" st /tmp/mpvsocketytmp ;;
v) mpv_socket_commands s volume $2 st /tmp/mpvsocketytmp ;;
rv) mpv_socket_commands s volume 100 st /tmp/mpvsocketytmp ;;
# a dmenu wrapper
dm) 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 ;;
# queue up songs that fuzzy match args to play one after another; ex ytmpsuite qs '<search1>' '<search2>' '<search3>'
qs) mpv_socket_commands s loop false st /tmp/mpvsocketytmp >/dev/null 2>&1; shift 1; printf '%s\n' "$@" | while read p; do ( while (ytmp -n); do ytmp P $p; break; done; ) done ;;
# queue up entries to play one after another; ex: ytmpsuite qn 5 p+8 l-2
qn) mpv_socket_commands s loop false st /tmp/mpvsocketytmp >/dev/null 2>&1; shift 1; printf '%s\n' "$@" | while read p; do ( while (ytmp -n); do ytmp e $p; break; done; ) done ;;
# combination of both of the above
qsn)
mpv_socket_commands s loop false st /tmp/mpvsocketytmp >/dev/null 2>&1; shift 1
printf '%s\n' "$@" | while read p; do ( while (ytmp -n); do if (printf $p | grep -Eq '^.((\+|-)[0-9]*)?$|^[0-9]*$'); then ytmp e $p; else ytmp P $p; fi; break; done; ) done
;;
# search searches contained in (newline separated) $2 and put results in $prefix/playlists/"$3"
sa) [ -n "$3" ] && xargs -d '\n' -a "$2" -I ,, yt-dlp --print id --print title ",," | paste -s -d ' \n' >> $prefix/playlists/"$3" ;;
# make a queue file from playlist url and put it in $prefix/playlists/"$3"
ap) [ -n "$3" ] && yt-dlp --print id --print title "$2" | paste -s -d ' \n' >> $prefix/playlists/"$3" ;;
# select songs from playlists to add to $prefix/playlists/"$3"; $3=filename
a) pipe-viewer -e="*ID*" --results=50 --no-interactive --no-use-colors --custom-playlist-layout='*ID* *TITLE*' --custom-layout='*ID* *TITLE*' "$2" | sed 1,3d | fzf -m --preview="echo {} | cut -d' ' -f1 | xargs -I ,, pipe-viewer --results=1 -e='*ID*' --no-interactive --no-use-colors --custom-layout='Length: *TIME* \nUploader: *AUTHOR* \nDate: *PUBLISHED* \nURL: *URL*\n--------------\nDescription:\n--------------\n*DESCRIPTION*\nDESCEND\n--------------' ,," >> $prefix/playlists/"$3" ;;
# search for playlists and make a queue file with the selected one at $prefix/playlists/"$3"; $3=filename
# add playlists with yt-dlp -- pipe-viewer (used by 'sp' option) doesn't return all videos in a playlist
# and yt-dlp is slow so choose your trade off
spy) [ -n "$3" ] && query="$2" && pipe-viewer --results=50 --no-interactive -sp --custom-playlist-layout='*VIDEOS*VIDS *TITLE* *URL*' "$query" | fzf -m --bind="ctrl-x:execute(echo {} | awk -F ' ' '{print \$NF}' | xargs -r -0 -I ',,' ytmpsuite a ,, $3),ctrl-o:execute-silent(echo {} | awk -F ' ' '{print \$NF}' | xargs -0 -I ',,' $BROWSER ,, )" \
--preview='echo {} | awk "{print $NF}" | xargs -0 -I ",," pipe-viewer -e="*ID*" --no-use-colors --results=50 --custom-layout="*AUTHOR* *TIME* *TITLE*" --no-interactive ",,"' | awk '{print $NF}' | xargs -r -0 -I ',,' yt-dlp --print id --print title ',,' | paste -s -d ' \n' >> $prefix/playlists/"$3"
;;
sp) [ -n "$3" ] && query="$2" && pipe-viewer -e="*ID*" --results=50 --no-interactive --no-use-colors -sp --custom-playlist-layout='*VIDEOS*VIDS *TITLE* *URL*' "$query" | grep 'youtube\.com' | fzf -m \
--bind="ctrl-x:execute(echo {} | awk -F ' ' '{print \$NF}' | xargs -0 -I ',,' ytmpsuite a ,, $3),ctrl-o:execute-silent(echo {} | awk -F ' ' '{print \$NF}' | xargs -0 -I ',,' $BROWSER ,, )" \
--preview='echo {} | awk "{print $NF}" | xargs -0 -I ",," pipe-viewer -e="*ID*" --no-use-colors --results=50 --custom-layout="*AUTHOR* *TIME* *TITLE*" --no-interactive ",," | sed 1d' | awk '{print $NF}' | \
xargs -r -I ',,' pipe-viewer -e='*ID*' --no-use-colors --results=50 --custom-layout='*ID* *TITLE*' --no-interactive ',,' | sed 1d >> $prefix/playlists/"$3" ;;
# search for playlists and add the very first result.
# use case: add individual songs of albums instead of a long video containing all songs;
# pipe-viewer is used instead of yt-dlp because it's quicker and only
# rarely would albums track count exceed the max videos pipe-viewer can return
# args: <file-containing-searches-sep-by-newline> <path-to-dump-the-results> [< ><optional-string-to-add-to-the-end-of-all-search>]
# for the last optional arg - put a space before the string like: ' full album'
pvpl)
[ -z "$3" ] && exit
cat "$2" | while read -r search; do
# if line starts with #, append it and continue
echo "$search" | grep -q '^#' && echo "$search" >> "$3" && continue
[ -z "$search" ] && continue
pipe-viewer --no-use-colors --no-interactive --results=1 -e='*URL*' --custom-playlist-layout='*URL*' -sp "${search}${4}" | sed -n 2p | xargs -d '\n' -I ',,' pipe-viewer --results=50 --no-use-colors --no-interactive -e='*ID* *TITLE*' --custom-layout='*ID* *TITLE*' ",," | sed 1d >> "$3"
done
;;
# scrape sites like
# rym - https://rateyourmusic.com/charts/top/album/all-time/g:rock/
# aoty - https://www.albumoftheyear.org/genre/7-rock/all/
# discogs - https://www.discogs.com/search/?genre_exact=Rock
# this will print 'album - artist' and a comment above the entry like
# ## artist ## album
# workflow: put output in a file and send it to 'pvpl'
# which will create a playlist of all the albums and leave the comments
scrape)
shift
[ -z "$2" ] && echo '<rym|dsg|aoty> <file.html>' && return
case "$1" in
rym) sed -En 's/.*(data-artists=|data-albums=)"(.*)"/ \2 /gp' "$2" | paste -s -d '-\n' | sed 's/^ //' ;;
aoty) sed -Ene 's/.*alt="(.*)" data-src.*/\1/p' "$2" | sed '$d' ;;
dsg) sed -Ene 's/.*alt="(.*)".*/\1/p' "$2" | grep -- ' - ' ;;
esac | sed -e 's/"//g' -e p | sed -e 's/ / /g' -e 's/ - / ## /; s/^/## /; n'
;;
esac