Updated to use mpv instead of mplayer.
[utils.git] / planime
1 #!/bin/bash
2
3 isnum() {
4     grep -xq '[0-9]\+' <<<"$1"
5 }
6
7 scorefile() {
8     if [ "${1##*.}" = mkv ]; then
9         echo 10
10     elif [ "${1##*.}" = ogm ]; then
11         echo 5
12     else
13         echo 0
14     fi
15 }
16
17 findbase() {
18     if [ -r aliases ]; then
19         while read alias rest; do
20             if [ "$alias" = "$1" ]; then
21                 echo "$rest"
22                 return
23             fi
24         done <aliases
25     fi
26     echo "$1"
27 }
28
29 findfile() {
30     if [ -n "$debug" ]; then echo "finding base='$1', ep='$2', qual='$3'" >&2; fi
31     local base file tail eq eqt m matches max score
32     matches=()
33     base="$(findbase "$1")"
34     for file in "$base"*; do
35         tail="${file#"$base"}"
36         eq="${tail%.*}"
37         m=n
38         if [ "${eq%% *}" -eq "$2" ] 2>/dev/null; then
39             if [[ "$eq" == *\ * ]]; then
40                 eqt="${eq#* }"
41             else
42                 eqt=
43             fi
44             m=y
45         elif [ "${eq:0:${#2}}" = "$2" ]; then
46             eqt="${eq:${#2}}"
47             if [ "${eqt:0:1}" = " " -o -z "$eqt" ]; then
48                 eqt="${eqt# }"
49                 m=y
50             fi
51         fi
52         if [ "$m" = y ]; then
53             if [ "$eqt" = "$3" -o "$eqt" = "($3)" -o "${eqt:0:2}" = "- " ]; then
54                 matches=("${matches[@]}" "$file")
55             fi
56         fi
57     done
58     if [ ${#matches[@]} -lt 1 ]; then return 1; fi
59     max=
60     for m in "${matches[@]}"; do
61         score="$(scorefile "$m")"
62         if [ -n "$debug" ]; then echo "found \`$m': score $score" >&2; fi
63         if [ -z "$max" ] || [ "$score" -gt "$max" ]; then
64             max="$score"
65             file="$m"
66         fi
67     done
68     if [ -n "$debug" ]; then echo "using \`$file'" >&2; fi
69     echo "$file"
70     return 0
71 }
72
73 origargs=("$0" "$@")
74 cmdline=(mpv -fs)
75 debug=
76 unset pretend printfile
77
78 while [ "${1:0:1}" = - ]; do
79     a="$1"
80     shift
81     case "$a" in
82         -h)
83             echo "usage: planime [-fdhtC] [-A PLAYER-ARGS... ;] [-s PAR VAL] [--] [NAME-QUAL] [EP|.] [TYPE-QUAL]" >&2
84             exit 0
85             ;;
86         -d)
87             debug=y
88             ;;
89         -t)
90             cmdline=("${cmdline[@]}" -ao 'alsa:device=[hw:3,7]')
91             DISPLAY=:1
92             chwp=y
93             ;;
94         -C)
95             pretend=y
96             ;;
97         -A)
98             while :; do
99                 if [ $# -lt 1 ]; then
100                     echo "planime: unterminated argument list" >&2
101                     exit 1
102                 fi
103                 a="$1"
104                 shift
105                 if [ "$a" = \; ]; then
106                     break;
107                 fi
108                 cmdline=("${cmdline[@]}" "$a")
109             done
110             ;;
111         -s)
112             savepar="$1"
113             shift
114             saveval="$1"
115             shift
116             ;;
117         -f)
118             printfile=y
119             ;;
120         -v)
121             cmdline=("${cmdline[@]}" -v)
122             ;;
123         --)
124             break
125             ;;
126         *)
127             echo "planime: unknown option \`$a'"
128             exit 1
129             ;;
130     esac
131 done
132
133 dirbase="$(basename "$(pwd)")"
134 base=.
135 nextep=n
136 file=
137 tqual=
138 if [ $# -eq 0 ]; then
139     nextep=y
140 elif [ $# -eq 1 ]; then
141     if [ -r "$1" ]; then
142         file="$1"
143     else
144         base=
145         ep="$1"
146     fi
147 elif [ $# -eq 2 ]; then
148     if findfile "$dirbase - " "$1" "$2" >/dev/null; then
149         base=""
150         ep="$1"
151         tqual="$2"
152     else
153         base="$1"
154         ep="$2"
155     fi
156 else
157     base="$1"
158     ep="$2"
159     tqual="$3"
160 fi
161 if [ "$ep" = . ]; then nextep=y; fi
162 if [ "$nextep" = y -a -r nextep ]; then
163     ep="$(<nextep)"
164     if ! isnum "$ep"; then
165         echo "planime: nextep is non-numeric" >&2
166         exit 1
167     fi
168 fi
169 if [ -z "$file" ]; then
170     if [ "$base" = . ]; then
171         if [ -r curser ]; then
172             curser="$(<curser)"
173         else
174             curser=
175         fi
176     else
177         curser="$(findbase "$base")"
178     fi
179     if [ -n "$curser" ]; then
180         file="$(findfile "$dirbase $curser - " "$ep" "$tqual")" || \
181             file="$(findfile "$curser - " "$ep" "$tqual")"
182     else
183         file="$(findfile "$dirbase - " "$ep" "$tqual")"
184     fi
185 fi
186
187 if [ -z "$file" -o ! -r "$file" ]; then
188     echo "planime: no matching file found" >&2
189     exit 1
190 fi
191
192 case "${file##*.}" in
193     ogm)
194         aid=1
195         sid=0
196         ;;
197     mkv)
198         alang=jpn
199         slang=eng
200         ;;
201 esac
202
203 ifile=".${file}.info"
204
205 if [ -n "$savepar" ]; then
206     if [ -r "$ifile" ]; then
207         egrep -v "^${savepar} " "$ifile" >"$ifile.new"
208         mv -f "$ifile.new" "$ifile"
209     fi
210     echo "$savepar $saveval" >>"$ifile"
211     exit 0
212 fi
213
214 unset delay
215
216 if [ -r "$ifile" ]; then
217     exec 3<&0
218     exec 0<"$ifile"
219     while read par arg; do
220         if [ "$par" = delay ]; then
221             cmdline=("${cmdline[@]}" -delay "$arg")
222         elif [ "$par" = aspect ]; then
223             cmdline=("${cmdline[@]}" -aspect "$arg")
224         elif [ "$par" = volmod ]; then
225             cmdline=("${cmdline[@]}" -af volume="$arg")
226         elif [ "$par" = alang ]; then
227             unset alang aid
228             alang="$arg"
229         elif [ "$par" = aid ]; then
230             unset alang aid
231             aid="$arg"
232         elif [ "$par" = slang ]; then
233             unset slang sid
234             slang="$arg"
235         elif [ "$par" = sid ]; then
236             unset slang sid
237             sid="$arg"
238         fi
239     done
240     exec 0<&3
241     exec 3<&-
242 fi
243
244 if [ -n "$alang" ]; then
245     cmdline=("${cmdline[@]}" -alang "$alang")
246 elif [ -n "$aid" ]; then
247     cmdline=("${cmdline[@]}" -aid "$((aid + 1))")
248 fi
249 if [ -n "$slang" ]; then
250     cmdline=("${cmdline[@]}" -slang "$slang")
251 elif [ -n "$sid" ]; then
252     cmdline=("${cmdline[@]}" -sid "$((sid + 1))")
253 fi
254
255 if [ -n "$pretend" ]; then
256     echo "${cmdline[@]}" "$file"
257 elif [ -n "$printfile" ]; then
258     echo "$file"
259 else
260     if [ "$chwp" = y ]; then (sleep 2; randomwp) & fi
261     "${cmdline[@]}" "$file"
262     
263     if [ "$nextep" = y ]; then
264         echo "0. Save and continue (or Space)"
265         echo "1. Continue without saving"
266         echo "2. Save and exit (or Enter)"
267         echo "3. Exit without saving (or any key)"
268         IFS= read -sn1 c
269         save=n
270         cont=n
271         case "$c" in
272             0|" ")
273                 save=y
274                 cont=y
275                 ;;
276             1)
277                 cont=y
278                 ;;
279             2|"")
280                 save=y
281                 ;;
282         esac
283         if [ "$save" = y ]; then
284             let ep++
285             echo "$ep" >nextep
286         fi
287         if [ "$cont" = y ]; then
288             exec "${origargs[@]}"
289         else
290             echo "nextep is $ep"
291         fi
292     fi
293 fi