~hnaguski/aart

ref: 4af0ce8040fe0626ca6f82719babe70afe9bdca0 aart/aart -rwxr-xr-x 2.8 KiB
4af0ce80Henry Naguski add Makefile and config.mk. And properly support the XDG_CACHE_DIR for storing the noart.png file 2 years ago
                                                                                
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
#!/bin/sh

music_dir=$(xdg-user-dir MUSIC)

AART_TEMP=${AART_TEMP:-"/tmp/aart"}
AART_NOART=${XDG_CACHE_HOME:-"$HOME/.cache"}/aart/noart.png
AART_VIEWER=${AART_VIEWER:-"sxiv -b"}

extract_art() {
	current_path=$music_dir/$1

	# use ffmpeg to extract album art embedded in music files. copies the same
	# codec to (hopefully) not modify the file at all. Not sure if I have the
	# options for it set correctly, especially the format being image2 for
	# everything.
	ffmpeg -loglevel error -y -i "$current_path" -map v? -c copy -f image2 "$AART_TEMP" || return 1

	art="$AART_TEMP"
	printf "found embedded art\n"
	return 0
}

find_folder_art() {
	for art in "$album_dir"/folder.*; do
		[ -f "$art" ] || continue
		printf "found folder art\n"
		return 0
	done

	printf "no folder.*\n"
	return 1
}

find_cover_art() {
	for art in "$album_dir"/cover.*; do
		[ -f "$art" ] || continue
		printf "found cover art\n"
		return 0
	done

	printf "no cover.*\n"
	return 1
}

copy_art() {
	# get diretory of currently playing song
	album_dir="$music_dir/$1"
	album_dir=${album_dir:-}
	album_dir=${album_dir%%"${album_dir##*[!/]}"}
	[ "${album_dir##*/*}" ] && album_dir=.
	album_dir=${album_dir%/*}
	album_dir=${album_dir%%"${album_dir##*[!/]}"}

	find_folder_art || find_cover_art || return 1

	printf "found external art\n"
	return 0
}

no_art() {
	printf "no art found! falling back to default\n"
	art="$AART_NOART"
}

set_art() {
	# attempt to get the album art in various ways
	printf "finding art for %s\n" "$(mpc current)"
	extract_art "$1" || copy_art "$1" || no_art

	# copy the art to the file that's open in the image viewer
	cp -f "$art" "$AART_TEMP"

	# make output a bit easier to read
	printf "\n"
}

check_pid() {
	if [ ! -e /proc/"$viewer_pid" ]; then
		# clean up temp file
		rm "$AART_TEMP"

		printf "viewer missing! exiting\n"
		exit 1
	fi
}

first_start() {
	# check if mpd is running
	pgrep mpd >/dev/null || exit 1

	# check status of mpd, if it's stopped then wait for mpd to start playing
	# a song. Maybe only check for playing, I leave mpd paused quite often
	mpc status | grep -o "playing\|paused" > /dev/null || mpc -q current --wait

	# set the art
	set_art "$(mpc -q current -f %file%)"

	# open image viewer on the art and store the pid
	$AART_VIEWER "$AART_TEMP" & viewer_pid=$!
}

close_script() {
	# clean up temp file
	rm "$AART_TEMP"

	# kill the viewer
	kill $viewer_pid

	# remove weird artifact when closing
	printf "\n"
	exit 0
}

first_start

trap close_script INT

while true;
do
	old_song="$(mpc current -f %file%)"

	# wait for a player event, if mpd closes then exit
	mpc -q idle player > /dev/null || close_script

	# make sure viewer is still open
	check_pid

	# only change the art if the song changes
	new_song="$(mpc current -f %file%)"
	[ "$old_song" != "$new_song" ] && set_art "$new_song"
done