Silverlightでムービーをストリーミング

Windows Media Serviceを使って動画を配信する場合、従来ならば、Windows Media Playerを使わなければなりませんでした。さらに、Windows Media PlayerはWindowsではActiveXとして提供されているものの、Firefoxなどでは、プロパティやイベントによる細かな制御が出来ないため、IE限定などにせざるを得ませんでした。当然、Macでは・・・というか、Windows Media Player自体が既にIntel Macに非対応ですし、Flip4Macを使ってQuickTimeで再生したとしても、やっぱり、制御は出来ませんでした。

そこに登場したSilverlightですが、Windows、MacとOSを選ばないだけでなく、現在でもIE, Firefox, Safariに対応しています。さらに、"Silverlight, coming soon to a browser near you"によれば、すぐにOperaにも対応する模様。当然、Linux上でもMoonlightによる対応がそこまで見えている状況。Silverlight自体は、別にムービーを再生するだけの代物ではないんですが、強力すぎるぐらいの代役となります。

mmsとかrtspが使えない?

とはいうものの、一筋縄ではいかないようです。

<Canvas Width="800" Height="400"
   xmlns="http://schemas.microsoft.com/client/2007"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
  <MediaElement x:Name="media"
    Source="rtsp://somewhere/pubpoint/"
    Width="320" Height="240" />

</Canvas>

とか書いても全く認識してくれません。ちなみに、IE7で見る場合、ローカルでSilverlightをテストすると、セキュリティの関係で外界(インターネット)のリソースにアクセスできないので、それにはご注意。

で、何が悪いのかというと、そもそもSilverlightがmmsとか、rtspに対応していないような雰囲気。SDKによれば、

Supported Protocols
The following web protocols are supported.

http 
https 
mms 

とあるのですが、mmsはどうやら動いていなさそうです。ということで、http/httpsでの運用をせざるを得ないわけですが、海外のサイトでいろいろと調べてみたところ、これも、ストリーミングの制御をちゃんと行うのであれば、多少面倒な手順を踏まないといけなさそうです。とはいえ、分かってしまえば大したことではないのですが、まず、Windows Media Serviceで、「WMS HTTP サーバー制御プロトコル」のポートを80以外に設定しないといけません。

f:id:espresso3389:20070902041900j:image

f:id:espresso3389:20070902041920j:image

次に、参照する側(XAML)ですが、

  <MediaElement x:Name="media"
    Source="http://somewhere:8080/pubpoint/"
    Width="320" Height="240" />

のようにポートを明示的に指定しないといけません。とはいえ、これだけです。HTTPなので、RTSP(UDP)ほどのレスポンスは得られないことがありますが、逆にHTTPじゃないとプロキシにはじかれたりということもあるので、これは妥協すべき点なのでしょう。

ランダムシークしてみる

さきほどのXAMLが、

function createSilverlight(parent) {
 Silverlight.createObject(
  "test.xaml",
  parent,
  "mySilverlightPlugin",
  {
    width:'800', height:'400',
    inplaceInstallPrompt:false,
    background:'white',
    background:'#D6D6D6',
    isWindowless:'false',
    framerate:'24',
    enableFramerateCounter:false,
    version:'1.0'},
  {onError:null, onLoad:null, onResize:null},
  null);
}

のように、mySilverlightPluginという名前でロードされている場合なら、

document.getElementById("mySilverlightPlugin").content.findName("media").Position = "00:12:00";

のようなJavaScriptコードで、12分00秒のところまで移動できる。
当然、Silverlightのイベントだったら、senderというインスタンスが得られているので、

function media_back(sender, args) {
  sender.findName("media").Position = "00:12:00";
}

で十分。