-pattern_type glob
这个很好的选项在许多情况下使选择图像变得更加容易。
以30 FPS每帧只有一个图像的正常速度视频
ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
-c:v libx264 -pix_fmt yuv420p out.mp4
这是它的外观:
使用以下命令生成GIF:https://askubuntu.com/questions/648603/how-to-create-an-animated-gif-from-mp4-video-via-command-line/837574#837574
为其添加一些音频:
ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
-i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4
结果: https://www.youtube.com/watch?v=HG7c7lldhM4
这些是我使用的测试媒体:
wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true
unzip opengl-rotating-triangle.zip
cd opengl-rotating-triangle
wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg
使用以下方式生成的图像:如何使用GLUT / OpenGL渲染到文件?
观察到视频在专门的算法帮助下跨帧压缩,比ZIP压缩图像序列要好得多:
opengl-rotating-triangle.mp4
:340K
opengl-rotating-triangle.zip
:7.3M
将一个音乐文件转换为固定图像的视频,以用于上传到YouTube
答案位于:https://superuser.com/questions/700419/how-to-convert-mp3-to-youtube-allowed-video-format/1472572#1472572
每秒钟播放一张图片的幻灯片视频
ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
-c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
加入一些音乐,当图像结束时,停止较长的音频:
ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
-c:a copy -shortest -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
这里有两个YouTube演示:
成为嬉皮士,使用Theora专利未受限制的视频格式,存储在OGG容器中:
ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
-c:a copy -shortest -c:v libtheora -r 30 -pix_fmt yuv420p out.ogv
您的图片应按字母顺序排序,通常为:
0001-first-thing.jpg
0002-second-thing.jpg
0003-and-third.jpg
等等其他内容。
我首先会确保所有要使用的图像具有相同的纵横比,可能通过使用imagemagick
或nomacs进行裁剪,以便ffmpeg不必做出艰难的决定。特别是,宽度必须可以被2整除,否则转换将失败并显示“宽度不能被2整除”。
逐步设置完整现实幻灯片案例研究
创建幻灯片秀需要的步骤比运行单个ffmpeg命令多一些,因此这里提供了一个更详细、更有趣的例子,受到这个时间线的启发。
获取输入媒体:
mkdir -p orig
cd orig
wget -O 1.png https://upload.wikimedia.org/wikipedia/commons/2/22/Australopithecus_afarensis.png
wget -O 2.jpg https://upload.wikimedia.org/wikipedia/commons/6/61/Homo_habilis-2.JPG
wget -O 3.jpg https://upload.wikimedia.org/wikipedia/commons/c/cb/Homo_erectus_new.JPG
wget -O 4.png https://upload.wikimedia.org/wikipedia/commons/1/1f/Homo_heidelbergensis_-_forensic_facial_reconstruction-crop.png
wget -O 5.jpg https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Sabaa_Nissan_Militiaman.jpg/450px-Sabaa_Nissan_Militiaman.jpg
wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg
cd ..
# Convert all to PNG for consistency.
# https://unix.stackexchange.com/questions/29869/converting-multiple-image-files-from-jpeg-to-pdf-format
# Hardlink the ones that are already PNG.
mkdir -p png
mogrify -format png -path png orig/*.jpg
ln -P orig/*.png png
现在我们快速查看所有图像大小,以决定最终的纵横比:
identify png/*
输出结果为:
png/1.png PNG 557x495 557x495+0+0 8-bit sRGB 653KB 0.000u 0:00.000
png/2.png PNG 664x800 664x800+0+0 8-bit sRGB 853KB 0.000u 0:00.000
png/3.png PNG 544x680 544x680+0+0 8-bit sRGB 442KB 0.000u 0:00.000
png/4.png PNG 207x238 207x238+0+0 8-bit sRGB 76.8KB 0.000u 0:00.000
png/5.png PNG 450x600 450x600+0+0 8-bit sRGB 627KB 0.000u 0:00.000
因此,经典的480p(640x480 == 4/3)宽高比看起来比较合适。
进行一次最小的转换以使宽度变为偶数(TODO自动化任何宽度的转换,在这里我只是手动查看了identify
输出并将宽度和高度减小了1):
mkdir -p raw
convert png/1.png -resize 556x494 raw/1.png
ln -P png/2.png png/3.png png/4.png png/5.png raw
ffmpeg -framerate 1 -pattern_type glob -i 'raw/*.png' -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p raw.mp4
这会产生糟糕的输出,因为从下面可以看到:
ffprobe raw.mp4
ffmpeg会直接采用第一张图片的尺寸,即556x494,并将其它所有图片转换为该精确尺寸,破坏它们的宽高比。
现在,我们可以通过像ImageMagick: how to minimally crop an image to a certain aspect ratio?中所述的自动裁剪方法将图像转换为目标480p宽高比。
mkdir -p auto
mogrify -path auto -geometry 640x480^ -gravity center -crop 640x480+0+0 png/*.png
ffmpeg -framerate 1 -pattern_type glob -i 'auto/*.png' -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p auto.mp4
现在,纵横比例很好,但不可避免地需要进行一些裁剪,这样就切掉了图像的一些有趣部分。
另一个选择是用黑色背景填充,以获得与此处所示相同的纵横比,如:Resize to fit in a box and set background to black on "empty" part
mkdir -p black
mogrify -path black -thumbnail 640x480 -background black -gravity center -extent 640x480 png/*.png
ffmpeg -framerate 1 -pattern_type glob -i 'black/*.png' -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p black.mp4
一般来说,最好能选择相同或类似纵横比的图像,以避免出现这些问题。
关于CLI选项
请注意,尽管名为-glob
,但这不像shell Glob模式那样通用,例如:-i '*'
会失败:https://trac.ffmpeg.org/ticket/3620(显然是因为文件类型由扩展名推断出来)。
-r 30
使-framerate 1
视频成为每秒30帧,以解决像VLC这样播放器在低帧率下的故障: 使用ffmpeg从图像创建低1 FPS视频时,VLC冻结 因此,它会将每个帧重复30次,以保持所需的每秒1张图片的效果。
下一步操作
您还需要:
ffmpeg -i in.mp3 -ss 03:10 -to 03:30 -c copy out.mp3
或者,您还可以通过在音频-i
之前添加-ss
来直接在转换命令中剪切它:
ffmpeg -framerate 1 -pattern_type glob -i 'raw/*.png' -ss 0:36 -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p raw.mp4
TODO: 学习如何将多个音频文件剪切和拼接到视频中,而不需要中间文件。我相信这是可能的:
每张图片的持续时间不同
https://video.stackexchange.com/questions/23530/use-ffmpeg-to-create-a-video-from-a-few-images 提供了一种解决方案。
您可以创建一个名为in.txt
的文件,内容如下:
file png/1.png
outpoint 5
file png/2.png
outpoint 2
file png/3.png
outpoint 7
outpoint
设置前一图像的持续时间(以秒为单位)。
然后,我们只需从先前的转换命令中移除 -framerate
:
ffmpeg -f concat -i in.txt -framerate 1 -i orig/audio.ogg -c:v libx264 -c:a copy -shortest -r 30 -pix_fmt yuv420p black.mp4
我也喜欢文件名在一个文件中的这种方法,比重新命名输入文件以获得正确的顺序更好,这使得在文本编辑器中快速重新排序图像变得更容易(多个-i
无法工作)。每个输入文件有两行会使这个过程有点更麻烦,我没有成功将file
和outpoint
组合成一行,但还是很好知道。
如果你只想转换图像的子集,则这种方法也很方便。然后,为了节省ImageMagick的时间,您可以重复使用in.txt
文件,仅循环处理您关心的图像:
grep -E '^file ' in.txt | sed -E 's/^file //; s/\..*//' | while read f; do
echo $f
convert -thumbnail 1280x720 -background black -gravity center -extent 1280x720 "$(command ls -1 ../$f.* | grep -v .xcf | head -n1)" "out/$f.jpg"
done
测试环境
ffmpeg 3.4.4,vlc 3.0.3,Ubuntu 18.04。
参考文献
ffmpeg -loop 1 -i input.jpg -c:v libx264 -t 10 output.mp4
其中,input.jpg
是输入图片的路径,-loop 1
表示循环播放该图片,-c:v libx264
表示以H.264编解码格式输出视频,-t 10
表示输出视频的时长为10秒,output.mp4
则是输出视频的文件名和格式。 - barlop