Извлечение АУДИО, манипулирование и объединение снова - PullRequest
0 голосов
/ 21 января 2020

Я использую Spleeter , чтобы удалить musi c из aud ios.

Моя цель - создать скрипт, который автоматизирует процесс извлечения аудио из видео, запускает Spleeter для извлеченного аудио и затем объединяет манипулированный звук обратно в видео, заменяя исходный.

Основная проблема, с которой я столкнулся, заключается в том, что мне не хватает оперативной памяти для обработки всего извлеченного аудио. Мне нужно разбить его на несколько частей и выполнить Spleeter для каждого фрагмента.

Затем объединить обработанные фрагменты вместе и объединить результат с видео.

Вот что я пробовал:

#!/bin/bash

cd ~/Desktop/Video-convert

# create audio from video
ffmpeg -i *.mp4 output.mp3

# Split the audio into pieces
ffmpeg -i output.mp3 -f segment -segment_time 120 -c copy output_%03d.mp3


# Execute Spleeter upon each sample
FILES=~/Desktop/Video-convert/*.mp3

for f in $FILES
do
  spleeter separate -i $f -o output_vocal
done

# delete unneeded audios
rm *.mp3
cd output_vocal

# ===========================================================
# the problem starts here
# ===========================================================

# concatenate manipulated audios together
find . -name 'vocals.wav' -exec echo {} >> mylist.txt \;

ffmpeg -f concat -safe 0 -i mylist.txt -c copy vocal.mp3

mv vocal.mp3 ../

cd ../

# merge the audio back to video
ffmpeg -i *.mp4 -i vocal.mp3 \
-c:v copy -c:a aac -strict experimental \
-map 0:v:0 -map 1:a:0 vocal-vid.mp4

Все работает хорошо до тех пор, пока не придется объединить Aud ios вместе. Spleeter выводит результат в vocal.wav & сопровождение.wav в подпапке, имя которой совпадает с аудио, которое было обработано.

Дерево файлов выглядит следующим образом:

output_vocal
- output_000
----- vocal.wav
----- accompaniment.wav
- output_001
----- vocal.wav
----- accompaniment.wav
- output_002
----- vocal.wav
----- accompaniment.wav

Как видите, проблема заключается в наименовании. Моя цель - объединить все vocal.wav в один аудиофайл в формате mp3.

А затем объедините окончательное vocal.mp3 аудио с видео *. Mp4 .

Единственная проблема заключается в способе вывода Spleeter результат ауд ios.

1 Ответ

1 голос
/ 21 января 2020

Проблема, с которой вы сталкиваетесь, заключается в том, что concat демпфер ffmpeg требует входной файл, содержащий директивы, а не простой список файлов.

Ваш вызов find создает файл, подобный:

output_vocal/output_000/vocal.wav
output_vocal/output_001/vocal.wav
output_vocal/output_002/vocal.wav

, в то время как ffmpeg concat demuxer действительно требует такой файл, как:

file output_vocal/output_000/vocal.wav
file output_vocal/output_001/vocal.wav
file output_vocal/output_002/vocal.wav

Также обратите внимание, что find не обязательно возвращает файлы в алфавитном порядке c, тогда как большинство скорее всего, вы захотите объединить файлы в таком порядке.

Наконец, при объединении WAV-файлов вы не можете использовать copy код c для создания файла MP3 (поскольку код WAV / RIFF * 1022) * это не MP3). но вам все равно не нужен промежуточный MP3-файл

Вот обновленный скрипт, который - использует временный каталог для всех промежуточных файлов - перебирает все mp4-файлы, представленные на cmdline (вместо жесткого ввода каталог) - создает файл «XXX_vo c .mp4» для каждого входного файла «XXX.mp4» (перезаписывая любые существующие файлы)

#!/bin/bash

for infile in "$@"
do
  outfile=${infile%.mp4}_voc.mp4

  # create a temp-directory to put our stuff to
  TMPDIR=$(mktemp -d)

  # create audio from video
  ffmpeg -i "${infile}" "${TMPDIR}/output.mp3"

  # Split the audio into pieces
  ffmpeg -i "${TMPDIR}/output.mp3" -f segment -segment_time 120 -c copy "${TMPDIR}/output_%03d.mp3"

  # Execute Spleeter upon each sample
  find "${TMPDIR}" -maxdepth 1 -type f -name "output_*.mp3" \
    -exec spleeter separate -i {} -o "${TMPDIR}/output_vocal" ";"

  # find all 'vocal.wav' files generated by spleeter, sort them, 
  # prefix them with 'file ', and put them into output.txt
  find "${TMPDIR}/output_vocal" -type f -name "vocal.wav" -print0 \
  | sort -z \
  | xargs -0 -I{} echo "file '{}'" \
  > "${TMPDIR}/output.txt"
  # concatenate the files and create an MP3 file
  ffmpeg -f concat -safe 0 -i "${TMPDIR}/output.txt" -c copy "${TMPDIR}/vocal.wav"

  # merge the audio back to video
  ffmpeg -y -i "${infile}" -i "${TMPDIR}/vocal.wav" \
    -c:v copy -c:a aac -strict experimental \
    -map 0:v:0 -map 1:a:0 "${outfile}"

  rm -rf "${TMPDIR}"
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...