-
Notifications
You must be signed in to change notification settings - Fork 0
/
syncotater.sh
executable file
·272 lines (233 loc) · 7.66 KB
/
syncotater.sh
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#!/bin/bash
# func dat
PrintUsage () {
cat << EOF
Usage:
syncotater.sh -htlrcopCV
Required:
-l leftvid
-r rightvid
-o outputvid
-C clapperlessfile
-f frame rate counter
Optional:
-p qualitypreset
(ffmpeg preset for h264)
-c Hres:Vres:offsetH:offestV
ie, 1080p -> 900p would use 1600:900:160:90
-t
test mode (output command strings only, no reencoding)
EOF
}
if [ $# -lt 4 ]
then
PrintUsage
exit 0
fi
# do the stuff and things!
while getopts "htl:r:o:c:p:C:f:" OPTION; do
case ${OPTION} in
t) PREFIX="echo ";;
l) LEFTVID="$OPTARG" ;;
r) RIGHTVID="$OPTARG" ;;
o) OUTFILE="$OPTARG" ;;
c) CROPOPTS=' -filter:v "crop='$OPTARG'"' ;;
p) PRESETOPT="$OPTARG" ;;
C) CLPR="$OPTARG" ;;
f) FRAMER="$OPTARG";;
esac
done
shift $(($OPTIND - 1))
if [ ! -r ${LEFTVID} ]
then
echo "Can't read left video?"
exit 2 fi
if [ ! -r ${RIGHTVID} ]
then
echo "Can't read right video?"
exit 2
fi
if [ -e ${OUTFILE}-3d.mp4 ]
then
echo "${OUTFILE}-3d.mp4 exists, cowardly refusing to try overwriting."
exit 3
else
touch ${OUTFILE}
CRTD=$?
if [ ! ${CRTD} ]
then
echo "Unable to write to file ${OUTFILE}."
exit 3
else
rm -f ${OUTFILE}
fi
fi
if [ ! -r ${CLPR} ]
then
echo "Can't find clapperless!"
exit 4
fi
if [ ! -x ${FRAMER} ]
then
echo "Can't run frame rate tool!"
exit 5
fi
PRESETOPT="${PRESETOPT:-ultrafast}"
# veryslow slow fast ultrafast, etc
ENCODEROPT=" -strict -2 -acodec aac -vcodec libx264 -preset ${PRESETOPT} "
# old ways to get frames/rates
#
#LFC=$(ffprobe -i ${LEFTVID} -show_frames -hide_banner |grep coded_picture_number | tail -1 | cut -d= -f2 )
#RFC=$(ffprobe -i ${RIGHTVID} -show_frames -hide_banner |grep coded_picture_number | tail -1 | cut -d= -f2 )
#LFR=$(exiftool -VideoFrameRate ${LEFTVID} | awk ' { print $NF} ' )
#RFR=$(exiftool -VideoFrameRate ${RIGHTVID} | awk ' { print $NF} ' )
while read count rate
do
LFC=$count
LFR=$rate
done < <(${FRAMER} ${LEFTVID})
while read count rate
do
RFC=$count
RFR=$rate
done < <(${FRAMER} ${RIGHTVID})
if [ $LFR != $RFR ]
then
echo "Differing frame rates. This tool needs matched frame rates for now."
exit 5
fi
# clapperless hates fractional framerates. Set one framerate as whole number,
# but keep frame interval time at actual frame rate interval.
case ${RFR} in
"24")
FR_IVAL="0.04166666666"
;;
"25")
FR_IVAL="0.04"
;;
"29.97")
LFR=30
FR_IVAL="0.03336670003"
;;
"30")
FR_IVAL="0.03333333333"
;;
"59.94")
LFR=60
FR_IVAL="0.01668335001"
;;
"60")
FR_IVAL="0.01666666666"
;;
"47.8")
LFR=48
FR_IVAL="0.02092050209"
;;
"48")
FR_IVAL="0.02083333333"
;;
"119.88")
LFR=120
FR_IVAL="0.008341675"
;;
"120")
FR_IVAL="0.00833333333"
;;
"239.76")
LFR=240
FR_IVAL="0.0041708375"
;;
"240")
FR_IVAL=".00416666666"
;;
esac
# get frame offsets...
FOFF=$(python2 ${CLPR} -c -r ${LFR} ${LEFTVID} ${RIGHTVID} | tail -1 |awk ' { print $1 } ')
# Using the second number's decimals would give a relative quality assessment. Closer to .5, the worse the offset.
#Offset would be A_n = B_1. A has X items, B has Y.
#If (n = 0 && X = Y) then Booya!
#If n < 0 then (swap [A,B], absval(n)).
#If (X - n = Y ) then trim A to [A_n -> X]
#If (X - n > Y ) then trim A to [A_n -> (A_n + Y)]
#If (X - n < Y ) then trim B to [B_1 -> (Y - (Y - A_n))] and trim A to [A_n -> X]
if [ ${FOFF} -eq 0 ] && [ ${LFC} -eq ${RFC} ]
then
LTRIMARGS=''
RTRIMARGS=''
# matching syncs and lengths
else
#Unmatched things, fixing those up...
if [ ${FOFF} -lt 0 ]
then
FOFF=$(( 0 - ${FOFF}))
# trim right to start at left.
FRONT_TRIM=$(echo "${FOFF} * ${FR_IVAL}" | bc)
FRONT_TRIM_TIME=$(date -d "1970-1-1 0:00 + 0${FRONT_TRIM} seconds" "+%H:%M:%S.%N")
RFCT=$((${RFC} - ${FOFF}))
LFCT=${RFCT}
if [ ${RFCT} -eq ${LFC} ]
then
#trimmed right equals left
RTRIMARGS="-ss ${FRONT_TRIM_TIME}"
LTRIMARGS=''
else
RFCE=$((${RFCT} - ${LFC}))
if [ ${RFCE} -gt 0 ]
then
#Right ending exceeds, trimming
END_TRIM=$(echo "${FR_IVAL} * ${LFC}" | bc)
RTRIMARGS="-ss ${FRONT_TRIM_TIME} -t ${END_TIME}"
LTRIMARGS=''
else
#Left ending exceeds, trimming.
END_TIME=$( echo "${FR_IVAL} * ${RFCT}" | bc)
RTRIMARGS="-ss ${FRONT_TRIM_TIME}"
LTRIMARGS="-ss 0 -t ${END_TIME}"
fi
fi
else
LFCT=$((${LFC} - ${FOFF}))
FRONT_TRIM=$(echo "${FOFF} * ${FR_IVAL}" | bc)
FRONT_TRIM_TIME=$(date -d "1970-1-1 0:00 + 0${FRONT_TRIM} seconds" "+%H:%M:%S.%N")
if [ ${LFCT} -eq ${RFC} ]
then
#trimmed left equals right.
LTRIMARGS="-ss ${FRONT_TRIM_TIME}"
RTRIMARGS=''
else
LFCE=$((${LFCT} - ${RFC}))
if [ ${LFCE} -gt 0 ]
then
#Left ending exceeds, trimming.
END_TRIM=$(echo "${FR_IVAL} * ${RFC}" | bc)
LTRIMARGS="-ss ${FRONT_TRIM_TIME} -t ${END_TIME}"
RTRIMARGS=''
else
#Right ending exceeds, trimming.
END_TIME=$( echo "${FR_IVAL} * ${LFCT}" | bc)
LTRIMARGS="-ss ${FRONT_TRIM_TIME}"
RTRIMARGS="-ss 0 -t ${END_TIME}"
fi
fi
fi
fi
echo "LFR RFR LFC RFC FOFF" >> $$.out
echo "$LFR $RFR $LFC $RFC $FOFF " >> $$.out
# Crop args:
LCROPARGS="${CROPOPTS}"
RCROPARGS="${CROPOPTS}"
# Shifted crop args:
# LCROPARGS=' -filter:v "crop=1600:900:164:90"'
# RCROPARGS=' -filter:v "crop=1600:900:156:90"'
echo "Trimmed left, front trim, front trime time, end trim, end trim time" >> $$.out
echo "${LFCT}, ${FRONT_TRIM}, ${FRONT_TRIM_TIME}, ${END_TIME}, ${END_TRIM_TIME}" >> $$.out
echo " left args, right args, left crop args, right crop args, encoding options" >> $$.out
echo "${LTRIMARGS}, ${RTRIMARGS}, ${LCROPARGS}, ${RCROPARGS}, ${ENCODEROPT}" >> $$.out
echo "ffmpeg -i ${LEFTVID} ${LTRIMARGS} ${ENCODEROPT} ${LAUDOPTS} ${LCROPARGS} ${OUTFILE}-left.mp4" >> $$.out
${PREFIX} ffmpeg -i ${LEFTVID} ${LTRIMARGS} ${ENCODEROPT} ${LAUDOPTS} ${LCROPARGS} ${OUTFILE}-left.mp4
echo "ffmpeg -i ${RIGHTVID} ${RTRIMARGS} ${ENCODEROPT} ${RAUDOPTS} ${RCROPARGS} ${OUTFILE}-right.mp4" >> $$.out
${PREFIX} ffmpeg -i ${RIGHTVID} ${RTRIMARGS} ${ENCODEROPT} ${RAUDOPTS} ${RCROPARGS} ${OUTFILE}-right.mp4
echo ${PREFIX} ffmpeg -i ${OUTFILE}-left.mp4 -i ${OUTFILE}-right.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2[v]; [0:a][1:a]amerge[a]" -map "[v]" -map "[a]" -ac 2 ${ENCODEROPT} ${OUTFILE}-3d.mp4 >> $$.out
${PREFIX} ffmpeg -i ${OUTFILE}-left.mp4 -i ${OUTFILE}-right.mp4 -filter_complex "[0:v][1:v]hstack=inputs=2[v]; [0:a][1:a]amerge[a]" -map "[v]" -map "[a]" -ac 2 ${ENCODEROPT} ${OUTFILE}-3d.mp4
echo "## ${OUTFILE}-3d.mp4 made with Potato! ##"
exit 0