~q3cpma/mus

ref: e99afe099fd0b6cf6a4cce58902c9612ecd9fca9 mus/mus_daemon -rwxr-xr-x 4.4 KiB
e99afe09q3cpma Finish build.sh and README, move TODO to root 1 year, 1 month 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/sh
# Dependencies: ed, flock
# Portability:  GNU, *BSD, MacOS
# +-------------+-----+---------+--------+--------------+---------+-------+---------+-------+-----+------+-------+
# | cmd\OS      | GNU | OpenBSD | NetBSD | DragonflyBSD | FreeBSD | MacOS | Illumos | HP-UX | AIX | IRIX | Tru64 |
# +-------------+-----+---------+--------+--------------+---------+-------+---------+-------+-----+------+-------+
# | flock       | o   | i       | o      | o            | o       | i     |         |       |     |      |       |
# +-------------+-----+---------+--------+--------------+---------+-------+---------+-------+-----+------+-------+
# | xargs -0    | o   | o       | o      | o            | o       | o     | o       |       |     |      |       |
# +-------------+-----+---------+--------+--------------+---------+-------+---------+-------+-----+------+-------+
# o: supported, i: external package exists, s: different syntax needed, X: different behaviour
set -eu -o noglob
rpath_bin=$(readlink -f -- "$(dirname -- "$0")")
rpath_share=$(readlink -f -- "$(dirname -- "$0")")
rpath_cbin=$(readlink -f -- "$(dirname -- "$0")/mus_player")
. "$rpath_share"/mus_util.sh


plread()
{
	flock -- "$1" ed -s -- "$1" <<-EOF
		1p
		d
		w
		q
EOF
}

exec_status_cmd()
{
	set +e
	[ "$status_cmd" ] && echop "status $1" | sh -c "$status_cmd"
	set -e
}

usage()
{
	cat <<EOF | text_format
**NAME**
    $(basename -- "$0") - Album playlist based music player (daemon)

**SYNOPSIS**
    $(basename -- "$0") [**-h**] [**-l** __FILE__] [**-o** __PLAYER_OPTS__] [**-s** __COMMAND__] [**-u** __SOCKET__]

**DESCRIPTION**
    Consume a newline separated list of album paths (a playlist). For each
    album path, search recursively for .flac and .ogg files and play them
    one by one with **mus_player**, whose standard error is redirected to
    $log.

    These albums paths can be specified relatively to \$__MUS_MUSIC_DIR__.

    The playlist is read and written via **flock**(1) so it shouldn't be
    modified manually, only via **mus_client**.

**OPTIONS**
    **-h**
        Print this notice and exit.

    **-l** __FILE__
        Set the playlist path. Override the \$__MUS_PLAYLIST__ environment
        variable.

    **-o** __PLAYER_OPTS__
        Additional options to pass to mus_player.

    **-s** __COMMAND__
        Use __COMMAND__ as **mus_player**'s status command (**-s** option).

    **-u** __SOCKET__
        Set the IPC UNIX domain socket path. Override the \$__MUS_SOCKET__
        environnement variable.


**ENVIRONMENT**
    __MUS_PLAYLIST__
        Album playlist path. Defaults to
        \${XDG_CONFIG_HOME:-\$HOME/.config}/mus/playlist.

    __MUS_SOCKET__
        IPC UNIX domain socket path. Defaults to /tmp/mus.sock.

    __MUS_MUSIC_DIR__
        Music directory. Defaults to \$HOME/Music.

EOF
	exit $1
}

pidfile=/tmp/mus_daemon.pid
poll_duration=0.1

status_cmd=
udsock=/tmp/mus.sock
music_dir=${MUS_MUSIC_DIR:-$HOME/Music}
playlist=${MUS_PLAYLIST:-${XDG_CONFIG_HOME:-$HOME/.config}/mus/playlist}
player_opts=
log=/tmp/mus_player.log

while getopts "hl:o:s:u:" OPT
do
	case "$OPT" in
		h)
			usage 0
			;;
		l)
			playlist=$OPTARG
			;;
		o)
			player_opts=$OPTARG
			;;
		s)
			status_cmd=$OPTARG
			;;
		u)
			udsock=$OPTARG
			;;
		\?)
			usage 1
			;;
	esac
done
shift $((OPTIND - 1))
[ $# -ne 0 ] && usage 1

echop $$ >"$pidfile"

trap 'exit' INT TERM HUP QUIT
trap 'rm -f -- "$pidfile"' EXIT

# Use $@ to store the mus_player command line
set -- "$rpath_cbin"/mus_player -i "$udsock" $player_opts
[ "$status_cmd" ] && set -- "$@" -s "$status_cmd"
set -- "$@" --

# Produce a -name *.ext1 -o -name *.ext2 ... list for find according to the
# formats supported by mus_player
find_opts=$("$rpath_cbin"/mus_player -v | sed -n '
	/FLAC/       {s#.*#-name *.flac#; H}
	/Ogg Vorbis/ {s#.*#-name *.ogg#;  H}
	/Ogg Opus/   {s#.*#-name *.opus#; H}
	${g; s#^\n##; s#\n# -o #g; p}')

mkdir -p -- "$(dirname -- "$playlist")"
# Wait for the playlist to be created
if [ ! -e "$playlist" ]
then
	exec_status_cmd "no_playlist"
	poll_test $poll_duration -f "$playlist"
fi

[ -d "$music_dir" ] && cd -- "$music_dir"
while true
do
	# Wait for the playlist to be non-empty
	if [ ! -s "$playlist" ]
	then
		exec_status_cmd "empty_playlist"
		poll_test $poll_duration -s "$playlist"
	fi

	album=$(plread "$playlist")

	[ ! -f "$album" ] && [ ! -d "$album" ] &&
		{ echop "$album: file not found"; continue;}

	find -- "$album" -type f $find_opts | sort -n | xargsnl "$@" 2>>"$log"
done