Bash 同步两个音频文件

Bash 同步两个音频文件,bash,audio,ffmpeg,signal-processing,sox,Bash,Audio,Ffmpeg,Signal Processing,Sox,我有2个音频文件: correct.wav(持续时间3:07) 不正确的.wav(持续时间3:10) 它们几乎是相同的,但生成的声音字体不同 问题:第二个文件延迟了几秒钟。 如何将第二个文件与第一个文件同步?也许有一些bash软件可以检测到第一个声音中出现的第一个响亮的声音,并将correct.wav与error.wav进行比较,缩短error.wav文件的结尾 我知道我可以手动操作,但我需要很多文件的自动解析 以下是我找到的近似解决方案: 1) 用于检测声音同步,请使用此Python脚本

我有2个音频文件:

  • correct.wav(持续时间3:07)
  • 不正确的.wav(持续时间3:10)

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

问题:第二个文件延迟了几秒钟。

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

我知道我可以手动操作,但我需要很多文件的自动解析

以下是我找到的近似解决方案:

1) 用于检测声音同步,请使用此Python脚本-但它不是完美的,不是100%检测

2) 使用sox切割/修剪/比较/检测声音持续时间(代码提取):

对超声波果冻的回答发表评论: 下面是我对您的代码得到的结果:

以下是我需要的结果:

这里有一个解决方案:

  • 使用
    ffmpeg
    查找每个文件中的前导静音
  • 如果新文件的前导静音较长,请使用
    sox
  • 如果新文件的前导静音较短,请用
    sox
  • 使用
    sox
Bash脚本:

FILEONE=$1
FILETWO=$2
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 "$1>$2 ... padding $2"
  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 "$1<$2 ... trimming $2"
  sox $FILETWO $BASE.trim.wav trim $DIFF
fi

length1=$(sox $FILEONE -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p')
length2=$(sox $BASE.trim.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#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
FILEONE=$1
FILETWO=$2
MINSILENCE=0.1
THRESH=“-50dB”
S1=$(ffmpeg-i$FILEONE-af-silencedetect=noise=$THRESH:d=$MINSILENCE-f null-2>&1 | grep-silence_duration-m1 | awk'{print$NF})
S2=$(ffmpeg-i$FILETWO-af silenedetect=noise=$THRESH:d=$MINSILENCE-f null-2>&1 | grep silence_duration-m1 | awk'{print$NF}')
如果[-z“$S1”];然后回显“在$FILEONE中未发现启动静音”&&exit 1;fi
如果[-z“$S2”];然后回显“在$FILETWO中找不到启动静音”&&exit 1;fi
差异=$(回音“$S1-$S2”| bc)
ISNEG=$(echo$DIFF'>0'| bc-l)
DIFF=${DIFF#-}
BASE=“${FILETWO%.*}”
如果[$ISNEG-等式1]
然后
回显“$1>$2…填充$2”
SAMPRATE=$(sox--i-r$FILETWO)
sox-n-r$SAMPRATE-c 2静音.wav微调0.0$DIFF
sox silence.wav$FILETWO$BASE.shift.wav
rm.wav
其他的
echo“$1$length1”| bc-l));然后
差异=$(回声“$length2-$length1”| bc-l)
echo“差异=$diff”
sox$BASE.trim.wav finished.wav trim 0-$diff
fi
这里有一个解决方案:

  • 使用
    ffmpeg
    查找每个文件中的前导静音
  • 如果新文件的前导静音较长,请使用
    sox
  • 如果新文件的前导静音较短,请用
    sox
  • 使用
    sox
Bash脚本:

FILEONE=$1
FILETWO=$2
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 "$1>$2 ... padding $2"
  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 "$1<$2 ... trimming $2"
  sox $FILETWO $BASE.trim.wav trim $DIFF
fi

length1=$(sox $FILEONE -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p')
length2=$(sox $BASE.trim.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#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
FILEONE=$1
FILETWO=$2
MINSILENCE=0.1
THRESH=“-50dB”
S1=$(ffmpeg-i$FILEONE-af-silencedetect=noise=$THRESH:d=$MINSILENCE-f null-2>&1 | grep-silence_duration-m1 | awk'{print$NF})
S2=$(ffmpeg-i$FILETWO-af silenedetect=noise=$THRESH:d=$MINSILENCE-f null-2>&1 | grep silence_duration-m1 | awk'{print$NF}')
如果[-z“$S1”];然后回显“在$FILEONE中未发现启动静音”&&exit 1;fi
如果[-z“$S2”];然后回显“在$FILETWO中找不到启动静音”&&exit 1;fi
差异=$(回音“$S1-$S2”| bc)
ISNEG=$(echo$DIFF'>0'| bc-l)
DIFF=${DIFF#-}
BASE=“${FILETWO%.*}”
如果[$ISNEG-等式1]
然后
回显“$1>$2…填充$2”
SAMPRATE=$(sox--i-r$FILETWO)
sox-n-r$SAMPRATE-c 2静音.wav微调0.0$DIFF
sox silence.wav$FILETWO$BASE.shift.wav
rm.wav
其他的
echo“$1$length1”| bc-l));然后
差异=$(回声“$length2-$length1”| bc-l)
echo“差异=$diff”
sox$BASE.trim.wav finished.wav trim 0-$diff
fi

文件在开始时会有一些静默吗?在大多数情况下-是的,它取决于正确的.wav文件,开始静默可能在1-5秒之间变化。所有文件在开始时都会有一些静默吗?在大多数情况下-是的,它取决于正确的.wav文件,开始静默可能在1-5秒之间变化W,这几乎是我需要的,但我用图片更新了我的问题我到底需要什么。请回复我。我只需要修剪较长的文件。我会修改代码。非常感谢,修改后我会接受你的回答。我已经花了很多时间手动编辑了数百个这样的文件,在你的帮助下我可以自动编辑)它工作起来很有魅力。我添加了一些代码来删除文件末尾FILETWO,因此FILEONE==FILETWO持续时间。Сode可能有点凌乱,因此您可以对其进行编辑。还有一件事需要提及,如果在运行代码之前先对每个文件上的音频进行规范化,您可能会获得更好的精度。看起来你的一个文件比另一个文件安静得多。哇,这几乎是我需要的,但我用图片更新了我的问题,我需要的是什么。请回复我。我只需要修剪较长的文件。我会修改代码。非常感谢,修改后我会接受你的回答。我已经花了很多时间手动编辑了数百个这样的文件,在你的帮助下我可以自动编辑)它工作起来很有魅力。我添加了一些代码来删除文件末尾FILETWO,因此FILEONE==FILETWO持续时间。Сode可能有点凌乱,因此您可以对其进行编辑。还有一件事需要提及,如果在运行代码之前先对每个文件上的音频进行规范化,您可能会获得更好的精度。看起来您的一个文件比另一个文件安静得多。