Thanks Driven Life

日々是感謝

動画ファイルから Animation GIF を作る go-gifer を作ってみた

gongo/go-gifer · GitHub

Motivation

  1. Go で何か作ってみたかった
  2. Go と言えば Go Routine
  3. 並列っぽい処理で効果を発揮しそうなの探してた
  4. http://blog.geta6.net/post/62420516580/mp4-gif を見つけたので練習として書いてみた

Installation

$ go get github.com/gongo/go-gifer

Usage

$ go-gifer -h
Usage of go-gifer:
  -delay=50: Set frame delay to TIME (1/100 sec)
  -h=false: Show this message
  -i="": Input movie filename (required)
  -loopcount=0: Set loop extension to N (0 is forever
  -n=100: Number of frames to extract
  -o="gifer.gif": Output gif filename

使ってる様子も go-gifer で作ってみた。QuickTime の画面録画した mov から作成。 なんか右側に青いのが出てるけど気にしない

demo gif

(Options) Development

  • ゴルーチンでffmpeg のプロセスを開きまくったら Bad file descriptor とか言われた
  • ffmpeg のゴルーチン全て終わってから gifsicle の処理に入りたかった

というわけでこうしてみました。実際はこう

queue := make(chan bool, processMaxCount)

var wg sync.WaitGroup
for i, n := range frameIndexes {
    wg.Add(1)
    go func(index, frameNumber int) {
        defer wg.Done()
        queue <- true
        // フレーム作成
        <-queue
    }(i, n)
}
wg.Wait()

これであってるかなー。プロセス確認した感じだと、ffmpeg が最大 processMaxCount 分しか起動してなかったから多分大丈夫

ちなみに今回は gifsicle 使ったんですが、Go 1.2 ぐらいから image/gif に Encode が追加されそうなので、そこらへんに移行しても良さそうだけど、きっと gifsicle の方が綺麗にできそうな気もする。

あと ffmepg の go binding みたいなやつもあったけど、いろいろあって今回はシステムコールで対処

Conclusion

golang 難しいようなだけど面白いような。幸せな気持ちで書いてる気分です。 標準の go tool だったり gocode だったり、環境が良いのも開発楽しい一因かもですね。

しかし、ffmpeg よくわかってなくて、今回はとりあえず指定フレームを抜き出すみたいなことを -ss N -vframes 1 (-start_number の方がよかったかな…) のゴルーチンでやったんですが フレームレートを調整-r して指定フレーム数になるようにする方が早い気がする(というか早い)ので あまり Go の爆発力感じることができなかった。別案を考えよう…