
Flash Media Server 3 の Streaming 配信
会社で Flash Media Server 3 を触る機会があり、H.264 のストリーミング再生を試してみたのでメモ。
H.264 は従来の On2 VP6 コーデックよりもパフォーマンスと効率が向上した動画圧縮規格で、Flash Player 最新版(Flash Player 9.0.115)であれば、従来の .flv や .mp3 に加え、H264 を使用した他の動画フォーマット(.mov、.avi、.mp4 など)を Streaming 再生させることが可能。Adobe Flash on で HD 画質の動画を普通に見れますが、この画質は恐ろしく奇麗過ぎる!もはや映画レベルの画質をウェブでコンテンツとして普通に配信出来ますね。Flash Media Streaming Server 3 はそこまで高くはなく購入出来るレベルなので、専用サーバ立てて portfolio サイトのコンテンツ配信ぐらいなら十分ですね。どこかの記事で読みましたが、H.264 を Red5 もサポート予定らしいので、ライセンス購入なしに高画質動画配信が可能になる可能性がありますね。
といういことで、Flash Media Server 3 の動画の Streaming 配信の際は、従来の NetConnection.connect の記述がフォーマットの違いによって微妙に異なるので下記に記述します。
▽ メインタイムライン上のソース
*簡潔にするため、class などを使わず直に書いています。
*mp3 ファイルに関しては Sound オブジェクトなどで制御すべきですが、今回は接続方法のみに注目したためそのままで接続しています。
stop();
import flash.display.MovieClip;
import flash.events.AsyncErrorEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;/**
* ///////////////////////////////////
* アプリケーション接続関連設定
* ///////////////////////////////////
*//**
* NetConnection オブジェクト設定
*/
var nc:NetConnection = new NetConnection();
nc.client = new CustomClient();
nc.addEventListener(NetStatusEvent.NET_STATUS, onNcNetStatusEvent);
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onNcAsyncErrorEvent);
nc.addEventListener(IOErrorEvent.IO_ERROR, onNcIOErrorEvent);
nc.connect("rtmp://hogehoge.com:1935/アプリケーション名/インスタンス名(*必要な場合)");/**
* NetConnection onStatus イベントハンドラ関数
* @param NetStatusEvent evt
* @return void
*/
function onNcNetStatusEvent(evt:NetStatusEvent):void {
switch(evt.info.code) {
case "NetConnection.Connect.Success":
trace("アプリケーションへの接続が成功しました。");
playVideo();
break;
case "NetConnection.Connect.Failed":
trace("アプリケーションへの接続が失敗しました。");
break;
case "NetConnection.Connect.Rejected":
trace("アプリケーションに接続する権限がありません。");
break;
case "NetConnection.Connect.Closed":
trace("アプリケーションへの接続が無事解除されました。");
break;
case "NetConnection.Connect.InvalidApp":
trace("アプリケーション名が無効です。");
default:
trace(evt.info.code);
break;
}
}/**
* NetConnection AsyncErrorEvent イベントハンドラ関数
* @param AsyncErrorEvent evt
* @return void
*/
function onNcAsyncErrorEvent(evt:AsyncErrorEvent):void {
trace("AsyncErrorEvent エラー");
trace(evt.toString());
}/**
* NetConnection IOErrorEvent イベントハンドラ関数
* @param IOErrorEvent evt
* @return void
*/
function onNcIOErrorEvent(evt:IOErrorEvent):void {
trace("IOErrorEvent エラー");
}/**
* ///////////////////////////////////
* NetStream オブジェクト関連設定
* ///////////////////////////////////
*//**
* 動画再生用関数
* @return void
*/
function playVideo():void {
// メインの Video 格納用
var mainMc:MovieClip = new MovieClip();
mainMc.graphics.lineStyle(0, 0x000000, 1);
mainMc.graphics.drawRect(0, 0, 320, 240);
mainMc.x = Math.floor((this.stage.stageWidth / 2) - (mainMc.width / 2));
mainMc.y = Math.floor((this.stage.stageHeight / 2) - (mainMc.height / 2));
addChild(mainMc);
// NetStream オブジェクト作成
var ns:NetStream = new NetStream(nc);
ns.client = new CustomClient();
ns.addEventListener(NetStatusEvent.NET_STATUS, onNsNetStatusEvent);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onNsAsyncErrorEvent);
// Video オブジェクト作成
var video:Video = new Video();
video.attachNetStream(ns);
mainMc.addChild(video);
// NetStream 再生
ns.play("mp4:sample.mp4");// sample.mp4 を Streaming 再生する場合
ns.play("mp4:sample.mov");// sample.mov を Streaming 再生する場合
//ns.play("mp3:sample");// sample.mp3 を Streaming 再生する場合(mp3 に関しては video とは関係ないですが、基本的な考えは同じ)
//ns.play("sample");// sample.flv を Steaming 再生する場合
}
/**
* NetStream NetStatusEvent イベントハンドラ関数
* @param NetStatusEvent evt
* @return void
*/
function onNsNetStatusEvent(evt:NetStatusEvent):void {
trace(evt.info.code);
}
/**
* NetStream AsyncErrorEvent イベントハンドラ関数
* @param AsyncErrorEvent evt
* @return void
*/
function onNsAsyncErrorEvent(evt:AsyncErrorEvent):void {
trace("NetStream の非同期エラー");
trace(evt.toString());
}
▽ CustomClient クラス
package {
public class CustomClient {
/**
* onBWDone イベントハンドラ関数
* @return void
*/
public function onBWDone():void {
trace("onBWDone");
}
/**
* onMetaData イベントハンドラ関数
* @param Object infoObj
* @return void
*/
public function onMetaData(infoObj:Object):void {
trace("onMetaData");
}
/**
* onPlayStatus イベントハンドラ関数
* @param Object infoObj
* @return void
*/
public function onPlayStatus(infoObj:Object):void {
trace("playStatus");
}
}
}
▽ 注意点
FMS 3.0 のデフォルトのアプリケーション(vod)に接続すると、onBWDone という関数が各 client オブジェクトに対して call されて呼び出され、非同期エラー(AsyncErrorEvent)が返ってきました。これは main.asc で Application.onConnect 時に呼び出されている関数で、これもここでは CustomClient クラスに追記しました。main.asc はその他関連ファイルと共に、 main.far というパッケージ化されたファイル内に含まれているので、もし詳しく main.asc の内容を見たい方は、unzip main.far をすることで、内部のファイル一覧に解凍し、main.asc を見ることが出来るようになります。
今シーズンは素材用にと結構スノボー動画を Xacti CA-65 で撮影してましたが、やっぱりさらに高画質を目指したいので Xacti HD700 辺りで撮影して、H.264 形式で配信もいいなとか思います。
【使用環境】
Flash CS3 Professional、Flash Media Server 3、Flash Player 9.0.115











