同步两个音频文件 [英] Sync two audio files

查看:110
本文介绍了同步两个音频文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个音频文件:

  • correct.wav(持续时间3:07)
  • incorrect.wav(持续时间3:10)

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

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

如何将第二个文件与第一个文件同步?也许有一些bash软件可以检测到第一声声音中出现的第一声声音,然后将正确的.wav与错误的.wav进行比较,缩短不正确的.wav文件的结尾.

我知道我可以手动完成此操作,但是我需要自动解决许多文件的问题.

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

1)用于检测声音同步以使用此Python脚本-

这是我需要什么结果:

解决方案

这里是一种解决方案:

  • 使用 ffmpeg 查找每个文件中的前导静音
  • 如果新文件的前导寂静时间更长,请使用 sox
  • 调整差异
  • 如果新文件的前导音较短,请以 sox
  • 开头
  • 使用 sox
  • 将新文件修剪为与原始文件相同的长度

Bash脚本:

  FILEONE = $ 1FILETWO = $ 2最小= 0.1THRESH =-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}')如果[-z"$ S1"];然后回显在$ FILEONE中找不到开始的静默状态"&&1号出口; fi如果[-z"$ S2"];然后回显在$ FILETWO中找不到开始的静默状态"&&1号出口; fiDIFF = $(回显"$ S1- $ S2" | bc)ISNEG = $(echo $ DIFF'> 0'| bc -l)DIFF = $ {DIFF#-}BASE ="$ {FILETWO%.*}"如果[$ ISNEG -eq 1]然后echo"$ 1> $ 2 ... padding $ 2"SAMPRATE = $(sox –i -r $ FILETWO)袜-n -r $ SAMPRATE -c 2 silence.wav trim 0.0 $ DIFF袜类沉默.wav $ FILETWO $ BASE.shift.wavrm silence.wav别的回声"$ 1< $ 2 ...修剪$ 2"袜$ FILETWO $ BASE.trim.wav修剪$ DIFF科幻length1 = $(sox $ FILEONE -n stat 2>& 1 | sed -n's#^长度(秒):[^ 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')如果(($(echo"$ length2> $ length1" | bc -l)));然后diff = $(echo"$ length2-$ length1" | bc -l)回声差异= $ diff"sox $ BASE.trim.wav完成.wav修剪0-$ diff科幻 

I have 2 audio files:

  • correct.wav (duration 3:07)
  • incorrect.wav (duration 3:10)

They are almost the same, but was generated with different sound fonts.

The problem: The second file is late for a few seconds.

How can I sync second file with the first one? Maybe there some bash software that could detect first loud sounds appearance in the first sound and compare correct.wav with incorrect.wav, shorten the end of the incorrect.wav file.

I know I can do it manually, but I need automated soulution for a lot of files.

Here is approximate solutions I found:

1) for detecting sound syncing to use this Python script - https://github.com/jeorgen/align-videos-by-sound but it's not perfect, not detecting 100%.

2) use sox for cutting/trimming/comparing/detecting sound durations (code extraction):

length1ok=$(sox correct.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p')
length2ok=$(sox incorrect.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#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

Comment to UltrasoundJelly's answer: Here what result I get for your code:

Here what result I need:

解决方案

Here's one solution:

  • Use ffmpeg to find the leading silence in each file
  • If the new file has a longer leading silence, trim the difference with sox
  • If the new file has a shorter leading silence, pad the start with sox
  • Trim the new file to the same length as the original with sox

Bash Script:

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

这篇关于同步两个音频文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆