FFmpeg将多张图片合成视频
- FFmpeg將多張圖片合成視頻
- 從不同目錄下多張圖合成視頻
- Pipe
- Concat
- 容易誤解的幾個命令
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進行某些轉換??梢杂胒fmpeg -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-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)讀取輸入文件,生成視頻。
這個命令在linux、Mac OS、Windows上都是可行的,但是在安卓中不行,可能是ffmpeg找不到那個“全局管道”。
那么我們可以自己創建一個管道,然后告訴ffmpeg管道在哪?
創建管道:
mkfifo Desktop/pic.pipe向管道輸入文件:
cat Desktop/aa/img1.jpg Desktop/aa/img2.jpg > Desktop/pic.pipe使用ffmpeg讀取管道,生成視頻:
ffmpeg -loop 0 -f image2pipe -r 3 -b 200k -s 640*360 -t 12 -i Desktop/pic.pipe -y Desktop/oup.mp4這里pic.pipe的路徑子安安卓上要換成安卓的路徑:Environment.getExternalStorageDirectory().getAbsolutePath()下面
管道文件非常,非常強大,更多管道知識:
【Linux】mkfifo命令創建命名管道實現進程之間通信
【Linux】進程間通信-命名管道FIFO
Concat
首先,創建個input.txt文件,填寫圖片信息:
file 文件路徑
duration 這張圖播放時長
注意!!! 最后一個圖要重復寫一遍,但不用加duration。
然后run ffmpeg command:
ffmpeg -f concat -safe 0 -i Desktop/input.txt -vsync vfr -pix_fmt yuv420p Desktop/output.mp4這里命令里要加上-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 都是“不起作用的”,除非管道一直有內容。
-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 set if 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參考:
FFmpeg官網:
http://ffmpeg.org/ffmpeg.html
https://trac.ffmpeg.org/wiki/Slideshow
總結
以上是生活随笔為你收集整理的FFmpeg将多张图片合成视频的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 护眼软件Linux,四个 Linux 下
- 下一篇: parallelStream数据丢失问题