ffmpeg ã§é£ç¶ç»åããã¯ãã¹ãã§ã¼ãã¹ã©ã¤ãã·ã§ã¼ãï¼ç¡çããï¼ä½æããã®ã§ã æ¦è¦ãã¡ã¢ãã¦ããã¾ãã
å°å ¥
åæ©ã¨ãã¦ã¯ãç»åçæ AI ã§ä½ã£ãç»åãæ¯è¼ããã®ã«åç»ã§ã§ããªãããªã¨æã£ã次第ã§ãã
ãã¥ã¢ã¼ã§ä¸æä¸æè¦ããã¨ãã§ããã®ã§ããã äºæ¬¡å çã«æ¯è¼ããã (ä¾ãã°ãã·ãã¥ã¨ã¼ã·ã§ã³ãxããã©ã¡ã¼ã¿ãã¿ãããª) å ´åã äºã¤ãã¥ã¢ã¼ãç«ã¡ä¸ãã¦ããããå¥ã ã«åããã®ã¯é¢åã§ãã é¢åã ããªãã¾ã ããããã®æéãéªéããã¦å°è±¡ã失ããã¦ãã¾ãã¾ãã ã¾ããæ¬å½ã«ç´°ããéããã¿ãå ´åã¯ç¬éã§åãæ¿ããã®ãããã®ã§ããã é°å²æ°çãªãã®ã確èªãããå ´åã¯ãããã¯ãã¹ãã§ã¼ãã®æ¹ãåãã¦ãã¾ã (å人ã®ææ³ã§ã)ã
XYZ ã°ãªããçæãããã¾ããã å¾®å¦ãªå·®ã確èªãããå ´åã«ã¯å¥ã ã«ä¸¦ãã§ããç»åãè¦ã¦å¤æããã®ã¯é£ãããã®ãããã¾ãã ããã«ãæ¬å½ã«å¤§éçæãããå ´åã«ã¯ã°ãªããã«ãããã¨ããã§ãã¾ããã
ã¨ãã訳ã§ã大éã®ç»åãããã°ãªããã§åç»ã§ã¯ãã¹ãã§ã¼ãã¹ã©ã¤ãã·ã§ã¼ãã¦ãããããã«ããã ffmpeg ã®ã³ãã³ããä½ãã¾ããã
æ£ç¢ºã«ã¯ãããããããã ffmpeg ã®ã³ãã³ãããçæããã¹ã¯ãªããããä½ãã¾ããã ã¨ããã®ããæåã¯ãã£ã¨ç°¡åã«æ¸ãã¨æã£ã¦ããã®ã§ããã ããªãé·ãã¹ã¯ãªãããæ¸ããªãã¨ãããªãã¨åãã£ã¦ã ããæ¼ãããããã§ãã
ãããªäºæ ãããã®ã§ãåºæ¥ã¯ãå¯ããã ããã ã¡ãã㨠python ãªãã§æ¸ããæ¹ãèªã¿ããããã®ãã§ããã¨æãã¾ãã ãããã ffmpeg ã®ä»æ§ãã¡ããã¨ããã£ã¦ãã¾ãããã
ã³ã¼ã
åã®äºã®è¨ãåã«ã³ã¼ããç½®ãã¦ããã¾ãã powershell ã§ãã
åå¿é²ãªã®ã§åä½ã¯ä¿è¨¼ãã¾ããã èªå·±è²¬ä»»ã§ãå©ç¨ãã ããã念ã®ããã
1 ã¿ã¤ã«ã®ã¹ã©ã¤ãã·ã§ã¼
ã³ã¼ãã表示
$secPerPict = 1.0 $file_ext = "webp" $inputs = "" $filter = "" $overlay = "[0][f0]overlay[bg1];" $prev = 0 $index = 0 $count = 0 $fade = $secPerPict / 5.0 $offsetPerPict = $secPerPict - ($fade / 2.0) $files = Get-ChildItem -Path ".\" -Filter "*.$file_ext" foreach ($f in $files) { if ($count -ge 3) { $overlay += "[bg$prev][f$prev]overlay[bg$index]; `n" } $prev = $index $index = $count $count += 1 $name = $f.Name $tmp1 = $name -Split "-" $tmp2 = $tmp1[1] -Split "@" $text = $tmp2[0] $inputs += "-loop 1 -t $secPerPict -i '$name' `n" if ($count -ge 2) { $offset = $offsetPerPict * $count $text_part = "drawtext=text='$text':fontsize=80:x=20:y=20:box=1:boxcolor=white" $filter += "[$index]$text_part,fade=d=0.1:t=in:alpha=1,setpts=PTS-STARTPTS+$offset/TB[f$prev]; `n" } } $overlay += "[bg$prev][f$prev]overlay,format=yuv420p[v]" $cmd = "ffmpeg -y $inputs -filter_complex `n `"$filter$overlay`" " $cmd += '-map "[v]" ' $cmd += '-r 60 ' $cmd += 'output.mp4' $exec_cmd = "$cmd" -replace "`n","" Set-Clipboard -Value $exec_cmd Invoke-Expression "$exec_cmd"
ä»æ§ã¯ä»¥ä¸ã®ãããªæãã§ãã å¤æ´ãããå ´åã¯ã³ã¼ããå¼ã£ã¦ãã ããã
- å
¥å
- ã«ã¬ã³ããã£ã¬ã¯ããªã®è¤æ°ã®ç»å (4æ以ä¸)ã
- ãã¡ã¤ã«åã¯
xxx-<text>@xxx.png
ã- xxx ã¯
-
ã@
ãå«ã¾ãªãä»»æã®æååã <text>
ã¯ç»åã«è¡¨ç¤ºããæååã- æ¡å¼µåã¯ä¸è¨ã®å¤æ°ã§è¨å®å¯è½ã
- xxx ã¯
- è¨å®å¤
- secPerPict: ç»åä¸æã®è¡¨ç¤ºæé
- file_ext: ãã¡ã¤ã«æ¡å¼µå (png ã¨ã webp ã¨ã)
- åºå
- output.mp4 ã¨ããååã®åç»ã
- ç»å表示æéã® 1/5 ã®æéã§ã¯ãã¹ãã§ã¼ãã
- å·¦ä¸ã«ç½èæ¯ã®é»ããã¹ãã表示ã
- 60 fpsã
é£çµç¨ã®ã³ãã³ã
å ã»ã©ã®ã¹ã¯ãªãããè¤æ°ã®ãã£ã¬ã¯ããªã§å®è¡ãã¦ã çæããåç»ã縦ã«ä¸¦ã¹ã¾ãã
ffmpeg ` -i dir_hogehoge\output.mp4 ` -i dir_fugafuga\output.mp4 ` -filter_complex "vstack" output.mp4
横ã«ä¸¦ã¹ãã¨ãã°ãªããã«ããã¨ããã§ããã¨æãã¾ãã*1
ã³ãã³ãã®è§£èª¬
ã¡ã¢ç¨åº¦ã«ããªãã§ãããªã¹ã¯ãªãããæ¸ããã¨ã«ãªã£ãã®ãã¨ããåå ã ã¤ã¾ãã ffmpeg ã®ä»æ§ã¨ãã®éçãã¾ã¨ãã¦ããã¾ãã
å½åã®æ³å®
å½åã¯ã以ä¸ã®ãããªã³ãã³ãã§ä½ã¨ãããããªã¨æã£ã¦ãã¾ããã (å¼æ°ã¯ã¾ã£ããã®é©å½ã§ã)
ffmpeg -input *.webp -option_hogehoge "fade_fugafuga" ... output.mp4
åç´ã«é£çµããã ããªãããã«è¦ã¤ãã£ã¦ã ä¾ãã°ä»¥ä¸ã®ãããªã³ãã³ãã§è¯ãããã§ãã *2
$ ffmpeg -framerate 30 -i image_%03d.webp -vcodec libx264 -pix_fmt yuv420p -r 60 output.mp4
ããã§ã«ã¬ã³ããã£ã¬ã¯ããªã«ããé£çªã®ãã¡ã¤ã«ãåãæ¿ããªãã表示ãããã¨ãã§ãã¾ãã ã§ããããã§ãããªãããããåç»ãä½ããªãã¦ãããã®ã§ã
ä»ã®æ¹æ³ã®æ¨¡ç´¢
ãªã®ã§ããããæ¢ãã¦ã¿ãã®ã§ãããç°¡åãªæ¹æ³ã¯è¦ã¤ããã¾ããã åç»èªä½ã«ã¯ãã¹ãã§ã¼ããããããã¯ããããã§ãããã ç»åã®é£çµã«ãããããæ¹æ³ã¯è¦ã¤ããã¾ããã§ããã
ãã£ã¨è¦ã¤ãã£ãã®ã¯ãç»åãã¨ã«å¦çãæ¸ãæ¹æ³ã§ãã 以ä¸ã®ã³ãã³ãã¯ã 5æã®ç»åãé£çµãã¦ã 3ç§é表示ãã¤ã¤1ç§ããã¦ã¯ãã¹ãã§ã¼ãããå¦çã§ãã *3
ffmpeg \ -loop 1 -t 3 -i img001.jpg \ -loop 1 -t 3 -i img002.jpg \ -loop 1 -t 3 -i img003.jpg \ -loop 1 -t 3 -i img004.jpg \ -loop 1 -t 3 -i img005.jpg \ -filter_complex \ "[1]fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+2/TB[f0]; \ [2]fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+4/TB[f1]; \ [3]fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+6/TB[f2]; \ [4]fade=d=1:t=in:alpha=1,setpts=PTS-STARTPTS+8/TB[f3]; \ [0][f0]overlay[bg1];[bg1][f1]overlay[bg2];[bg2][f2]overlay[bg3]; \ [bg3][f3]overlay,format=yuv420p[v]" -map "[v]" -r 25 output.mp4
ç´°ããè¦ã¦ããã¨ã
loop
ã®é¨åã¯ãå ¥åãã¡ã¤ã«ã¨è¡¨ç¤ºæé (-t
)ã- å ¥åãã¡ã¤ã«ã®æ°ã ãæå®ããã
[n]fade...
ã®é¨åã¯ãã§ã¼ãå¦çãå®ç¾©ãfade=d=X
ã®X
ã§ãã§ã¼ãæç¶æéãæå®ãPTS-STARTPTS+X
ã®X
ã§ãã§ã¼ãéå§æéãæå®ã- å ¥åãã¡ã¤ã«ã®æ°ããä¸ã ãå°ããåæ°æå®ããã
[bgN][fN]overlay[bgN+1];
ã®é¨åã¯ãããããæ¥ç¶ãã¦ãã (ã£ã½ã)ã
å®éããã®æ¹æ³ã使ãã°æãéãã®åç»ãã§ãã¾ããã
ãããããã®æ¹æ³ã®åé¡ã¯ãå ¥åãã¡ã¤ã«ã®æ°ã ã大éã«ãªãã·ã§ã³ãããªããããæå®ããå¿ è¦ããããã¨ã§ãã ä»ã«ãã£ã¨ããæ¹æ³ãããããã§ããã調ã¹ãªããã®ãé¢åã ã£ãã®ã§ããæ¼ããã¾ããã
ãããå
ã«æããã³ã¼ãã§ãã
ãã¡ã¤ã«ã®ä¸è¦§ãåå¾ãã¦ããã®æ°ã ãä¸è¨ã®ãªãã·ã§ã³ã追å ãã¦ã
æå¾ã« Invoke-Expression
ã§å®è¡ãããã¨ããããæ¼ãã§ãã
åå¹
ãã®æ¹æ³ã使ã£ããã¨ã«ããå©ç¹ã¨ãã¦ã åã¹ã©ã¤ãã«åå¹ãã¤ãããã¨ãå¯è½ã¨ãªãã¾ããã
å
·ä½çã«ã¯ã[n]fade...
ã®é¨åã«å¦çã追å ãã¾ãã
以ä¸ã«ãã¹ã¯ãªããä¸ã®ãã®ãæç²ãã¾ãã
drawtext=text='$text':fontsize=80:x=20:y=20:box=1:boxcolor=white
ãã㧠$text
ã®ä¸èº«ããå·¦ä¸ãã 20x20 ã®é¨åã«ããã©ã³ããµã¤ãº 80 ã§ã
ç½èæ¯ã§åºåããã¾ãã
*4
ãã ãæåã®ç»åã«ã ãã¯åå¹ã表示ãããªããã°ãããã¾ãã ç´ãã®ãé¢åãªã®ã¨ãå®ç¨ä¸åé¡ãªãã®ã§ãã®ã¾ã¾ã«ãã¦ãã¾ãã
çæä¾
å®éã«çæãã¦ã¿ããã®ã¯ Twitter ã«ã
*1:ãç¥ãã¾ãããã©ãã
*2:åè: https://qiita.com/livlea/items/a94df4667c0eb37d859f
*3:åè: https://www.bannerbear.com/blog/how-to-create-a-slideshow-from-images-with-ffmpeg/#slideshow-with-a-crossfade-transition
*4:ããã©ã«ãã®ãã©ã³ããä½ãã¯åããã¾ãããã è±èªä»¥å¤ã®æååã表示ããå ´åã¯ã¡ããã¨æå®ããªãã¨ãã¡ããããã¾ãã (試ãã¦ãã¾ãã)ã