[MPlayer-users] A/V sync problem from out-of-spec audio sampling rate

Heitzso heitzso at growthmodels.com
Thu Jun 2 01:12:32 CEST 2005


I appreciate all of the help I've received on this problem.
I still need to test a mencoder patch (that I've applied and compiled
with, but have not tested).  In the meantime, I'm posting the following
script that will resample audio when the audio is out-of-spec, and not
resample audio when the audio is within spec. 

NOTE script meant to compress raw.dv to dvd grade mpg with
ac3 audio at 4500 video bit rate.

The video compression part is based on transcode's dvtodvd.sh.
I can't use transcode peeled off audio to determine how much the
audio is out of spec because transcode cuts the audio based on the
video (and assumes the audio is within spec).  Hence using ffmpeg
to peel off the audio, ecalength to measure, etc.

THIS SCRIPT IS NOT PARAMETERIZED NOR IS IT INDUSTRIAL STRENGTH.
I AM NOT PROVIDING A SITE/APP SPECIFIC CONFIG SCRIPT.
I AM NOT PROVIDING THE FFMPEG.CFG FILE (FIND AT TRANSCODE SITE).
In other words, won't work at all without a little touch up, no error 
checking
re whether a program is happy or not doing its job, etc.  But it should get
someone started with a solution if faced with this problem.

[[ short explanation of problem -- some DV equip creates out of spec
unlocked audio that becomes apparent when the A/V streams are separated,
compressed, and re-mux'ed together.  Problem  not apparent at beginning of
the video, the A/V creeps increasingly out of sync.  Worst offender 
seems to
be some Canon camera models from a particular time period that created
48008-48009 audio which leads to approx .3 sec A/V out of sync after about
30 minutes of video. ]]

========================
#!/bin/bash

if [ ! -e cstandalone.sh -o ! -e config.sh -o ! -e ffmpeg.cfg ]; then
    echo "You must run this program from the scripts directory!"
    exit 1
fi

returnDir=`pwd`
. config.sh
cp ffmpeg.cfg $dvInterviewsDir
cd $dvInterviewsDir

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 configuration file
rm -f ffmpeg.cfg
# 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" " 
-f3`
videoSec=$(echo "scale=3; $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 
$actualRate"
# #######################################

# #######################################
# 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 ]
then
    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 
else
    echo "Not resampling $1 audio."
    mv  $1.long.wav  $1.wav
fi
# #######################################

# #######################################
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
# #######################################

# #######################################
echo "Moving $1.mpg to $mpegsDir ..."
mv $1.mpg $mpegsDir
# #######################################

echo "Finished compressing $1"
echo ""
cd $returnDir




More information about the MPlayer-users mailing list