3
# A convenient front-end for the various mpeg encoding tools.
4
# Allows "1 command" production of a video stream...
7
# Licensed under GPL (see http://www.fsf.org/licenses/gpl.html or contact
8
# the Free Software Foundation for a copy)
9
# Copyright Scott Moser
12
# these can be changed with env variables, just set and export to override
13
NICEVAL=${NICEVAL:-19}
15
LAV2YUV=${LAV2YUV:-"lav2yuv"}
16
YUVSCALER=${YUVSCALER:-"yuvscaler"}
17
MPEG2ENC=${MPEG2ENC:-"mpeg2enc"}
18
LAV2WAV=${LAV2WAV:-"lav2wav"}
19
AUDIOENC=${AUDIOENC:-"mp2enc"} # can be "toolame" or "mp2enc"
20
MPLEX=${MPLEX:-"mplex"}
21
YUVDENOISE=${YUVDENOISE:-"yuvdenoise"}
22
LAVINFO=${LAVINFO:-"lavinfo"}
24
NOISYLOGFILE="" # if not set, will be outputfilename.log -- only used if -L flag sent
25
QUIETLOG=${QUIETLOG:-"lav2mpeg.log"} # if set to not "" will log all normal messages to this file as well as stdout
26
LOGDATE=${LOGDATE:-1} # whether or not to output the date in log messages
27
LOGDATESTR=${LOGDATESTR:-"+%H:%M:%S"} # format for the date - only used if logdate!=0
28
LOGCOMMANDS=${LOGCOMMANDS:-0}; # if non-zero, will output the commands it runs. commands are always logged to NOISYLOGFILE if used
29
LOGONLY=${LOGONLY:-""} # will only log the commands it would use if set (for example useage/testing)
30
LAV2MPEGRC=${LAV2MPEGRC:-"$HOME/.lav2mpegrc"} # set this to contain your lav2mpeg rc file -- in bash sourceable syntax.
31
# it can modify any ENV vars in this script
32
# or set a "LAV2MPEG_OPTIONS" ENV to prepend default options that will be overridden by explicit command line options.
33
if [ "$LOGONLY" != "" ]; then
36
VCD_MEDIUM_BR=${VCD_MEDIUM_BR:-1550}
37
VCD_HIGH_BR=${VCD_HIGH_BR:-1800}
38
SVCD_HIGH_BR=${SVCD_HIGH_BR:-3000}
39
SVCD_HIGH_QUAL=${SVCD_HIGH_QUAL:-5}
40
SVCD_HIGH_BUFFSIZE=${SVCD_HIGH_BUFFSIZE:-100}
42
# extra flags for the encoders (will be the last thing on the line before file names)
43
EXTRA_LAV2YUV=${EXTRA_LAV2YUV:-""}
44
EXTRA_YUVSCALER=${EXTRA_YUVSCALER:-""}
45
EXTRA_MPEG2ENC=${EXTRA_MPEG2ENC:-""}
46
EXTRA_LAV2WAV=${EXTRA_LAV2WAV:-""}
47
EXTRA_AUDIOENC=${EXTRA_AUDIOENC:-""}
48
EXTRA_MPLEX=${EXTRA_MPLEX:-""}
49
EXTRA_YUVDENOISE=${EXTRA_YUVDENOISE:-""}
51
# things that can be changed with arguments
52
# don't let an env override, to avoid confusion
67
# -- shouldn't have to change below here
68
NICE="nice -n $NICEVAL"
73
if [ $LOGDATE -ne 0 ]; then
74
NOW=$(date $LOGDATESTR)
77
if [ "$logfile" = "" ]; then
80
echo "${NOW}$@" | tee -a $logfile
82
if [ "$output_noisy" != "" ]; then
83
echo "${NOW}$@" >> $noisylog
88
# delete raw files if sawraw is 0 or exiting with non-zero
89
if [ $saveraw -eq 0 -a "$1" = "0" ]; then
100
hours=$(expr $diff / 3600)
101
temp=$(expr $hours \* 3600 )
102
diff=$(expr $diff - $temp )
103
minutes=$(expr $diff / 60)
104
sec=$(expr $diff % 60)
105
printf "%i:%02d:%02d\n" "$hours" "$minutes" "$sec"
109
if [ "$LOGCOMMANDS" = "0" ]; then
110
echo "COMMAND=${step[$count]}"
112
if [ "$LOGONLY" = "" ]; then
122
Usage: $name [ -s/S -k/K -f/F -l/L -n/N -y/Y ] [ -m mode ] [ -e 0|1|2 ] [ -o outputFile ] [ -b vidbitrate ] [ -a audbitrate ] [ -q 0-30 ] [ -d XxY ] srcfile...
123
s/S - stereo : -s=off -S=on (default auto)
124
k/K - keep raw output files (.m1v, .m2v, .mp2) : -k=no -K=yes (default no)
125
f/F - use fifos : -f=no -F=yes (default no)
126
l/L - log all encoding : -l=no -L=yes (default no)
127
n/N - be noisy (don't hide output of tools) : -n=no -N=yes (default no)
128
y/Y - yuvdenoise : -y=don't use -Y=use (default e=1|2 use e=0 dont)
129
m - one of MODES (see below) (default $mode)
130
e - encoding quality : 0, 1, or 2 (default $encode_quality)
131
o - output file ( defaults to firstInputFileName.mpg )
132
b - video bitrate in kbps ( only used when -o is "mpeg1" or "mpeg2" )
133
a - audio bitrate in kpbs ( only used when -o is not "vcd*" )
134
q - quality for mpeg2enc ( only used when -o is "mpeg1" or "mpeg2" )
135
d - dimensions XxY ( only used when -o is "mpeg1" or "mpeg2" )
136
defaults to same as input
139
vcd -- standard VCD (352x240 or 352x288)
140
vcd_medium -- ${VCD_MEDIUM_BR}kbps video VCD (352x240 or 352x288)
141
vcd_high -- ${VCD_HIGH_BR}kbps video VCD (352x240 or 352x288)
142
svcd -- standard SVCD (480x480 or 480x576)
143
svcd_high -- ${SVCD_HIGH_BR}kbps(max) vbr @qual=${SVCD_HIGH_QUAL} (480x480 or 480x576)
144
mpeg1 -- honor -a -b -q -d flags default resolution same as input
145
mpeg2 -- honor -a -b -q -d flags default resolution same as input
149
- will create a VCD compatible mpeg named file.mpg
150
mpeg2: $name -m mpeg2 -o output.mpg file.edl
151
- will create a mpeg2 with default bitrate in same res as input
152
mpeg1: $name -a 160 -b 2110 -d 320x240 -m mpeg1 -o output.mpg file.edl
153
- will create a mpeg2 with videobitrate=2110 and audio=160
154
- and resolution 320x240
155
debug: export LOGONLY=1; $name -m mpeg2 -o output.mpg file.edl
156
- will print out the commands it would use to do this, but
159
please see the script for more info and environment variables set/used
165
logIt "going from ${video_width}x${video_height} ($video_norm) to ${output_width}x${output_height} in $mode with quality=$quality, bitrate=$bitrate and encodequal=${encode_quality}"
166
logIt "outfile=$outfile audio=$audio video=$video"
167
logIt "lav2yuv_flags=$lav2yuv_flags"
168
logIt "yuscaler_flags=$yuvscaler_flags"
169
logIt "mpeg2enc_flags=$mpeg2enc_flags"
170
logIt "lav2wav_flags=$lav2wav_flags"
171
logIt "audioenc_flags=$audioenc_flags"
172
logIt "mplex_flags=$mplex_flags"
173
logIt "need_scale=$needscale"
174
logIt "downscale=$downscaling"
177
if [ $# -eq 0 -o "$1" = "--help" -o "$1" = "-h" ]; then
183
if [ -e $LAV2MPEGRC ]; then
184
logIt "Sourcing lav2mpgrc file $LAV2MPEGRC (this can change defaults!)"
186
LAVRC_COUNT=$(echo $LAV2MPEG_OPTIONS | wc -w )
190
while getopts "sSkKfFlLnNyYb:a:q:d:m:e:o:" opt $LAV2MPEG_OPTIONS $@
194
infostr="${infostr} using mono -"
197
infostr="${infostr} using stereo -"
200
infostr="${infostr} not saving raw files -"
203
infostr="${infostr} saving raw files -"
206
infostr="${infostr} not using fifos-"
209
infostr="${infostr} using fifos-"
212
infostr="${infostr} not logging all -"
215
infostr="${infostr} logging all -"
218
infostr="${infostr} not being noisy -"
221
infostr="${infostr} being noisy -"
224
infostr="${infostr} not using yuvdenoise -"
227
infostr="${infostr} using yuvdenoise -"
230
infostr="${infostr} using video bitrate=$bitrate -"
232
a) useraencbpr=$OPTARG
233
infostr="${infostr} using audio bitrate=$useraencbpr"
236
infostr="${infostr} using quality=$quality -"
239
infostr="${infostr} using outputres=$outputres -"
242
infostr="${infostr} mode=$mode -"
244
e) encode_quality=$OPTARG
245
infostr="${infostr} encode_quality=$encode_quality -"
248
infostr="${infostr} outfile=$outfile -"
255
let MOPTIND=OPTIND-LAVRC_COUNT
256
shift `expr $MOPTIND - 1`
258
if [ "${QUIETLOG}" != "" ]; then
263
#uncomment to blank logfile
268
# lavinfo should set up video_frames, video_width
269
# video_height, video_inter, video_norm, audio_chans
270
eval $($LAVINFO $@ | grep "=") # grep for = to remove Warnings
271
if [ "$video_frames" = "" ]; then
272
logIt "'lavinfo $@' died! exiting"
273
logIt " maybe you don't have lavinfo. or your input flags were wrong"
274
logIt " input files must be the last input on the command line"
281
NTSC) output_width=352; output_height=240 ;;
282
PAL) output_width=352; output_height=288 ;;
283
SECAM) output_width="SECAM_VCD_WIDTH???"; output_height="SECAM_VCD_HEIGHT";;
288
NTSC) output_width=480; output_height=480 ;;
289
PAL) output_width=480; output_height=576;;
290
SECAM) output_width="SECAM_SVCD_WIDTH???"; output_height="SECAM_SVCD_HEIGHT" ;;
294
if [ "$outputres" != "" ]; then
296
temp=${outputres%%[+-]*}
297
output_width=${temp%x*}
298
output_height=${temp#*x}
299
logIt "using output_width=$output_width, output_height=$output_height"
300
# these don't work yet, negative values would mess them up
302
output_xoff=${temp%%[+-]*}
303
output_yoff=${temp##*[+-]}
305
output_width=$video_width
306
output_height=$video_height
312
# hopefully sane input has been checked, lets start setting things up
314
# simple check for logonly mode
315
if [ "$LOGONLY" != "" -a "$LOGONLY" != "0" -a $use_fifo -eq 1 ]; then
317
logIt "can't do logonly with fifos, turning fifos off"
320
# set up extra flags as possibly given by user
321
lav2yuv_flags=$EXTRA_LAV2YUV
322
yuvscaler_flags=$EXTRA_YUVSCALER
323
mpeg2enc_flags=$EXTRA_MPEG2ENC
324
lav2wav_flags=$EXTRA_LAV2WAV
325
audioenc_flags=$EXTRA_AUDIOENC
326
mplex_flags=$EXTRA_MPLEX
327
yuvdenoise_flags=$EXTRA_YUVDENOISE
329
# get output mpeg version and output file names
331
vcd|vcd_medium|vcd_high|mpeg1) mpegver=1 ;;
332
svcd|svcd_high|mpeg2) mpegver=2 ;;
335
if [ "$outfile" != "" ]; then
336
basename=${outfile%.*}
339
outfile=${basename}.mpg
341
video=${basename}.m${mpegver}v
342
audio=${basename}.mp2
344
if [ "$NOISYLOGFILE" = "" ]; then
345
noisylog=${basename}.log
347
noisylog=$NOISYLOGFILE
351
if [ "$userstereo" = "" ]; then
352
stereo=${audio_chans:-0}
357
if [ $AUDIOENC = "mp2enc" ]; then
363
if [ "$stereo" != "0" ]; then
364
aencbpr=$aencbpr_stereo
366
aencbpr=$aencbpr_mono
367
mono_flag=$nostereo_flag
369
# set useraencbpr to aencbpr unless set
370
useraencbpr=${useraencbpr:-$aencbpr}
372
# set up always-on flags
373
lav2yuv_flags="$lav2yuv_flags $@"
379
yuvscaler_flags="-n $ysnorm $yuvscaler_flags"
380
mpeg2enc_flags="-o $video $mpeg2enc_flags"
381
lav2wav_flags="$lav2wav_flags $@"
382
if [ $AUDIOENC = "mp2enc" ]; then
383
audioenc_flags="$mono_flag -r 44100 ${audioenc_flags} -o $audio"
386
audioenc_flags="$mono_flag -s 44.1 /dev/stdin ${audioenc_flags} $audio"
388
mplex_flags=" -o $outfile $mplex_flags $audio $video"
390
# input/output dependent
391
if [ $video_width -eq $output_width -a $video_height -eq $output_height ]; then
397
if [ $video_width -gt $output_width -o $video_width -eq $output_width ]; then
398
if [ $video_height -gt $output_height -o $video_height -eq $output_height ];
404
if [ "$video_inter" = "1" ]; then
405
yuvdenoise_flags="$yuvdenoise_flags -F"
408
#encoder quality dependent
409
case ${encode_quality} in
411
mpeg2enc_flags="-4 4 -2 4 ${mpeg2enc_flags}"
412
if [ $downscaling -ne 0 ]; then
413
yuvscaler_flags="-M RESAMPLE ${yuvscaler_flags}"
416
if [ "$userdenoise" != "" -a "$userdenoise" != "0" ]; then
417
logIt "set dodenoise to on at users request"
422
mpeg2enc_flags="-4 1 -2 1 ${mpeg2enc_flags}" # -N here?
424
if [ "$userdenoise" != "" -a "$userdenoise" = "0" ]; then
430
if [ "$userdenoise" != "" -a "$userdenoise" = "0" ]; then
436
# output(mode) dependent
439
yuvscaler_flags="-O VCD ${yuvscaler_flags}"
440
mpeg2enc_flags="-a 2 -f 1 ${mpeg2enc_flags}"
441
mplex_flags="-f 1 ${mplex_flags}"
444
yuvscaler_flags="-O VCD ${yuvscaler_flags}"
445
mpeg2enc_flags="-a 2 -f 2 -b ${VCD_MEDIUM_BR} ${mpeg2enc_flags}"
446
mplex_flags="-f 2 ${mplex_flags}"
449
yuvscaler_flags="-O VCD ${yuvscaler_flags}"
450
mpeg2enc_flags="-a 2 -f 2 -b ${VCD_HIGH_BR} ${mpeg2enc_flags}"
451
mplex_flags="-f 2 ${mplex_flags}"
454
yuvscaler_flags="-O SIZE_${output_width}x${output_height} ${yuvscaler_flags}"
455
mpeg2enc_flags="-f 0 -b ${bitrate} ${mpeg2enc_flags}"
456
mplex_flags="-f 0 ${mplex_flags}"
460
yuvscaler_flags="-O SVCD ${yuvscaler_flags}"
461
mpeg2enc_flags="-a 2 -f 4 ${mpeg2enc_flags}"
462
mplex_flags="-f 4 ${mplex_flags}"
464
audioenc_flags="-e $audioenc_flags"
467
yuvscaler_flags="-O SVCD ${yuvscaler_flags}"
468
mpeg2enc_flags="-a 2 -f 5 -b ${SVCD_HIGH_BR} -V ${SVCD_HIGH_BUFFSIZE} -q ${SVCD_HIGH_QUAL} ${mpeg2enc_flags}"
469
mplex_flags="-f 5 ${mplex_flags}"
471
audioenc_flags="-e $audioenc_flags"
474
yuvscaler_flags="-O SIZE_${output_width}x${output_height} ${yuvscaler_flags}"
475
mpeg2enc_flags="-f 3 -b ${bitrate} -q $quality ${mpeg2enc_flags}"
476
mplex_flags="-V -f 3 ${mplex_flags}"
481
if [ $dodenoise -ne 0 ]; then
482
yuvdenoise_str="| $NICE $YUVDENOISE $yuvdenoise_flags"
485
logIt "not using yuvdenoiser, dodenoise=$dodenoise"
488
if [ $needscale -ne 0 ]; then
489
yuvscale_str="| $NICE $YUVSCALER $yuvscaler_flags"
494
#final flags -- bitrate flag is -b for both mp2enc and toolame
495
audioenc_flags="-b $aencbpr $audioenc_flags"
498
# this is kinda nasty, but it ends up giving a somewhat clean loop at the
499
# bottom without a whole lot of if's and such
501
stepdesc[$count]="video encoding"
502
step[$count]="$NICE $LAV2YUV $lav2yuv_flags $yuvdenoise_str $yuvscale_str | $NICE $MPEG2ENC $mpeg2enc_flags"
505
stepdesc[$count]="audio encoding"
506
step[$count]="$NICE $LAV2WAV $lav2wav_flags | $NICE $AUDIOENC $audioenc_flags"
509
if [ $use_fifo -eq 1 ]; then
510
stepdesc[$count]="encoding with fifos"
512
stepdesc[$count]="multiplexing"
514
step[$count]="$NICE $MPLEX $mplex_flags"
517
if [ $noisy -ne 0 -a $logall -ne 0 ]; then
518
output_noisy="2>&1 | tee -a $noisylog"
521
if [ $noisy -eq 0 ]; then
522
if [ $logall -eq 0 ]; then
526
output_noisy=">>$noisylog 2>&1"
530
if [ $use_fifo -ne 0 ]; then
538
logIt "using mode=$mode, stereo=$stereo audio bpr=$aencbpr"
539
if [ $logall -ne 0 ]; then
540
logIt "logging everything to $noisylog"
542
logIt "beginning conversion of $@ to $outfile"
543
logIt "had $video_frames to encode"
550
if [ $stepnum -eq 3 -o $use_fifo -ne 1 ]; then
551
logIt "beginning ${stepdesc[$count]}"
552
if [ $LOGCOMMANDS != "0" ]; then
553
logIt "COMMAND=${step[$count]}"
556
if [ $stepnum -eq 3 ]; then
557
detach="" # don't detach the last stem (mplex)
559
eval doStep $output_noisy $detach
561
if [ $RET -ne 0 ]; then
562
logIt "ugh! ${stepdesc[$count]} failed, bailing. used command:"
563
logIt "${step[$count]}"
566
if [ $stepnum -eq 3 -o $use_fifo -ne 1 ]; then
567
diff=$(getTimeDiff $START $SECONDS)
568
elapsed=$(expr $SECONDS - $START)
569
if [ "$elapsed" != "0" ]; then
570
fps=$(echo "scale=3; $video_frames / $elapsed " | bc)
571
logIt "finished ${stepdesc[$count]} ( took $diff - $fps fps)"
573
logIt "finished ${stepdesc[$count]} ( took $diff )"
579
diff=$(getTimeDiff $STARTALL $SECONDS)
580
temp=$(expr $SECONDS - $STARTALL)
581
if [ "$temp" != "0" ]; then # avoid divide by zero possibility
582
fps=$(echo "scale=3; $video_frames / $temp" | bc)
583
logIt "finished encoding (took $diff - $fps fps)"
585
logIt "finished encoding (took $diff)"