同步两个音频文件 [英] Sync two audio files
问题描述
我有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屋!