p5.jsで作ったジェネラティブアートをtwitterに動画で貼り付ける際のメモ

# 本メモの結論
ffmpegを使って連番pngを結合して動画を作成するとよさそう。
もっといいやり方あるのかもだけど、この方法である程度改善はしたのでメモを残しておく。

## Canvasのpngを連番で保存
この`savePicture()`を`draw()`の一番最後に入れます。適切な`maxCount`を設定してください。
※大量に画像が保存されることになるので、ご注意！
また、私のPCの様に非力だとなぜか出力されないフレームが出てくるので、その場合は`setup()`内で`frameRate(5)`とかでフレームレート落として実行してください。

```javascript
let count = 0;
const savePicture = ( maxCount = 10 ) => {
  
  save( ( '' + count ).padStart( 3, '0' ) + '.png' );
  count++;
  if( count > maxCount ){
    noLoop()
  }

}
```

## 連番pngをffmpegで結合しmp4化
```bash
ffmpeg.exe -r 30 -i ~/Downloads/%03d.png -vcodec libx264 -pix_fmt yuv420p -r 30 out.mp4
```


# 結論に至るまで
## 背景
最近、p5.jsでジェネラティブアートを作って遊んでいるのですが、特に動きのある作品を動画としてtwitterに投稿したときに、自動的に圧縮され非常に残念な結果となります。↓はびっくりするぐらい汚い絵になった例。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">setup=_=&gt;g=createCapture({audio:0,video:{}}).hide()<br>draw=_=&gt;{a=g.get()<br>f=fill<br>resizeCanvas(w=a.width,h=a.height)<br>u=10<br>textSize(d=2*u)<br>for(i=h/u;i--;)for(j=w/u;j--;)f(a.get(u*j,u*i)),r=random(d),circle(u*j,u*i,r)<br>f(255)<br>textStyle(BOLD)<br>text(&#39;<a href="https://twitter.com/hashtag/%E3%81%A4%E3%81%B6%E3%82%84%E3%81%8DProcessing?src=hash&amp;ref_src=twsrc%5Etfw">#つぶやきProcessing</a> <a href="https://twitter.com/hashtag/pchj03?src=hash&amp;ref_src=twsrc%5Etfw">#pchj03</a> &#39;,d,2*d)} <a href="https://t.co/N4qLTjCZRc">pic.twitter.com/N4qLTjCZRc</a></p>&mdash; Tetsunori NAKAYAMA | 中山 哲法 (@tetunori_lego) <a href="https://twitter.com/tetunori_lego/status/1299621176029790208?ref_src=twsrc%5Etfw">August 29, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これは、Windows PCの画面キャプチャでも、iPhone/iPadの画面キャプチャでもどちらでも発生しており、最初はこんなものかなと思っていましたが、他の皆様の投稿を見ていると、キレイに動画を投稿できている方が多いので解はあるはずだと思い、調査を始めました。

## 解決していそうな方のコメント
なんかtwitterの動画がひどく圧縮されないための条件が複数あるらしいのですが、画サイズを720以下にする以外は動画の設定を細かく調整する必要がありそうです。面倒なので、その辺をケアできている`ffmepg`の神コマンド落ちていないかなと検索した結果見つけました。↓

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">こんにちは！<br>特にこれといってしていませんが、30fpsで連番pngで出力したものをffmpegで繋げています。<br>コマンドはこんな感じです<br><br>./ffmpeg.exe -r 30 -i ~/Downloads/img%03d.png -vcodec libx264 -pix_fmt yuv420p -r 30 out.mp4</p>&mdash; かねた (@kanetaaaaa) <a href="https://twitter.com/kanetaaaaa/status/1141941001738571776?ref_src=twsrc%5Etfw">June 21, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ただ、デフォルトではp5.jsには連番の画像出力機能はないと思うので、上述の関数を作って連番PNGを出力できるようにしてからトライしました。

## やってみた
対応前後の動画を比較します。
### Before
こちらはiPadの画面キャプチャをトリミングしたそのままの動画。若干ノイジーに感じます。


<blockquote class="twitter-tweet"><p lang="en" dir="ltr"> <a href="https://t.co/mkfLaYipoH">pic.twitter.com/mkfLaYipoH</a>
</p>&mdash; Tetsunori NAKAYAMA | 中山 哲法 (@tetunori_lego) 
<a href="https://twitter.com/tetunori__lego/status/1302595542384390145?ref_src=twsrc%5Etfw">September 6, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


### After
コチラが今回の方法で出力した動画。すこしだけキレイになめらかに表示されています！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ffmpegでpngから生成した動画がなめらかに見えるかのテスト <a href="https://t.co/7DZguJsv6C">pic.twitter.com/7DZguJsv6C</a></p>&mdash; Tetsunori NAKAYAMA | 中山 哲法 (@tetunori_lego) <a href="https://twitter.com/tetunori_lego/status/1302975574470569985?ref_src=twsrc%5Etfw">September 7, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


別の動画も投稿してみましたが、まずまずのなめらかさな気がする。とりあえず、継続して試してみよう。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr"> <a href="https://t.co/XY0o9yr2PD">pic.twitter.com/XY0o9yr2PD</a></p>&mdash; Tetsunori NAKAYAMA | 中山 哲法 (@tetunori_lego) <a href="https://twitter.com/tetunori_lego/status/1302967499386884098?ref_src=twsrc%5Etfw">September 7, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>