[MPlayer-users] corrected a/v sync correction script

Heitzso heitzso at growthmodels.com
Thu Jun 2 17:29:23 CEST 2005

The script I emailed to these lists last night did not
maintain enough precision with bc to work optimally.
The following excerpt bumps up the scale factor for
bc but otherwise is the same (though excerpt and with
some comment lines pulled). 

As noted in my last email to these lists with the script,
it needs configuration/modification etc.   But may help
someone else who is fighting out-of-spec audio sampling
in a raw.dv file.

ALSO, I noted that yesterday's script got banged up
in email.  Please, if you use a variation of this script,
be sure to work through it and double check that
lines weren't rearranged in transit. 

Reiterating the problem I'm trying to solve with this
script -- some DV equip does not clock audio samples
correctly.  Viewing the dv files looks fine.  When compressed,
if assume audio is really 48000, you end up with creeping
A/V sync problems (gradually increasing).  This script
peels off audio, calculates a correction factor, resamples
the audio, then re-multiplexes the compressed A/V
streams back together.   Compression based on dvtodvd.sh
from transcode. 

echo "Compressing $1 for standalone: ac3, video bit rate 4500 ..."
# encode video, throw away stdout, hold onto stderr from last run
echo "... video compression pass one"
transcode --ext none,none -i $1.dv -x dv,null \
    -o $1.m2v -y ffmpeg,null -m $1.ac3 \
    -E 48000,16,2 --export_prof dvd-ntsc -R 1,$1.log \
    -b 192 -j 0,8,0,8 -w 4500 --encode_fields b --export_asr 2 \
    > /dev/null 2>$1.stderr
echo "... video compression pass two"
transcode --ext none,none -i $1.dv -x dv,null \
    -o $1.m2v -y ffmpeg,null -m $1.ac3 \
    -E 48000,16,2 --export_prof dvd-ntsc -R 2,$1.log \
    -b 192 -j 0,8,0,8 -w 4500 --encode_fields b --export_asr 2 \
    > /dev/null 2>$1.stderr
# clean up ffmpeg log and audio file if present
rm -f $1.log $1.ac3
# pick up number of frames
videoFrames=`grep ' encoded ' $1.stderr | grep 'clip length' | cut -d" " 
videoSec=$(echo "scale=6; $videoFrames/30000.0*1001.0" | bc)
echo "$1 has $videoFrames video frames, $videoSec seconds"
rm -f $1.stderr
# use ffmpeg to split out ENTIRE audio stream (versus transcode that clips)
echo "Splitting $1 audio to wav file ..."
rm -f $1.long.wav
ffmpeg -i $1.dv -vn $1.long.wav \
    >$1.split_out_audio.log 2>&1
rm -f $1.split_out_audio.log
# use ecalength to calculate length, then calculate correction
audioSec=`ecalength -s $1.long.wav  2>/dev/null`
actualRate=$(echo "scale=4; $audioSec/$videoSec*48000.0" | bc)
echo "$1 has $audioSec seconds of audio assuming 48000, actual rate is 
# test whether need to resync or not
diffSec=$(echo "scale=3; $audioSec-$videoSec" | bc)
diffSec=$(echo "scale=3; if ($diffSec<=0) $diffSec*-1 else $diffSec" | bc)
resync=$(echo "if ($diffSec>0.08) {1} else {0}" | bc)
if [ $resync -eq 1 ]
    echo "Resampling $1 audio to correct sample rate ..."
    sox -r $actualRate $1.long.wav -r 48000 $1.wav resample -q
    rm  -f  $1.long.wav 
    echo "Not resampling $1 audio."
    mv  $1.long.wav  $1.wav
echo "Converting $1 audio wav to ac3 ..."
ffmpeg -i $1.wav -hq -ab 192 $1.ac3 >/dev/null 2>&1
rm -f $1.wav
echo "Multiplexing $1 video and audio into $1.mpg ..."
mplex -v 1 -f 8 -o $1.mpg -V $1.m2v $1.ac3 >$1.mplex.log 2>&1
rm -f  $1.m2v  $1.ac3
rm -f $1.mplex.log

More information about the MPlayer-users mailing list