FFmpeg將多張圖片合成視頻

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/wangshuainan/article/details/77914508
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
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’
1
2
3
4
5
6
7
注意!!! 最後一個圖要重複寫一遍,但不用加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.
1
2
3
4
5
6
7
8
-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
1
參考:

FFmpeg官網:
http://ffmpeg.org/ffmpeg.html

https://trac.ffmpeg.org/wiki/Slideshow
————————————————
版權聲明:本文爲CSDN博主「wangshuainan」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wangshuainan/article/details/77914508

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章