首先要计算出视频的总帧数:
总帧数 = duration * fps 。
duration是我们设定的视频的长度,fps是视频每秒的帧数。
第二步将所有的图片文件放到一个临时目录,并且制定一个命名规则(可正则的):
例如图片的素材是image0.jpg image1.jpg image2.jpg
然后可以执行命令合成视频了:
带音频:
ffmpeg -threads2 -y -r 10 -i /tmpdir/image%04d.jpg -i audio.mp3 -absf aac_adtstoasc output.mp4
1
参数的解释含义:
-threads 2 以两个线程进行运行, 加快处理的速度。
-y 对输出文件进行覆盖
-r 10 fps设置为10帧/秒(不同位置有不同含义,后面再解释)
-i /tmpdir/image%04d.jpg 输入图片文件,图片文件保存为 image0001.jpg image0002.jpg ….
-i audio.mp3 输入的音频文件
-absf aac_adtstoasc 将结果的音频格式转为faac格式时需要这个选项。将音频格式转为faac是因为在iphone上某些音频格式的视频无法播放,例如mp3. 但faac格式的音频的视频在iphone上可以播放。-absf 的意思是设置一个bitstream filter进行某些转换。可以用ffmpeg -bsfs 查看所有支持的bitstream filter。 bitstream filter和 aac_adtstoasc的具体含义我也说不上。但是如果不用这个选项又会导致转换失败。
不带音频
ffmpeg -loop 1 -f image2 -i /tmpdir/image%04d.jpg -vcodec libx264 -r 10 -t 10 test.mp4
1
-loop 1循环读输入 0读完就不读了
-vcode 编码格式libx264
-b 指定200k码率
-t 输出视频总时长:
这样运行命令就可以生成视频了;
从不同目录下多张图合成视频
上面命令需要从指定文件夹下的特殊命名规则的一组图中去做输入文件;有没有更好的方式呢?比如我有一些图片的存储路径,能不能不拷贝到一个文件夹下再操作,答案是有的。
1. 使用管道Pipe
2. 使用Concat命令
Pipe
You can use cat or other tools to pipe to ffmpeg:
cat读取多张图片输入到一个“全局管道文件”中,然后后面ffmpeg命令从全局管道中(指定-f image2pipe)读取输入文件,生成视频。
cat Desktop/aa/img1.jpg Desktop/aa/img2.jpg Desktop/aa/img3.jpg | ffmpeg -loop 0 -f image2pipe -r 3 -b 200k -s 640*360 -t 12 -i log.pipe -y Desktop/oup.mkv
1
这个命令在linux、Mac OS、Windows上都是可行的,但是在安卓中不行,可能是ffmpeg找不到那个“全局管道”。
那么我们可以自己创建一个管道,然后告诉ffmpeg管道在哪?
创建管道:
mkfifo Desktop/pic.pipe
1
向管道输入文件:
cat Desktop/aa/img1.jpg Desktop/aa/img2.jpg > Desktop/pic.pipe
1
使用ffmpeg读取管道,生成视频:
ffmpeg -loop 0 -f image2pipe -r 3 -b 200k -s 640*360 -t 12 -i Desktop/pic.pipe -y Desktop/oup.mp4
1
这里pic.pipe的路径子安安卓上要换成安卓的路径:Environment.getExternalStorageDirectory().getAbsolutePath()下面
管道文件非常,非常强大,更多管道知识:
【Linux】mkfifo命令创建命名管道实现进程之间通信
【Linux】进程间通信-命名管道FIFO
Concat
首先,创建个input.txt文件,填写图片信息:
file 文件路径
duration 这张图播放时长
file '/Users/wangshuainan/Desktop/aa/imga.jpg'
duration 5
file '/Users/wangshuainan/Desktop/aa/imgb.jpg'
duration 1
file '/Users/wangshuainan/Desktop/aa/imgc.jpg'
duration 3
file '/Users/wangshuainan/Desktop/aa/imgc.jpg'
注意!!! 最后一个图要重复写一遍,但不用加duration。
然后run ffmpeg command:
ffmpeg -f concat -safe 0 -i Desktop/input.txt -vsync vfr -pix_fmt yuv420p Desktop/output.mp4
1
这里命令里要加上-safe 0,不然会报unsafe file name的error,不要问我怎么知道的。
参考:
https://trac.ffmpeg.org/wiki/Slideshow
容易误解的几个命令:
下面解释下几个特殊命令的特殊含义:
-t duration
用做输入选项(在-i之前),是限制读取输入文件的的时长;
用做输出选项(before an output url),超过这个时间停止写输出文件;
比如:循环读取一个输入文件时(-loop 1),当到时间就会停止输出,生成一个duration时长的视频。但是如果没有循环选项,而且输入文件短于这个时长时,就会随着输入文件结束就结束,生成视频,视频时长小于duration。所以我们可以看出 -t 并不仅仅是输出文件时长。
当用“管道”时,也不太一样,管道读了之后,里面内容就没了,所以没持续的输入,这个-loop,-t 都是“不起作用的”,除非管道一直有内容。
-t duration (input/output)
When used as an input option (before -i), limit the duration of data read from the input file.
When used as an output option (before an output url), stop writing the output after its duration reaches duration.
duration must be a time duration specification, see (ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual.
-to and -t are mutually exclusive and -t has priority.
-r fps
帧率,可以指定两个帧率,输入帧率,输出帧率;
输入帧率:-i之前,设定读入帧率,比如 -r 0.5 ,也就是说1秒要播0.5个图片,那么一个图也就是要播2s;
输出频率:-i之后,真正的输出视频播放帧率,不写话,是默认和输入频率一样。比如设 -r 30 ,对应上面的设定,一个图播2
s,那么输出文件播放时,这2s内,都是这张图,但是播放了60帧。
You can specify two frame rates: input and output.
Set input frame rate with the -framerate input option (before -i). The default for reading inputs is -framerate 25 which will be setif no -framerate is specified.
The output frame rate for the video stream by setting -r after -i or by using the fps filter. If you want the input and output frame rates to be the same, then just declare an input -framerate and the output will inherit the same value (meaning you can omit the -r).
By using a separate frame rate for the input and output you can control the duration at which each input is displayed and tell ffmpeg the frame rate you want for the output file. This is useful if your player cannot handle a non-standard frame rate. If the input -framerate is lower than the output -r then ffmpeg will duplicate frames to reach your desired output frame rate. If the input -framerate is higher than the output -r then ffmpeg will drop frames to reach your desired output frame rate.
In this example each image will have a duration of 5 seconds (the inverse of 1/5 frames per second). The video stream will have a frame rate of 30 fps by duplicating the frames accordingly:
ffmpeg -framerate 1/5 -i img%03d.png -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
1
参考:
FFmpeg官网:
http://ffmpeg.org/ffmpeg.html
https://trac.ffmpeg.org/wiki/Slidesh
四、linux 下多个图片合并,FFmpeg将多张图片合成视频
cat Z000*.jpg | ffmpeg -r 3 -t 12 -i pipe:0 -y -b 200K out.mp4
FFmpeg将多张图片合成视频
首先要计算出视频的总帧数:
总帧数 = duration * fps 。
duration是我们设定的视频的长度,fps是视频每秒的帧数。
第二步将所有的图片文件放到一个临时目录,并且制定一个命名规则(可正则的):
例如图片的素材是image0.jpg image1.jpg image2.jpg
然后可以执行命令合成视频了:
带音频:
点击(此处)折叠或打开
ffmpeg -threads2 -y -r 10 -i /tmpdir/image%04d.jpg -i audio.mp3 -absf aac_adtstoasc output.mp4
参数的解释含义:
-threads 2 以两个线程进行运行, 加快处理的速度。
-y 对输出文件进行覆盖
-r 10 fps设置为10帧/秒(不同位置有不同含义,后面再解释)
-i /tmpdir/image%04d.jpg 输入图片文件,图片文件保存为 image0001.jpg image0002.jpg ….
-i audio.mp3 输入的音频文件
-absf aac_adtstoasc 将结果的音频格式转为faac格式时需要这个选项。将音频格式转为faac是因为在iphone上某些音频格式的视频无法播放,例如mp3. 但faac格式的音频的视频在iphone上可以播放。-absf 的意思是设置一个bitstream filter进行某些转换。可以用ffmpeg -bsfs 查看所有支持的bitstream filter。 bitstream filter和 aac_adtstoasc的具体含义我也说不上。但是如果不用这个选项又会导致转换失败。
不带音频
点击(此处)折叠或打开
ffmpeg -loop1 -f image2 -i /tmpdir/image%04d.jpg -vcodec libx264 -r 10 -t 10 test.mp4
-loop1循环读输入 0读完就不读了
-vcode 编码格式libx264
-b 指定200k码率
-t 输出视频总时长:
这样运行命令就可以生成视频了;
从不同目录下多张图合成视频
上面命令需要从指定文件夹下的特殊命名规则的一组图中去做输入文件;有没有更好的方式呢?比如我有一些图片的存储路径,能不能不拷贝到一个文件夹下再操作,答案是有的。
1. 使用管道Pipe
2. 使用Concat命令
Pipe
You can use cat or other tools to pipe to ffmpeg:
cat读取多张图片输入到一个“全局管道文件”中,然后后面ffmpeg命令从全局管道中(指定-f image2pipe)读取输入文件,生成视频。
点击(此处)折叠或打开
cat Desktop/aa/img1.jpg Desktop/aa/img2.jpg Desktop/aa/img3.jpg | ffmpeg -loop0 -f image2pipe -r 3 -b 200k -s 640*360 -t 12 -i log.pipe -y Desktop/oup.mkv
这个命令在linux、Mac OS、Windows上都是可行的,但是在安卓中不行,可能是ffmpeg找不到那个“全局管道”。
那么我们可以自己创建一个管道,然后告诉ffmpeg管道在哪?
点击(此处)折叠或打开
创建管道:
mkfifo Desktop/pic.pipe
1
向管道输入文件:
cat Desktop/aa/img1.jpg Desktop/aa/img2.jpg > Desktop/pic.pipe
1
使用ffmpeg读取管道,生成视频:
ffmpeg -loop0 -f image2pipe -r 3 -b 200k -s 640*360 -t 12 -i Desktop/pic.pipe -y Desktop/oup.mp4
1
这里pic.pipe的路径子安安卓上要换成安卓的路径:Environment.getExternalStorageDirectory().getAbsolutePath()下面
Concat
首先,创建个input.txt文件,填写图片信息:
点击(此处)折叠或打开
file 文件路径
duration 这张图播放时长
file '/Users/wangshuainan/Desktop/aa/imga.jpg'
duration 5
file '/Users/wangshuainan/Desktop/aa/imgb.jpg'
duration 1
file '/Users/wangshuainan/Desktop/aa/imgc.jpg'
duration 3
file '/Users/wangshuainan/Desktop/aa/imgc.jpg'
注意!!! 最后一个图要重复写一遍,但不用加duration。
然后run ffmpeg command:
点击(此处)折叠或打开
ffmpeg -f concat -safe 0 -i Desktop/input.txt -vsync vfr -pix_fmt yuv420p Desktop/output.mp4
容易误解的几个命令:
下面解释下几个特殊命令的特殊含义:
-t duration
用做输入选项(在-i之前),是限制读取输入文件的的时长;
用做输出选项(before an output url),超过这个时间停止写输出文件;
比如:循环读取一个输入文件时(-loop1),当到时间就会停止输出,生成一个duration时长的视频。但是如果没有循环选项,而且输入文件短于这个时长时,就会随着输入文件结束就结束,生成视频,视频时长小于duration。所以我们可以看出 -t 并不仅仅是输出文件时长。
当用“管道”时,也不太一样,管道读了之后,里面内容就没了,所以没持续的输入,这个-loop,-t 都是“不起作用的”,除非管道一直有内容。
-t duration (input/output)
When usedasaninput option (before-i), limitthedurationofdatareadfromtheinputfile.
When usedasanoutput option (beforeanoutput url), stop writingtheoutputafterits duration reaches duration.
duration must beatimeduration specification, see (ffmpeg-utils)theTime duration sectionintheffmpeg-utils(1) manual.
-toand-t are mutually exclusiveand-t has priority.
-r fps
帧率,可以指定两个帧率,输入帧率,输出帧率;
输入帧率:-i之前,设定读入帧率,比如 -r 0.5 ,也就是说1秒要播0.5个图片,那么一个图也就是要播2s;
输出频率:-i之后,真正的输出视频播放帧率,不写话,是默认和输入频率一样。比如设 -r 30 ,对应上面的设定,一个图播2
s,那么输出文件播放时,这2s内,都是这张图,但是播放了60帧。
You can specify two frame rates: input and output.
Set input frame rate with the -framerate input option (before -i). The defaultfor reading inputs is -framerate 25 which will be setif no -framerate is specified.
The output frame rate for the video stream by setting -r after -i orbyusing the fps filter. If you want the input and output frame rates to be the same, then just declare an input -framerate and the output will inherit the same value (meaning you can omit the -r).
Byusing a separate frame rate for the input and output you can control the duration at which each input is displayed and tell ffmpeg the frame rate you want for the output file. This is useful if your player cannot handle a non-standard frame rate. If the input -framerate is lower than the output -r then ffmpeg will duplicate frames to reach your desired output frame rate. If the input -framerate is higher than the output -r then ffmpeg will drop frames to reach your desired output frame rate.
In this example each image will have a duration of5 seconds (the inverse of1/5 frames per second). The video stream will have a frame rate of30 fps by duplicating the frames accordingly:
ffmpeg -framerate 1/5 -i img%03d.png -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库