Silverlightで動画プレイヤーを作ってみた
MicrosoftのSilverlightを使ってみました。
Hello Worldを出しただけじゃ面白くないので、簡単な動画プレイヤーを作ってみました。
SilverlightではXAMLと呼ばれるXMLベースのファイルで視覚的な構造を定義し、それをJavaScriptを使って動かします。
Flashとは違いテキストのままで動作させることが出来るので、コンパイル作業は必要ありません。
Silverlightはマルチプラットフォーム・クロスブラウザ対応ということですが、現状だと結構動かない環境もあるようです。Windows2000などでは動作しないかもしれないです。
Silverlightで構築するときは、基本的に以下の5つのファイルを使用します。
Silverlight.js ・・・Silverlightの本体
Default_html.js ・・・基礎部分。ほぼ編集することはない。
Page.xaml.js ・・・編集しまくる
Page.xaml ・・・視覚情報用xamlファイル。これで見た目のカッコよさが決まる。
index.html ・・・表示させるHTML
この中で手を入れることになるのは、ほとんどPage.xaml.jsだけです。
Silverlight.jsはここのページからSDKをダウンロードすることで入手できます。
見た目を決定するxamlファイルは基本的にテキストエディタがあれば作成可能ですが、カッコよく作るにはMicrosoft ExpressionなどのXaml形式のファイルを出力してくれるデザインツールを使うといいらしいです。
Silverlight1.0の段階だとxamlに日本語を書いても表示できませんが、このへんのツールを使って日本語文字列をベクトルデータとして持たせる方法などもあります。
現在Silverlightのバージョンは1.0と1.1alphaがあります。1.1からはC#やVB.NETなどの言語でも開発できるようになるらしいですが、特に必要ないので今回は1.0を使用しました。
また、SilverlightはMicrosoftのVisualSutudioで開発できるらしいです。
おそらく、デザイナーがMicrosoft Expressionでxamlを作って、プログラマーがVisualStudioで処理を書いていくような形を想定しているんだと思いますが、どっちも持ってないので全部テキストエディタでガリガリ書いていきます。
そして完成品とプログラムが↓の通りです。
でも特に解説するところも無いような・・・
おそらくプログラムを見ればほとんど分かると思います。
xamlファイルは、ボタンやパネルなどの表示したい項目をCanvasタグで追加していき、属性で見た目を変更することになります。
う~ん、なかなかしょぼい。
やっぱ見た目って大切ですね。
シークバーは部品の作成がめんどかったので作ってません。
this.player.position.secondsで現在の秒数?が取れるのでこのへん使って作るのかなー
ちなみに表示している動画はフリー動画を提供しているミニネットZOOさんからお借りしてます。
index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Player</title>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript" src="Default_html.js"></script>
<script type="text/javascript" src="Page.xaml.js"></script>
</head>
<body>
<div id="SilverlightControlHost">
<script type="text/javascript">
createSilverlight();
</script>
</div>
</body>
</html>
Page.xaml
<Canvas
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300"
Background="gray"
x:Name="Page" >
<!-- 動画表示部分 -->
<MediaElement x:Name="player" Width="400" Height="300" />
<!-- 再生・停止ボタン -->
<Canvas x:Name="play_button"
Width="60"
Height="40"
Canvas.Left="50"
Canvas.Top="300"
Cursor="Hand"
Background="lightgray" >
<!-- 再生・停止ボタンの中のテキスト -->
<TextBlock x:Name="play_button_text"
FontSize="20"
Text="Play!">
</TextBlock>
</Canvas>
</Canvas>
Default_html.js
function createSilverlight(){
var player = new Player.Page();
Silverlight.createObjectEx({
source: "Page.xaml",
parentElement: document.getElementById(
"SilverlightControlHost"
),
id: "SilverlightControl",
properties: {
width: "400",
height: "350",
background:'gray',
isWindowless: 'false',
version: "1.0"
},
events: {
onLoad: Silverlight.createDelegate(
player, player.handleLoad
)
}
});
}
if (!window.Silverlight)
window.Silverlight = {};
Silverlight.createDelegate = function(instance, method) {
return function() {
return method.apply(instance, arguments);
}
}
Page.xaml.js
rootElement.children.findName();はdocument.getElementById();と同じようなモノです。
if (!window.Player) window.Player = {};
Player.Page = function()
{
}
Player.Page.prototype =
{
handleLoad: function(control, userContext, rootElement) {
// 読み込ませる動 画ファイル名
this.filename = "bsky2.wmv";
// Page.xamlの x:Name="player" の要素。動画表示部分。
this.player = rootElement.children.findName("player");
this.player.Source = this.filename;
this.player.AutoPlay = "false";
// 動画が最後まで再生されたら handleMediaEnded を呼び出す
this.player.addEventListener(
"MediaEnded",
Silverlight.createDelegate(
this, this.handleMediaEnded
)
);
// Page.xamlの x:Name="play_button" の要素。再生ボタン。
this.play_button =
rootElement.children.findName("play_button");
// 左クリックされたら handlePlay を呼び出す
this.play_button.addEventListener(
"MouseLeftButtonDown",
Silverlight.createDelegate(this, this.handlePlay)
);
},
/**
* 再生・停止を扱う。ボタンをクリックするたびに呼び出される
* ついでに再生ボタンのテキストを書き換える
*/
handlePlay: function(sender, args) {
// Page.xamlの x:Name="play_button_text" 要素
play_button_text =
sender.children.findName('play_button_text');
// 動画の再生状態で処理を切り分け
switch (this.player.currentState) {
case "Playing":
// 再生中だったらポーズに
play_button_text.Text = "Play";
this.player.pause();
break;
case "Paused":
// ポーズ中だったら再生
play_button_text.Text = "Pause";
this.player.play();
break;
case "Stopped":
// 停止中だったら再生 使われてない気がする
play_button_text.Text = "Pause";
this.player.play();
break;
default:
alert(this.player.currentState);
}
},
/**
* 動画が最後まで再生されたらシークを先頭に戻す
*/
handleMediaEnded: function(sender, args) {
// 方法がわかんなかったのでSourceを再定義してみたら出来た
// たぶんやり方間違ってる
sender.Source = this.filename;
play_button_text.Text = "Play";
}
}