-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 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
Result: https://www.youtube.com/watch?v=HG7c7lldhM4 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渲染到文件? https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292
观察视频对图像序列的压缩程度比 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 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 上的两个演示:
- https://www.youtube.com/watch?v=grV64VE1U6c https://www.youtube.com/watch?v=grV64VE1U6c
- https://www.youtube.com/watch?v=_6D05gCWh_I https://www.youtube.com/watch?v=_6D05gCWh_I
做一个嬉皮士并使用OGG 容器中的 Theora 不受专利限制的视频格式 https://video.stackexchange.com/questions/14694/mp4-h-264-patent-issues:
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
or nomacs https://unix.stackexchange.com/questions/25978/image-viewer-for-multiple-images/539333#539333事先,这样 ffmpeg 就不必做出艰难的决定。特别是,宽度必须能被 2 整除,否则转换失败并显示:“宽度不能被 2 整除”。
完整的真实幻灯片案例研究设置一步一步
创建幻灯片比运行单个 ffmpeg 命令要复杂一些,所以这里有一个更有趣的详细示例受到这个时间线的启发 https://en.wikipedia.org/wiki/Human_evolution#History_of_study.
获取输入媒体:
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
输出并将宽度和高度减少一):
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,然后将所有其他图像转换为该精确大小,从而打破了它们的宽高比。
现在让我们通过裁剪将图像自动转换为目标 480p 宽高比ImageMagick:如何将图像最小化到特定的宽高比? https://stackoverflow.com/questions/21262466/imagemagick-how-to-minimally-crop-an-image-to-a-certain-aspect-ratio
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
所以现在,纵横比很好,但不可避免地需要进行一些裁剪,即剪切图像中有趣的部分。
另一种选择是用黑色背景填充以具有相同的纵横比,如下所示:调整大小以适合盒子,并将“空”部分的背景设置为黑色 https://stackoverflow.com/questions/18514083/resize-to-fit-in-a-box-and-set-background-to-black-on-empty-part/18514327
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 '*'
fails: https://trac.ffmpeg.org/ticket/3620 https://trac.ffmpeg.org/ticket/3620(显然是因为文件类型是从扩展名推导出来的)。
-r 30
使得-framerate 1
视频 30 FPS,以克服 VLC 等播放器中低帧率的错误:使用 ffmpeg 从图像创建的低 1 FPS 视频时 VLC 冻结 https://stackoverflow.com/questions/19267443/playback-issues-in-vlc-with-low-fps-video-from-images-using-ffmpeg/41797724#41797724因此,它会重复每帧 30 次,以保持所需的每秒 1 个图像的效果。
下一步
您还需要:
-
在加入之前剪切您想要的音频部分:使用ffmpeg根据开始和结束时间切割视频 https://stackoverflow.com/questions/18444194/cutting-the-videos-based-on-start-and-end-time-using-ffmpeg
ffmpeg -i in.mp3 -ss 03:10 -to 03:30 -c copy out.mp3
或者,您也可以直接在转换命令中添加-ss
就在音频之前-i
:
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:学习在没有中间文件的情况下将多个音频文件剪切并连接到视频中,我很确定这是可能的:
- ffmpeg 剪切和连接单个命令行 https://stackoverflow.com/questions/42250223/ffmpeg-cut-and-concat-single-command-line
- https://video.stackexchange.com/questions/21315/concatenating-split-media-files-using-concat-protocol https://video.stackexchange.com/questions/21315/concatenating-split-media-files-using-concat-protocol
- https://superuser.com/questions/587511/concatenate-multiple-wav-files-using-single-command-without-extra-file https://superuser.com/questions/587511/concatenate-multiple-wav-files-using-single-command-without-extra-file
每张图像的持续时间不同
https://video.stackexchange.com/questions/23530/use-ffmpeg-to-create-a-video-from-a-few-images https://video.stackexchange.com/questions/23530/use-ffmpeg-to-create-a-video-from-a-few-images给出了一个解决方案。
你创建一个文件in.txt
like:
file png/1.png
outpoint 5
file png/2.png
outpoint 2
file png/3.png
outpoint 7
and 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
and 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。
参考书目
-
http://trac.ffmpeg.org/wiki/Slideshow http://trac.ffmpeg.org/wiki/Slideshow官方维基