ちょっと前になりますが WPF を使って動画のサムネイルを生成してみた - しばやん雑記 で書いた通り WPF を使って動画のサムネイルを自動的に生成するコードを書いてみたのですが、これが Azure Web サイト上で動いてくれなくて困りました。
やはりサーバー OS はクライアント OS とは勝手が違ってきますね。なので、今回は有名な FFmpeg を使ってサムネイルを生成してみることにします。
https://www.ffmpeg.org/download.html
FFmpeg はクロスプラットフォームですが、Windows 版はビルド済みなものが公式サイトからは配布されていないので "Zeranoe FFmpeg Builds." というものを使いました。
色んな種類がありますが、今回は 32bit 版の Static ビルドを使いました。このバイナリは実行に必要な様々なライブラリがスタティックリンクされているバージョンで、Azure Web サイトなどのサーバー上で実行するには非常におあつらえ向きです。
ダウンロードした 7z を展開して、bin フォルダまで辿ると 3 つ実行ファイルがありますが、必要なのは ffmpeg.exe だけになります。
この段階で一度 ffmpeg.exe を使って動画のサムネイルを作成するコマンドを叩いておきます。
ffmpeg.exe -ss 20 -i claudia.mp4 -vframes 1 -f image2 claudia.jpg
パラメータを簡単に説明すると -i は入力ファイルのパス、-ss は秒数、-vframes は切り出すフレーム数、そして -f image2 は画像として保存するオプションになります。
なので、実際に先ほどのコマンドを実行すると以下のような画像が出力されます。
とてもいいシーンを切り出すことが出来ましたね。
とまあ、コマンドを叩けば FFmpeg がとても良い感じに出力してくれるので、今回は C# から ffmpeg.exe を実行するコードを書くだけです。
var input = "claudia.mp4"; var output = "claudia.jpg"; var seek = 20; var arguments = string.Format("-ss {1} -i \"{0}\" -vframes 1 -f image2 \"{2}\"", input, seek, output); var process = Process.Start(new ProcessStartInfo("ffmpeg.exe", arguments) { CreateNoWindow = true, UseShellExecute = false, }); process.WaitForExit();
単純にさっきのコマンドを C# の Process クラス使って書き直しただけです。Stream 使いたいですがファイルでやり取りしないといけないのが、やはりちょっとめんどくさいところですね。
当初の目的であった Azure Web サイト上での動作も FFmpeg が各種デコーダーなどを内蔵しているからか問題ありませんでした。
サーバー上で動画のサムネイルを作成する機会はあまりないと思いますが、参考までに。
追記
Twitter で ffmpeg.exe に渡すパラメータの順番を変えることで、無駄にデコードをせずに高速に処理できると教えてもらいました。ありがとうございます。
@shibayan -ssは-i "入力ファイル"の前に置くと、その位置までスキップするので早かったと思います。そして後だと頭からデコードしながら移動するんだったと思います。
— りっど (@foreheadlarge) July 8, 2014
テストしてみたところ確かに高速にサムネイルを切り出せました。なので、本文中のパラメータを修正しておきました。