同步两个音频文件

Sync two audio files

我有 2 个音频文件:

它们几乎相同,但生成的声音字体不同。

问题:第二个文件晚了几秒

如何将第二个文件与第一个文件同步?也许有一些bash软件可以检测到第一个声音中是否出现第一个响亮的声音并将correct.wav与incorrect.wav进行比较,缩短incorrect.wav文件的结尾。

我知道我可以手动完成,但我需要为很多文件自动解决。

这是我找到的近似解:

1) 用于检测声音同步以使用此 Python 脚本 - https://github.com/jeorgen/align-videos-by-sound 但它并不完美,未检测到 100%。

2) 将 sox 用于 cutting/trimming/comparing/detecting 声音持续时间(代码提取):

length1ok=$(sox correct.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$##p')
length2ok=$(sox incorrect.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$##p')
if [[ $length1ok == $length2ok ]]; then
    echo "Everything OK: $length1ok = $length2ok"
else
    echo "Fatal error: Not the same final files"
fi

diff=$(echo "$length2 - $length1" | bc -l)
echo "difference = $diff"
echo "webm $length1 not greater than fluid2 $length2"
sox correct.wav incorrect.wav pad 0 $diff

评论UltrasoundJelly的回答: 这是我为您的代码得到的结果:

这是我需要的结果:

这是一种解决方案:

  • 使用ffmpeg找到每个文件中的前导沉默
  • 如果新文件有较长的前导静默,trim与sox的区别
  • 如果新文件的前导静默较短,则用 sox
  • 填充开头
  • Trim 新文件与原文件长度相同 sox

Bash 脚本:

FILEONE=
FILETWO=
MINSILENCE=0.1
THRESH="-50dB"
S1=$(ffmpeg -i $FILEONE -af silencedetect=noise=$THRESH:d=$MINSILENCE -f null -  2>&1 | grep silence_duration -m 1 | awk '{print $NF}')
S2=$(ffmpeg -i $FILETWO -af silencedetect=noise=$THRESH:d=$MINSILENCE -f null -  2>&1 | grep silence_duration -m 1 | awk '{print $NF}')
if [ -z "$S1" ]; then echo "no starting silence found in $FILEONE" && exit 1;fi
if [ -z "$S2" ]; then echo "no starting silence found in $FILETWO" && exit 1;fi
DIFF=$(echo "$S1-$S2"|bc)
ISNEG=$(echo $DIFF'>0'| bc -l)
DIFF=${DIFF#-}
BASE="${FILETWO%.*}"
if [ $ISNEG -eq 1 ]
then
  echo "> ... padding "
  SAMPRATE=$(sox --i -r $FILETWO)
  sox -n -r $SAMPRATE -c 2 silence.wav trim 0.0 $DIFF
  sox silence.wav $FILETWO $BASE.shift.wav
  rm silence.wav
else
  echo "< ... trimming "
  sox $FILETWO $BASE.trim.wav trim $DIFF
fi

length1=$(sox $FILEONE -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$##p')
length2=$(sox $BASE.trim.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$##p')

if (( $(echo "$length2 > $length1" | bc -l) )); then
    diff=$(echo "$length2 - $length1" | bc -l)
    echo "difference = $diff"
    sox $BASE.trim.wav finished.wav trim 0 -$diff
fi