Silverlight 1.0でアプリケーションを開発し、デバッグの際に困難なことは、runtime errorの意味が時々わかりづらいということです。何かSilverlight側でエラーが起こっていることはわかるものの、メッセージやエラー番号から原因を調べるとしても情報が不足していると思います。今までに遭遇した例を紹介し、試行錯誤を減らすきっかけとなればと思います。
期待通りにビデオが再生されないようなケースや画像が表示されないケースがあります。これらは、次の原因にいきつくはずです。
・ビデオが再生されない MediaElementで動画を再生したい場合、たとえWindows Media Video形式であっても、音声のコーデックに注意してください。たとえば、Windows Media Audio 9 VoiceやWindows Media Audio 9 Professionalといったコーデックで音声が圧縮されているとビデオが再生できません。私自身、過去につくったビデオの再生でこの問題に気がつかず、理解せぬままに再エンコードを実行してビデオを作ったことがあります。 Silverlight 1.0でサポートされているメディアは、ここでご確認ください。・画像が表示されない - サポート外のフォーマット ImageやImageBrushを使う場合、サポートされている画像は、JPEGまたはPNGのみです。GIFはサポートされてません。すでにWeb上にあるような画像を参照しようとして、それがGIFだとうまくいかないのでご注意ください。Sourceプロパティの説明に記載されています。・ビデオや画像が表示されない - URIが正しくない データベース上にファイル名が格納されているような環境で、動的にURIを解決するようなプログラムを作っている場合、よく見たら、ローカルコンピュータでしか解決できない場所が指定されていた、ということがあります。注意しましょう。
・・・
ここからは、トラブルシュートではなく、うまく動かしていくための参考情報です。
・ビデオや画像のURIの動的解決の方法 参考情報として、MediaElementやImageオブジェクトのSourceプロパティへの設定は、Silverlightアプリケーションを起動するきっかけとなったURLを起点に相対的に解決できる場所にあれば、起点となっているところまでのURL表記は省略できます。たとえば、Webサーバの仮想ディレクトリ上に次のようにファイルがならんでいるとします。[Default.aspx][Video1.wmv][Image2.jpg]
表示しているXAMLには次のような要素があると仮定します。
<Canvas xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' Background='#FFF3E9EC' Width='960' Height='540' > <Canvas x:Name = 'MainPage' Loaded="onLoaded"> <Image x:Name ='ImageArea' ImageFailed="onImageError" /> <MediaElement x:Name='VideoPlayer' /> <Canvas x:Name='MediaController' Canvas.Top = '10' Width='100' Height='28' MouseLeftButtonUp="onPlayVideo"> <TextBlock>Play Video</TextBlock> </Canvas> <Canvas x:Name='ImageController' Canvas.Top = '40' Width='100' Height='28' MouseLeftButtonUp="onShowImage"> <TextBlock>Show Image</TextBlock> </Canvas> </Canvas></Canvas>
JavaScript側では次のようなコードを用意します。
var SLcontrol, mainCanvas, imageArea, videoPlayerfunction onLoaded(sender, args){ SLcontrol = sender.getHost(); // Silverlightコントロールの参照 mainCanvas = sender; // Canvasの参照 imageArea = mainCanvas.findName('ImageArea'); // 画像表示部分の参照 videoPlayer = mainCanvas.findName('VideoPlayer'); // ビデオ表示部分の参照 videoPlayer.addEventListener("mediaOpened", onMediaOpened); // ビデオが正しく開けたときのイベント videoPlayer.addEventListener("mediaFailed", onMediaFailed); // ビデオが正しく開けない場合のイベント(メディアのエラー) videoPlayer.addEventListener("mediaEnded", onMediaEnded); // 再生したビデオが止まったときのイベント}
var SLcontrol, mainCanvas, imageArea, videoPlayerfunction onLoaded(sender, args){ SLcontrol = sender.getHost(); // Silverlightコントロールの参照 mainCanvas = sender; // Canvasの参照 imageArea = mainCanvas.findName('ImageArea'); // 画像表示部分の参照 videoPlayer = mainCanvas.findName('VideoPlayer'); // ビデオ表示部分の参照
videoPlayer.addEventListener("mediaOpened", onMediaOpened); // ビデオが正しく開けたときのイベント videoPlayer.addEventListener("mediaFailed", onMediaFailed); // ビデオが正しく開けない場合のイベント(メディアのエラー) videoPlayer.addEventListener("mediaEnded", onMediaEnded); // 再生したビデオが止まったときのイベント}
では、ビデオや画像を動的にロードする方法を示しましょう。まずは、ビデオから。
function onPlayVideo(sender, args){ var videoURI = "Video1.wmv"; videoPlayer.Source = videoURI;}function onMediaOpened(sender, args){ // Sourceプロパティで指定したURIから正しくビデオがロードできたら再生する sender.Play();} function onMediaFailed(sender, args){ alert('ビデオを正しく開けません');}
function onPlayVideo(sender, args){ var videoURI = "Video1.wmv"; videoPlayer.Source = videoURI;}function onMediaOpened(sender, args){ // Sourceプロパティで指定したURIから正しくビデオがロードできたら再生する sender.Play();}
function onMediaFailed(sender, args){ alert('ビデオを正しく開けません');}
簡単ですね。さきほどのonPlayVideo関数中のURI指定をhttp:やmms:などを使っても同じように実行できます。例を示しましょう。これは私が投稿したChannel 9のビデオのひとつを示しています。
videoPlayer.Source = "mms://wm.microsoft.com/ms/japan/msdn/channel9/2007/070128-PrelaunchEvent-Omotesandohills.wmv";
加えて、ロードしたビデオをループ再生したい場合があるかと思います。その場合は、mediaEndedイベントハンドラを次のようにするだけで実現できます。
function onMediaEnded(sender, args){ videoPlayer.Position = "00:00:00"; // メディアの先頭に戻す videoPlayer.Play(); // 再生}
続いて画像(静止画)の場合です。
function onShowImage(sender, args){ var imageURI = "Image2.jpg" imageArea.Source = imageURI;}
これまた簡単です。Imageオブ��ェクトのSourceプロパティにもURIが指定できます。問題は、指定した画像が読み込めなかった場合の処理です。これは、次のようにイベントを処理します。上述のXAML内にImageFailedイベントハンドラを指定してあります。
function onImageError(sender, args){ alert("指定した画像を読み込めません");}
・ビデオを背景に別のビデオを再生する方法複数のMediaElementを組み合わせれば、背景をビデオにして、別のビデオも再生できます。さきほどのXAMLに要素を追加してみましょう。すでに紹介したループ再生の方法と組み合わせれば、実行中、背景のビデオがずっと流れることになります。(コードは省略します)
<Canvas xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' Background='#FFF3E9EC' Width='960' Height='540' > <MediaElement x:Name="BackgroundVideo" Canvas.Top="0" Canvas.Left="0" Source="SLV01.wmv" Width="960" Height="540" Stretch="Fill" AutoPlay="true" /> <Canvas x:Name = 'MainPage' Loaded="onLoaded"> <Image x:Name ='ImageArea' ImageFailed="onImageError" /> <MediaElement x:Name='VideoPlayer' /> <Canvas x:Name='MediaController' Canvas.Top = '10' Width='100' Height='28' MouseLeftButtonUp="onPlayVideo"> <TextBlock>Play Video</TextBlock> </Canvas> <Canvas x:Name='ImageController' Canvas.Top = '40' Width='100' Height='28' MouseLeftButtonUp="onShowImage"> <TextBlock>Show Image</TextBlock> </Canvas> </Canvas></Canvas>
Silverlight 1.0でビデオと画像を利用する際の参考になれば幸いです。