プログラマラブルに動画制作ができるnpmパッケージのediltyを使ってみた


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">プログラマルブに動画制作ができるnpmパッケージ<br><br>CLIでの操作でも出来るし、functionを渡してあげればプログラマラブルに動画制作できてる<a href="https://t.co/v6xp958tT1">https://t.co/v6xp958tT1</a></p>&mdash; Nash⚡️ReactNative書いてる (@snamiki1212) <a href="https://twitter.com/snamiki1212/status/1255153313760174087?ref_src=twsrc%5Etfw">April 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## 概要

[GitHub - mifi/editly: Slick, declarative command line video editing](https://github.com/mifi/editly)

```Editly is a tool and framework for declarative NLE (non-linear video editing) using Node.js and ffmpeg. Editly allows you to easily and programmatically create a video from set of clips, images and titles, with smooth transitions between and music overlaid.```

⇒意訳：宣言的プログラミングで動画制作が出来るツール

## Installation

* version: 0.2.0 (1系にも来てないのでプロダクションレベルじゃないかも）

[Requirements](https://github.com/mifi/editly#requirements)を見ると、他にも`ffmpeg`と`ffprobe`なるものが必要みたいです。


### ffmpeg

> ffmpegとは動画と音声を記録・変換・再生するためのフリーソフトウェアである。
> [FFmpeg - Wikipedia](https://ja.wikipedia.org/wiki/FFmpeg)

### ffprobe

> ffprobeとはマルチメディアストリーム情報を解析し、人間もしくは機会が理解出来る形式で出力するツールです。
> ffprobeはffmpegに含まれているのでffmpegをインストールします。
> [ CompilationGuide/macOS – FFmpeg ](https://trac.ffmpeg.org/wiki/CompilationGuide/macOS)

ffmpegは動画系でよく使われる優秀なツールみたい、知らなかった。

ffmpegさえ入れればffprobeも一緒に入るみたいなので、ffmpegを入れます。

```zsh
$ brew install ffmpeg

$ ffmpeg -version
ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
...
```

edilty本体を入れます。

```zsh
$ npm i -g editly
```

これで準備完了。


## Hello WorldでText2Video

いざHelloWorldな動画をジェネレートしてみます。
ここでは「テキストを元に動画を生成」という観点で見ていきます。

### CLI + オプション

```zsh
$ editly title:"Hello World" --out ./output.gif
320x320 10fps
createFrameSource linear-gradient clip 0 layer 0
createFrameSource title clip 0 layer 1
  0%  25%  50%  75% Done with transition, switching to next clip
No more transitionFromClip, done
Done. Output file can be found at:
./output.gif
# これで作成完了

$ open -a 'Google chrome' ./output.gif # gifをchromeで開くだけです
```

output.gif

> ![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186228/7dd92b02-b009-e6f4-08a3-c8402917da19.gif)
> （ちょっとわかりにくいですが、gifで動画になってます）

gifが作成できた。

### CLI + JSON5

CLIのオプションで指定していた内容をJSON5にしていきます。

```json5:my-video.json5
{
  outPath: "./result.gif",
  clips: [
    {
      duration: 2,
      layers: [
        {
          type: "title-background",
          text: "こんにちは、世界",
        },
      ],
    },
  ],
}
```

```zsh
editly my-video.json
# > output.gif
```

> ![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186228/a31e68b5-7167-9648-8144-c4e702c350b3.gif)

gifができた。これで動画をJSONで管理できるようになりました。

### TypeScript (or JavaScript)

CLIで実行していましたが次はJavaScriptで実行していきます。

```js:index.js
const editly = require('editly')

const spec = {
  outPath: "./outputByLib.gif",
  width: 640,
  height: 640,
  clips: [
    {
      duration: 3,
      layers: [
        {type: "rainbow-colors"},
        {
          type: "subtitle",
          text: "JSで作られた",
        }
      ],
    },
  ],
}

editly(spec)
  .then(() => {console.log('finish')})
  .catch(err => console.error(err))
```

```zsh
$ yarn init 
$ yarn --dev editly
$ node index.js
# => outputByLib.gif
```

> ![outputByLib.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186228/0f132f78-6423-8b05-51df-1a874d4dea5a.gif)

gif が出来た。これで動画をプログラマティックに生成できるようになりました。

forで回せば簡単に複数の動画も作成できるし、動画の設定自体はJSON5で持たせておいてimportしてくることもできますね。

ちなみに、CLIで作った動画と違って背景が虹色になってたり、サイズが大きいのはJSONにて設定を入れてるからです。

## 他にもどんな感じで動画を作成できるか

詳細はこちらのexample参照です。

- [editly/examples at master · mifi/editly · GitHub](https://github.com/mifi/editly/tree/master/examples)

動画と動画をつなぎ合わせたり、音声を入れたり、フェード効果などもつけられます。

特に、JavaScriptのコードを呼び出すことでプログラマラブルに動画ジェネレートできるのはアツいです。

## おわりに

きっかけ2020-04-29 0:20 JST時点でHacker Newsの上位にediltyというパッケージが上がってきたのでたまたま見つけました。

最近、「すっごい簡単なテキストベースの動画を、サクッと作成したいなー」という欲求があったので、自分のやりたいことを実現できる良いツールを見つけました。

これで動画をコード管理することが出来るのでエンジニア的には使い勝手の良いツールだと思います。