Синхронизировать два аудиофайла

У меня есть 2 аудиофайла:

  • правильный.wav (длительность 3:07)
  • некорректный.wav (длительность 3:10)

2 аудиофайла

Они почти одинаковые, но сгенерированы с разными звуковыми шрифтами.

Проблема: второй файл запаздывает на несколько секунд.

Как я могу синхронизировать второй файл с первым? Может быть, есть какая-нибудь программа bash, которая могла бы определить появление первых громких звуков в первом звуке и сравнить правильный.wav с неправильным.wav, укоротить конец неправильного.wav файла.

Я знаю, что могу сделать это вручную, но мне нужно автоматическое решение для многих файлов.

Вот приблизительные решения, которые я нашел:

1) для обнаружения синхронизации звука использовать этот скрипт Python - https://github.com/jeorgen/align-videos-by-sound, но это не идеально, не на 100%.

2) использовать sox для вырезания/обрезки/сравнения/определения длительности звука (извлечение кода):

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

Комментарий к ответу UltrasoundJelly: Вот какой результат я получаю для вашего кода:

Результат

Вот какой результат мне нужен:

Нужен результат


person kostya572    schedule 26.12.2017    source источник
comment
Будут ли файлы иметь некоторую тишину при запуске?   -  person Gyan    schedule 26.12.2017
comment
в большинстве ситуаций - да, зависит от правильного.wav файла, стартовая тишина может варьироваться от 1-5 секунд   -  person kostya572    schedule 26.12.2017


Ответы (1)


Вот одно из решений:

  • Используйте ffmpeg, чтобы найти первую паузу в каждом файле
  • Если новый файл имеет более продолжительную начальную паузу, обрежьте разницу с помощью sox
  • Если новый файл имеет более короткую начальную паузу, дополните начало sox
  • Обрежьте новый файл до той же длины, что и оригинал, с помощью sox

Баш-скрипт:

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
person UltrasoundJelly    schedule 27.12.2017
comment
Вау, это почти то, что мне нужно, но я обновил свой вопрос с картинками, что именно мне нужно. Пожалуйста ответьте мне. - person kostya572; 27.12.2017
comment
просто нужно будет обрезать более длинный файл. я переделаю код. - person UltrasoundJelly; 27.12.2017
comment
Большое спасибо, я приму ваш ответ после обновления. Я провел много часов, вручную редактируя сотни этих файлов, с вашей помощью я мог сделать это автоматически) - person kostya572; 27.12.2017
comment
Работает как часы. Я добавил некоторый код для удаления конца файла FILETWO, поэтому FILEONE == FILETWO продолжительность. Код мог быть немного грязным, поэтому вы могли его отредактировать. - person kostya572; 27.12.2017
comment
Еще одна вещь, которую следует упомянуть: вы можете получить еще большую точность, если сначала нормализуете звук в каждом файле перед запуском кода. Похоже, один из ваших файлов значительно тише другого. - person UltrasoundJelly; 28.12.2017
comment
Спасибо, проверю нормализацию на 2-х файлах. Первый звук очень громкий, поэтому имеет шорох. Нормализация не помогает убрать шелест, поэтому я использую такой сложный способ с 2-мя звуковыми шрифтами. Также теперь я работаю над ситуацией, когда тишина запуска второго файла находится перед тишиной запуска первого файла, теперь она выводится неправильно. - person kostya572; 28.12.2017
comment
Итак, вы хотите дополнить второй файл вместо того, чтобы укорачивать первый? Я снова модифицирую свой код. - person UltrasoundJelly; 28.12.2017
comment
Возможны 2 разные ситуации: заполнение и обрезка второго файла. 50% кода работает отлично. Основная задача: сделать синхронизацию с первым файлом, начиная с локации тишины. - person kostya572; 28.12.2017
comment
Именно то, что мне было нужно, теперь он работает на 100%, в ситуации заполнения он имеет (standard_in) 1: ошибка разбора, я думаю, что это не критическая ошибка bc. - person kostya572; 28.12.2017