我正在使用 Spleeter从音频中删除音乐。
我的目标是构建一个脚本,使从视频中提取音频的过程自动化,在提取的音频上执行 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
一切正常,直到必须将音频连接在一起。 Spleeter 将结果输出到 声乐.wav & 伴奏.wav 在与已处理音频命名相同的子文件夹中。
文件树如下所示:
output_vocal
- output_000
----- vocal.wav
----- accompaniment.wav
- output_001
----- vocal.wav
----- accompaniment.wav
- output_002
----- vocal.wav
----- accompaniment.wav
如您所见,问题在于命名。我的目标是连接所有 声乐.wav 成一个 mp3 音频。
然后合并最终的人声.mp3 的音频*.mp4 视频。
唯一的问题是围绕 Spleeter 输出结果音频的方式。
最佳答案
您遇到的问题是 ffmpeg 的 concat
demuxer 需要一个包含指令的输入文件,而不是一个简单的文件列表。
您的 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
不一定按字母顺序返回文件,而您很可能希望按该顺序连接文件。最后,在连接 WAV 文件时,不能使用
copy
编解码器生成 MP3 文件(因为 WAV/RIFF 编解码器不是 MP3)。但无论如何您都不需要中间 MP3 文件这是一个更新的脚本,
- 为所有中间文件使用临时目录
- 遍历 cmdline 提供的所有 mp4 文件(而不是硬编码输入目录)
- 为每个输入文件“XXX.mp4”创建一个“XXX_voc.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
关于linux - 提取音频,再次操作和合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59840282/