我正在尝试将音频文件与视频文件合并。
我有两个选项:
使用非常小的视频文件(例如10秒)循环播放,直到音频文件结束。
使用非常长的视频文件(比任何音频文件都要长),在其中附加音频文件。我想在音频完成后剪辑视频。
我正在使用后者,并使用 ffmpeg 的 -t <持续时间(秒)>
选项。这意味着我必须获取音频文件的持续时间并将其提供给 ffmpeg。有没有可能避免这一步?
有关第一个解决方案的任何指针?
如果你想将新的音频与视频合并,让视频重复播放直到音频结束,你可以尝试以下方法:
ffmpeg -stream_loop -1 -i input.mp4 -i input.mp3 -shortest -map 0:v:0 -map 1:a:0 -y out.mp4
使用-stream_loop -1意味着无限循环输入视频input.mp4,-shortest意味着在最短的输入流结束时完成编码。这里最短的输入流将是input.mp3。
如果您想将新音频与视频合并,并重复音频直到视频结束,您可以尝试以下方法:
ffmpeg -i input.mp4 -stream_loop -1 -i input.mp3 -shortest -map 0:v:0 -map 1:a:0 -y out.mp4
使用 -y 选项将在不询问的情况下覆盖输出文件。
ffprobe
计算两个文件的持续时间,并计算需要播放视频循环的次数以匹配音频的持续时间。ffprobe -i input_media -show_entries format=duration -v quiet -of csv="p=0"
ffmpeg -i input_audio -f concat -i <(for i in {1..n}; do printf "file '%s'\n" input_video; done) -c:v copy -c:a copy -shortest output_video
1..n
代表需要循环播放视频的次数。您可以使用-t
而不是-shortest
,因为您已经计算出音频的持续时间。
以下是相关的shell脚本。
#!/bin/bash
audio_duration=$(ffprobe -i ${1} -show_entries format=duration -v quiet -of csv="p=0")
video_duration=$(ffprobe -i ${2} -show_entries format=duration -v quiet -of csv="p=0")
n_loops=$(echo "(${audio_duration} / ${video_duration}) + 1"|bc)
ffmpeg -i ${1} -f concat -i <(for i in {1..${n_loops}}; do printf "file '%s'\n" ${2}; done) -c:v copy -c:a copy -shortest ${3}
对于Windows系统,您可以将此shell脚本转换为批处理脚本。
更多信息:
希望这可以帮助您!
对于第一个问题,可以尝试使用 ffmpeg -i yourmovie.mp4 -loop 10
命令将输入循环播放10次。
-map 0:v:0 -map 1:a:0
已经完成了它的工作。它将只从第一个-i
中获取视频,只从第二个-i
中获取音频,无论你的第二个输入是视频文件还是音频文件。 - Ninh Pham