ScalaでWebM形式の動画再生

それなりにたいへんそうで勉強になるかと思い、ScalaでWebM形式の動画を再生するコードを書いてみた。やりたくなったから、やっただけなので特に有用性とかはないです。

WebMのデコーダを準備する

Javaで、WebM形式の動画を扱うには gstreamer-java が使える。

gstramer-java はネイティブのgstreamerを呼びだすのでインストールする。また、gstreamerがWebM形式の動画をデコードできるように、デコーダもインストールしておく。

WebMデコーダのインストール

WebMのデコーダ(libvpx)のソースコードをcloneしてビルド/インストール。

$  git clone git://review.webmproject.org/libvpx.git
$ cd libvpx
$ ./configure
$ make
$ sudo make install # とりあえず/usr/local にいれておく
gstreamerのインストール

MacPortsからインストール。GNOME系のライブラリ/各種コーデックに依存しているためか、とても時間がかかる。

$ sudo port install gstreamer gst-plugins-base gst-plugins-bad gst-plugins-good

Scalaでgstreamerを呼び出すコードを書く

gstreamer-javaのサンプルコードをScalaに翻訳する。

import java.io.File;
import scala.swing._;

import org.gstreamer.Gst;
import org.gstreamer.State;
import org.gstreamer.elements.PlayBin;
import org.gstreamer.swing.VideoComponent;

object VideoPlayer {
  def main(args : Array[String]) {
    val gstArgs = Gst.init("VideoPlayer", args)
    val playBin = new PlayBin("VideoPlayer")
    playBin.setInputFile(new File(gstArgs(0)))

    Swing.onEDT {
      val videoComponent = new VideoComponent;
      playBin.setVideoSink(videoComponent.getElement)

      val panel = new BorderPanel {
        add(Component.wrap(videoComponent), BorderPanel.Position.Center)
      }
      val frame = new MainFrame {
        title = "VideoPlayer"
        preferredSize = new Dimension(640, 480)
        contents = panel
        open
      }
      playBin.setState(State.PLAYING)
    }

    Gst.main
    playBin.setState(State.NULL)
  }
}

もとのコードよりもSwingまわりはscalaっぽくなっていてきれいですね。newしながらコンストラクタ拡張しつつ初期化コードを走らせているのが Scalaっぽい? scala.swingの使い方がよくわかんなかったので適当です。

コンパイル

gstreamer-java-1.4.jarとjna.jarをダウンロードして適当なところにおいておく(うちはlibディレクトリを作っておいてる) 。あと、コンパイル時にはjnaにライブラリの場所を教えてあげる。あと、Scala2.8じゃないとうごかなさそうです。

$ scalac -Djna.library.path=/opt/local/lib/ -cp .:lib/gstreamer-java-1.4.jar:lib/jna.jar VideoPlayer.scala

実行

$ scala -Djna.library.path=/opt/local/lib/ -cp .:lib/gstreamer-java-1.4.jar:lib/jna.jar VideoPlayer ~/Desktop/k-on_op.webm

再生できました!!

WebM形式の動画は YouTube からとってくるのが便利ですね。

メモ

  • Java系で動画再生とか大変そうに思っていたけどライブラリがそろっていて簡単。Scalaでも余裕でつかえる
    • gstreamer/gstreamer-javaが汎用的に使えて便利 (WebMにもプラグインで対応)
    • ただしネイティブにコンパイルされたライブラリに依存してる
  • ScalaでJavaのライブラリを呼び出すコードを書くとあまりJavaとかわらなくなって、Scalaの書きやすさを享受できなくなる
    • scala.swingではなくて、javax.swingを使うとだいぶJavaっぽくなってしまう (new Runnable() {} とかいるし)
    • JavaのライブラリのScalaラッパが増えれば、もっとScalaが書きやすくなりそう
  • Scalaのソースコード内のライブラリのコードはScalaの勉強するのにたいへんよい
  • Scalaの開発環境整えたいです
    • import たいへん
    • コンパイラがおそい
    • クラスパスとかをコマンドラインで毎回渡すのがたいへん

今回のようにただ再生するだけだと、さすがにしょうもないので、今度は、Actorを使ってWebインターフェースからプレイヤーをコントロールとかやりたいですね。