ffmpeg 遇到一个问题 公司有一个需求,图片(图片要可以左右移动,图片是多张,图片要可以指定播放时长,例如:第一张图片播放时长3秒 第二张图片播放2秒 第三张x秒), 音频,合成mp4视频有会的吗?写ffmpeg 命令就可以了?
引用gpt作答:
使用ffmpeg可以将多张图片合成为一个视频,同时添加音频和字幕。
以下是一个示例命令,其中包括将图片合成为视频、添加音频和字幕、调整图片位置和指定每张图片的播放时长:
ffmpeg -y \
-loop 1 \
-i image1.png \
-loop 1 \
-i image2.png \
-filter_complex \
"[0:v]scale=w=1280:h=720,setsar=1[v0]; \
[1:v]scale=w=1280:h=720,setsar=1[v1]; \
[v0][v1]hstack=inputs=2[v]" \
-map "[v]" \
-t 10 \
-vf "drawtext=text='Your Subtitle':fontfile=/path/to/font.ttf:fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2" \
-i audio.mp3 \
-shortest \
output.mp4
这个命令将图片 image1.png 和 image2.png 合成为一个视频,图片会水平拼接在一起。 -filter_complex 参数中的 setsar 参数用于设置像素比例,以避免图像变形。 -t 参数用于设置视频的持续时间,这里设置为10秒。 -vf 参数用于添加字幕,你需要将其中的 text、fontfile、fontsize 和 fontcolor 等参数替换成你想要的字幕内容和样式。 -i 参数用于添加音频, -shortest 参数用于将音频的持续时间设置为视频的持续时间。最后的输出文件为 output.mp4。
如果你需要调整图片的位置,可以在 -filter_complex 参数中添加 x 和 y 参数,以指定图片的位置。例如,如果你想将第一张图片向左移动100个像素,可以将 -filter_complex 参数修改为:
-filter_complex \
"[0:v]scale=w=1280:h=720,setsar=1,x=100[v0]; \
[1:v]scale=w=1280:h=720,setsar=1[v1]; \
[v0][v1]hstack=inputs=2[v]"
其中的 x 参数设置为 100。你可以根据需要修改这些参数。
基于new Bing和ChatGPT的回答:
如果图片是多张的,可以考虑将多张图片合成一个视频流,然后再和音频、字幕合并成一个完整的视频。以下是一个可能的解决方案:
ffmpeg -framerate 25 -i image_%03d.png -c:v libx264 -pix_fmt yuv420p -crf 23 output.mp4
这个命令中,“-framerate 25”表示每秒播放25帧图片,“-i image_%03d.png”表示输入的图片文件名格式,“-c:v libx264”表示视频编码器使用libx264,“-pix_fmt yuv420p”表示像素格式使用yuv420p,“-crf 23”表示视频质量,23表示压缩比例,值越小,视频质量越高。最后的“output.mp4”表示输出的视频文件名。
ffmpeg -i output.mp4 -i audio.mp3 -i subtitle.srt -map 0:v -map 1:a -map 2:s -c:v copy -c:a copy -c:s mov_text -metadata:s:s:0 language=eng output_with_audio_and_subtitle.mp4
这个命令中,“-i output.mp4”表示输入的视频文件名,“-i audio.mp3”表示输入的音频文件名,“-i subtitle.srt”表示输入的字幕文件名,“-map 0:v -map 1:a -map 2:s”表示将输入的视频、音频、字幕按顺序映射到输出文件中,“-c:v copy”表示视频编码器不做改变,直接复制到输出文件,“-c:a copy”表示音频编码器不做改变,直接复制到输出文件,“-c:s mov_text”表示字幕编码器使用mov_text格式,“-metadata:s:s:0 language=eng”表示指定字幕的语言为英文。最后的“output_with_audio_and_subtitle.mp4”表示输出的带音频和字幕的视频文件名。
ffmpeg -i output_with_audio_and_subtitle.mp4 -t 30 output_with_audio_and_subtitle_30s.mp4
这个命令中,“-i output_with_audio_and_subtitle.mp4”表示输入的带音频和字幕的视频文件名,“-t 30”表示视频的播放时长为30秒。最后的“output_with_audio_and_subtitle_30s.mp4”表示输出的指定时长的视频文件名。
综合起来,可以将上述命令组合成一个完整的命令,如下:
ffmpeg -framerate 25 -i image_%03d.png -c:v libx264 -pix_fmt yuv420p -crf 23 -i audio.mp3 -i subtitle.srt -map 0:v -map
引用chatGPT作答,以下是使用 ffmpeg 合成视频的代码示例:
ffmpeg -y \
-loop 1 -t 5 -i image1.jpg \
-loop 1 -t 5 -i image2.jpg \
-filter_complex "[0:v]trim=0:5,setpts=PTS-STARTPTS,overlay=x='if(gte(t,2), -w+(t-2)*200, NAN)':y=0,format=yuv420p[v1]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS,overlay=x='if(gte(t,2), -w+(t-2)*200, NAN)':y=0,format=yuv420p[v2]; \
[v1][v2]concat=n=2:v=1:a=0,format=yuv420p[v]" \
-i audio.mp3 \
-map "[v]" -map 2:a \
-t 10 \
-subtitle subtitle.srt \
-c:v libx264 -c:a aac -strict -2 -b:a 192k -pix_fmt yuv420p output.mp4
这个命令使用了 image1.jpg 和 image2.jpg 两张图片,图片播放时长都是 5 秒,可以通过 -t 参数进行指定,以及一个音频文件 audio.mp3 和一个字幕文件 subtitle.srt。
对于图片的左右移动,我们使用 overlay filter 实现,具体来说是使用 if(gte(t,2), -w+(t-2)*200, NAN) 这个表达式来计算图片的 x 坐标,这个表达式的意思是,当时间大于等于 2 秒时,图片的 x 坐标从 -w 开始,每秒向右移动 200 个像素。这里的 -w 表示图片的宽度,是一个动态计算的值,因为我们不知道图片的宽度是多少,需要使用 ffmpeg 运行时计算。
最后,我们使用 -c:v libx264 和 -c:a aac 来分别指定视频和音频的编码器,以及 -b:a 192k 来指定音频的码率。
需要注意的是,这个命令中的一些参数需要根据实际情况进行调整,比如图片的路径、播放时长、字幕的路径等。
以下内容部分参考ChatGPT模型:
好的,以下是一个例子,可以将多张图片和一个音频文件合成一个mp4视频:
import subprocess
# 设置图片文件名列表和对应的播放时长
image_files = ['image1.jpg', 'image2.jpg', 'image3.jpg']
image_durations = ['3', '2', '5']
# 设置音频文件名和起始时间
audio_file = 'audio.mp3'
audio_start_time = '00:00:02'
# 设置输出视频文件名
output_file = 'output.mp4'
# 构造ffmpeg命令
command = ['ffmpeg']
for i, file in enumerate(image_files):
# 添加图片输入参数
command += ['-loop', '1', '-t', image_durations[i], '-i', file]
for i in range(len(image_files)):
# 添加图片拼接参数
command += ['-t', image_durations[i], '-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-vf', 'scale=trunc(iw/2)*2:trunc(ih/2)*2']
if audio_file:
# 添加音频输入参数
command += ['-ss', audio_start_time, '-i', audio_file]
# 添加音频拼接参数
command += ['-c:a', 'copy']
# 添加输出参数
command += ['-y', output_file]
# 执行ffmpeg命令
subprocess.run(command)
其中,image_files
和image_durations
分别存储了图片文件名和对应的播放时长,audio_file
存储了音频文件名,audio_start_time
存储了音频起始时间,output_file
存储了输出视频文件名。
在构造ffmpeg命令时,首先使用-loop
参数指定每张图片循环播放,然后使用-t
参数指定每张图片的播放时长,使用-c:v
和-pix_fmt
参数指定视频编码器和像素格式,使用-vf
参数指定视频滤镜,这里使用了scale
滤镜将图片的宽高调整为偶数,以避免编码器报错。如果有音频文件,则使用-ss
参数指定音频起始时间,使用-c:a
参数指定音频编码器,并使用copy
选项表示直接复制原始音频数据,以避免重新编码导致的质量损失。
最后,使用subprocess.run()
函数执行ffmpeg命令即可。
bash
ffmpeg -loop 1 -i image.jpg -i audio.mp3 -vf "drawtext=fontfile=font.ttf:textfile=sub.srt:y=h-line_h:x=10:fontcolor=white:fontsize=24" -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest output.mp4