Skip to content

Commit adadcfe

Browse files
committed
Initial project version.
1 parent eaeb115 commit adadcfe

File tree

1 file changed

+229
-0
lines changed

1 file changed

+229
-0
lines changed

query-handbrake-log.sh

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
#!/bin/bash
2+
#
3+
# query-handbrake-log.sh
4+
#
5+
# Copyright (c) 2014 Don Melton
6+
#
7+
8+
about() {
9+
cat <<EOF
10+
$program 1.0 of November 21, 2014
11+
Copyright (c) 2014 Don Melton
12+
EOF
13+
exit 0
14+
}
15+
16+
usage() {
17+
cat <<EOF
18+
Report information from HandBrake-generated \`.log\` files.
19+
20+
Usage: $program INFO [OPTION]... [FILE|DIRECTORY]...
21+
22+
Information types:
23+
time time spent during transcoding
24+
(sorted from short to long)
25+
speed speed of transcoding in frames per second
26+
(sorted from fast to slow)
27+
bitrate video bitrate of transcoded output
28+
(sorted from low to high)
29+
ratefactor average P-frame quantizer for transcoding
30+
(sorted from low to high)
31+
32+
Options:
33+
--reverse reverse direction of sort
34+
--unsorted don't sort
35+
36+
--help display this help and exit
37+
--version output version information and exit
38+
39+
Results are written to standard output.
40+
EOF
41+
exit 0
42+
}
43+
44+
syntax_error() {
45+
echo "$program: $1" >&2
46+
echo "Try \`$program --help\` for more information." >&2
47+
exit 1
48+
}
49+
50+
die() {
51+
echo "$program: $1" >&2
52+
exit ${2:-1}
53+
}
54+
55+
readonly program="$(basename "$0")"
56+
57+
case $1 in
58+
--help)
59+
usage
60+
;;
61+
--version)
62+
about
63+
;;
64+
esac
65+
66+
if (($# < 1)); then
67+
syntax_error 'too few arguments'
68+
fi
69+
70+
readonly info="$1"
71+
72+
case $info in
73+
time|bitrate|ratefactor)
74+
sort_options='--numeric-sort'
75+
;;
76+
speed)
77+
sort_options='--numeric-sort --reverse'
78+
;;
79+
*)
80+
syntax_error "unrecognized information type: $1"
81+
;;
82+
esac
83+
shift
84+
85+
while [ "$1" ]; do
86+
case $1 in
87+
--reverse)
88+
case $info in
89+
time|bitrate|ratefactor)
90+
sort_options='--numeric-sort --reverse'
91+
;;
92+
speed)
93+
sort_options='--numeric-sort'
94+
;;
95+
esac
96+
;;
97+
--unsorted)
98+
sort_options=''
99+
;;
100+
-*)
101+
syntax_error "unrecognized option: $1"
102+
;;
103+
*)
104+
break
105+
;;
106+
esac
107+
shift
108+
done
109+
110+
if (($# < 1)); then
111+
syntax_error 'too few arguments'
112+
fi
113+
114+
logs=()
115+
directory_count='0'
116+
last_directory=''
117+
118+
while [ "$1" ]; do
119+
120+
if [ ! -e "$1" ]; then
121+
die "input not found: $1"
122+
fi
123+
124+
if [ -d "$1" ]; then
125+
directory_logs=("$1"/*.log)
126+
directory_count="$((directory_count + 1))"
127+
last_directory="$(cd "$1" 2>/dev/null && pwd)"
128+
129+
if ((${#directory_logs[*]} == 1)) && [ "$(basename "${directory_logs[0]}")" == '*.log' ]; then
130+
die "\`.log\` files not found: $1"
131+
else
132+
logs=("${logs[@]}" "${directory_logs[@]}")
133+
fi
134+
else
135+
file_directory="$(cd "$(dirname "$1")" 2>/dev/null && pwd)"
136+
137+
if [ "$last_directory" != "$file_directory" ]; then
138+
directory_count="$((directory_count + 1))"
139+
last_directory="$file_directory"
140+
fi
141+
142+
logs=("${logs[@]}" "$1")
143+
fi
144+
145+
shift
146+
done
147+
148+
for item in "${logs[@]}"; do
149+
video_name="$(basename "$item" | sed 's/\.log$//')"
150+
151+
if (($directory_count > 1)); then
152+
video_name="$video_name ($(dirname "$item"))"
153+
fi
154+
155+
case $info in
156+
time|speed)
157+
fps="$(grep 'average encoding speed' "$item" | sed 's/^.* \([0-9.]*\) fps$/\1/')"
158+
159+
if [ ! "$fps" ]; then
160+
161+
if [ "$info" == 'time' ]; then
162+
echo "00:00:00 $video_name"
163+
else
164+
echo "00.000000 fps $video_name"
165+
fi
166+
167+
continue
168+
fi
169+
170+
if [ "$(echo "$fps" | wc -l | sed 's/^[^0-9]*//')" == '2' ]; then
171+
172+
# Calculate single `fps` result from two-pass `.log` file.
173+
#
174+
pass_1_fps="$(echo "$fps" | sed -n 1p)"
175+
pass_2_fps="$(echo "$fps" | sed -n 2p)"
176+
177+
fps="$(ruby -e 'printf "%.6f", (1 / ((1 / '$pass_1_fps') + (1 / '$pass_2_fps')))')"
178+
fi
179+
180+
if [ "$info" == 'time' ]; then
181+
duration="$(grep '+ duration: ' "$item" | sed 's/^.* \([0-9:]*\)$/\1/')"
182+
duration=($(echo " $duration " | sed 's/:/ /g;s/ 0/ /g'))
183+
duration="$(((duration[0] * 60 * 60) + (duration[1] * 60) + duration[2]))"
184+
185+
rate="$(grep '+ frame rate: ' "$item")"
186+
187+
if [ ! "$rate" ]; then
188+
echo "00:00:00 $video_name"
189+
continue
190+
fi
191+
192+
rate="$(echo "$rate" | sed '$!d;s/^.*+ frame rate: //;s/^.* -> constant //;s/ fps -> .*$//;s/ fps$//')"
193+
194+
duration="$(ruby -e 'printf "%.0f", (('$duration' * '$rate') / '$fps')')"
195+
196+
ruby -e 'printf "%02d:%02d:%02d '"$video_name"'\n", '$((duration / (60 * 60)))', '$(((duration / 60) % 60))', '$((duration % 60))
197+
else
198+
echo "$fps fps $video_name"
199+
fi
200+
;;
201+
bitrate)
202+
kbps="$(grep 'mux: track 0' "$item")"
203+
204+
if [ ! "$kbps" ]; then
205+
echo "0000.00 kbps $video_name"
206+
continue
207+
fi
208+
209+
echo "$(echo "$kbps" | sed 's/^.* \([0-9.]* kbps\).*$/\1/') $video_name"
210+
;;
211+
ratefactor)
212+
qp="$(grep 'x26[45] \[info\]: frame P:' "$item")"
213+
214+
if [ ! "$qp" ]; then
215+
echo "00.00 $video_name"
216+
continue
217+
fi
218+
219+
echo "$(echo "$qp" | sed '$!d;s/^.* QP://;s/ *size:.*$//') $video_name"
220+
;;
221+
esac
222+
223+
done |
224+
225+
if [ "$sort_options" ]; then
226+
sort $sort_options
227+
else
228+
cat
229+
fi

0 commit comments

Comments
 (0)