dotfiles

My collection of dotfiles
git clone git://git.noxz.tech/dotfiles
Log | Files | Refs

mpvc (6701B)


      1 #!/bin/sh
      2 
      3 mpvdsock="/tmp/mpvd.sock"
      4 cmd_socat="$(command -v socat) - '$mpvdsock'"
      5 cmd_jq="$(command -v jq)"
      6 cmd_exif="$(command -v exiftool)"
      7 
      8 print_help() {
      9 	echo "Usage: mpvc ACTION [ARGS]\n"
     10 	echo "ACTIONS:"
     11 	echo " append PATH      append file to playlist."
     12 	echo " goto INDEX       goto track index of playlist."
     13 	echo " help             print this help message."
     14 	echo " list             print playlist."
     15 	echo " load PATH        load file or directory, and override playlist."
     16 	echo " lower            lower volume 10 units"
     17 	echo " mute             toggle mute"
     18 	echo " next             go to next track."
     19 	echo " plmenu MODE      launch playlist menu."
     20 	echo " prev             go to previous track."
     21 	echo " raise            raise volume 10 units"
     22 	echo " seek (-)N        seek (-)n seconds"
     23 	echo " stop             stop playback"
     24 	echo " toggle           toogle play and pause."
     25 	echo " "
     26 	echo "EXTRA:"
     27 	echo " ytdl-format FMT  set ytdl-format"
     28 	echo " "
     29 	echo "ALSA:"
     30 	echo " alower           alsa lower 5%"
     31 	echo " amute            alsa mute"
     32 	echo " araise           alsa raise 5%"
     33 }
     34 
     35 send_command() {
     36 	local input=""
     37 	for var in "$@"; do
     38 		[ "$input" != "" ] && input="$input, "
     39 	input="$input\"$var\""
     40 	done
     41 	printf '{ "command": [%s] }\n' "$input" | $cmd_socat
     42 }
     43 
     44 get_path() {
     45 	local path="$(readlink -f "$@")"
     46 	if [ -f "$path" ] || [ -d "$path" ]; then
     47 		echo "$path"
     48 	else
     49 		echo "$@"
     50 	fi
     51 }
     52 
     53 notify_vol() {
     54 	case $1 in
     55 	master)
     56 		local level="$(amixer sget Master | awk -F"[][]" '/dB/ { print ($2+0) }')"
     57 	local muted="$(amixer sget Master | awk -F"[][]" '/dB/ { print ($6) }' | sed 's/off/true/')"
     58 		;;
     59 	mpv)
     60 		local level="$(send_command "get_property" "volume" | $cmd_jq -rM '.data')"
     61 		local muted="$(send_command "get_property" "mute" | $cmd_jq -rM '.data')"
     62 		;;
     63 	*) return;;
     64 	esac
     65 
     66 	echo $muted > /tmp/tttt
     67 
     68 	local marks="$((($level + 5) / 10))"
     69 	[ "$marks" -gt 10 ] && marks=10
     70 
     71 	local output="$1"
     72 	if [ "$muted" = "true" ]; then
     73 		local output="$output (muted)"
     74 	fi
     75 	local output="$output: [$([ "$marks" -gt 0 ] && printf "%-$((marks))s" "+" | sed 's/\ /+/g')"
     76 	local output="$output$([ "$marks" -lt 10 ] && printf "%-$((10-marks))s" " ")]"
     77 	local output="$output$(printf " %3d" "$level")%"
     78 	ztatus-notify "$output"
     79 }
     80 
     81 die() {
     82 	printf "Error: %s\n" "$@"
     83 	exit 1
     84 }
     85 
     86 # check if prerequisites exist
     87 [ -z "$cmd_socat" ] && die "could not find 'socat'"
     88 [ -z "$cmd_jq" ] && die "could not find 'jq'"
     89 [ -z "$cmd_exif" ] && die "could not find 'exiftool'"
     90 
     91 # check if daemonization should apply
     92 if [ "${0##*/}" = "mpvd" ]; then
     93 	if pidof -x "$(basename -- "$0")" -o $$ >/dev/null; then
     94 		die "Another instance of mpvd is already runnig..."
     95 	fi
     96 	[ -S "$mpvdsock" ] && rm "$mpvdsock"
     97 	while true; do
     98 		mpv --idle=yes \
     99 			--input-ipc-server="$mpvdsock" \
    100 		--ytdl-format=best \
    101 		--load-scripts=yes \
    102 		2>&1 >/tmp/mpvd.log
    103 	done
    104 	exit 0
    105 fi
    106 
    107 # check if socket exists
    108 [ ! -S "$mpvdsock" ] && die "socket: '$mpvdsock' is missing"
    109 
    110 # print help if no argument was passed
    111 if [ $# -lt 1 ]; then
    112 	print_help
    113 	exit 0
    114 fi
    115 
    116 show_playlist() {
    117 	cmd="fzf"
    118 	[ "$1" = "x" ] && cmd="dmenu_vtc -l 20 -p playlist:"
    119 	script="$(realpath -s $0)"
    120 	list="$($script list)"
    121 	[ "$list" = "" ] && exit 1
    122 	entry="$(
    123 		echo "$list"                                                        \
    124 		| sed -e  's/^[ \t]*/  /' -e 's/^[^\w]*current[^\t]*\t/> /'         \
    125 		| awk '{printf "%-5s %s\n", (NR  ": "), $0}'                        \
    126 		| $cmd                                                              \
    127 	)"
    128 	[ "$entry" != "" ] && $script goto "$((${entry%%:*}-1))" || exit 1
    129 }
    130 
    131 exif_extract() {
    132 	echo "$1" | grep ^"$2" | cut -d':' -f 2- | sed 's/^[ \t]*//'
    133 }
    134 
    135 exif_wrapper() {
    136 	exif_data="$($cmd_exif -directory -filename -artist -title -duration "$@")"
    137 	exif_directory="$(exif_extract "$exif_data" "Directory")"
    138 	exif_filename="$(exif_extract "$exif_data" "File Name")"
    139 	exif_artist="$(exif_extract "$exif_data" "Artist")"
    140 	exif_title="$(exif_extract "$exif_data" "Title")"
    141 	exif_duration="$(exif_extract "$exif_data" "Duration")"
    142 	exif_artisttitle="$exif_filename"
    143 
    144 	if [ "$exif_artist" != "" ] && [ "$exif_title" != "" ]; then
    145 		exif_artisttitle="$exif_artist - $exif_title"
    146 	fi
    147 
    148 	exif_directory="$(get_path "$exif_directory")"
    149 
    150 	# make sure duration is in the format of 'hh:mm:ss' then to seconds (awk)
    151 	exif_duration="$(echo "$exif_duration" | cut -d' ' -f 1)"
    152 	exif_duration="$(                                                       \
    153 		printf '0:0:%s' "$exif_duration"                                    \
    154 		| rev | cut -d':' -f -3 | rev                                       \
    155 		| awk -F':' '{ print ($1 * 3600) + ($2 * 60) + $3 }'                \
    156 	)"
    157 
    158 	echo "$(printf '#EXTINF:%s,%s\n%s/%s\n'                                 \
    159 		"$exif_duration"                                                    \
    160 		"$exif_artisttitle"                                                 \
    161 		"$exif_directory"                                                   \
    162 		"$exif_filename"                                                    \
    163 	)"
    164 }
    165 
    166 case "$1" in
    167 	# actions
    168 	load)
    169 		shift;
    170 		playlist="$(get_path "$@")"
    171 		if [ -d "$playlist" ]; then
    172 			playlist_tmp="$(mktemp /tmp/pls.mpvc.XXXXXXXXXX)"
    173 			echo '#EXTM3U' > "$playlist_tmp"
    174 			find "$playlist" -maxdepth 2 -type f | sort -n | while read -r f; do
    175 				case "$f" in
    176 				*.flac | *.mp3 | *.ogg)
    177 					exif_wrapper "$f" >> "$playlist_tmp" ;;
    178 				*) continue ;;
    179 				esac
    180 			done
    181 			playlist="$playlist_tmp"
    182 		fi
    183 		send_command "loadfile" "$playlist"
    184 		[ "$playlist_tmp" != "" ] && (sleep 10 && rm "$playlist_tmp") &
    185 		;;
    186 	append)
    187 		shift; send_command "loadfile" "$(get_path "$@")" "append" ;;
    188 	stop)
    189 		send_command "stop" ;;
    190 	toggle)
    191 		send_command "cycle" "pause" ;;
    192 	prev)
    193 		send_command "playlist-prev" ;;
    194 	next)
    195 		send_command "playlist-next" ;;
    196 	goto)
    197 		shift; send_command "set_property" "playlist-pos" "$@" ;;
    198 	list)
    199 		send_command "get_property" "playlist" \
    200 		| $cmd_jq -rM '.data[]|(
    201 			if .current then
    202 				"\\e[1;37mcurrent\\e[0m\\t"
    203 			else
    204 				"\\t" end
    205 		)+(.title//.filename)' \
    206 		| sed -e "s/\\\\t/\\t/g" -e "s/\\\\e/`printf "\033"`/g";;
    207 	plmenu) shift; show_playlist "$@" ;;
    208 	seek)
    209 		shift; send_command "seek" "$@" ;;
    210 	mute)
    211 		send_command "cycle" "mute"; notify_vol mpv;;
    212 	raise)
    213 		send_command "add" "volume" "10"; notify_vol mpv;;
    214 	lower)
    215 		send_command "add" "volume" "-10"; notify_vol mpv;;
    216 
    217 	# extra
    218 	ytdl-format)
    219 		shift; send_command "set" "ytdl-format" "$@" ;;
    220 
    221 	# alsa
    222 	amute)
    223 		amixer set Master toggle; notify_vol master;;
    224 	araise)
    225 		amixer -q sset Master 5%+; notify_vol master;;
    226 	alower)
    227 		amixer -q sset Master 5%-; notify_vol master;;
    228 
    229 	# default behaviour
    230 	help)
    231 		print_help ;;
    232 	*)
    233 		echo "Unknown option: $*"; print_help ;;
    234 esac