アプリケーションサーバ(今回は Red 5 を使用)から streaming 配信で flv ファイルを Flex Framework の VideoDisplay Component に表示しようと思ったが、イベントドリブン的なプログラム内で、任意のタイミングにより FLV を seek させて動画の PlayHead を管理しようと思ったがうまく処理が動かなかった。(上手くいくかもしれないですが、自分ではどうにも出来なかった。)
例えば、下記の様なクリックイベントで flv の streaming 配信させる簡単なスクリプトを組んでみる。これでも streaming 配信は可能なのだが、NetStream.seek の様な PlayHead の移動をさせる機能を持ち得ていないので、最初から再生させるには flv の再生が終了するのを待って再度クリックしないと先頭から再生しない模様。もっとも VideoDisplay の仕様的に、AutoRewind も streaming には対応してないみたいだし、試した限りでは、再生中はクリックしても特に何も変化せず動画は普通に再生し続けた。
▽ MXML ソース
<mx:Script>
<![CDATA[
private function playVideo():void {
var flvname:String = "rtmp://hogehoge.com/app/sample.flv";
local_video.source = flvname;
local_video.play();
}
]]>
</mx:Script><mx:VBox>
<mx:VideoDisplay id="local_video" width="320" height="320" />
<mx:Button label="再生" click="playVideo()" />
</mx:VBox>
今回はもろもろ動画の PlayHead を操作したかったのでどうしようか考えたのですが、色々と調べた結果、UIComponent に Video オブジェクトを addChild し、その Video オブジェクトに attachNetStream する NetStream を通常の ActionScript の操作で制御する方が都合が良さそうな様なのでメモ。(他のやり方など知っている方は是非教えてください!)
今回は下記の様にかなりシンプルなソースにしましたが、実際には UIComponent を extends してクラス化した方が後々便利です。
▽ MXML ソース
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
import flash.media.Video;
import flash.media.Camera;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.Event;
import flash.events.AsyncErrorEvent;
private var uiC:UIComponent = new UIComponent();
private var video:Video = new Video(320, 240);
private var rtmp:String = "rtmp://hogehoge.com/app";
private var nc:NetConnection;
private var ns:NetStream;
private var isStreamed:Boolean = false;
private function init():void {
nc = new NetConnection();
nc.connect(rtmp);
uiC.addChild(video);
videoContainer.addChild(uiC);
}
private function playVideo():void {
if(!isStreamed) {
ns = new NetStream(nc);
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
ns.client = new CustomClient();
video.attachNetStream(ns);
isStreamed = true;
}
ns.seek(0);
ns.play("sample.flv");
}
private function asyncErrorHandler(event:AsyncErrorEvent):void {
trace("asyncErrorHandler");
}]]>
</mx:Script>
<mx:VBox>
<mx:Canvas id="videoContainer" width="400" height="400" />
<mx:Button label="再生" click="playVideo()" />
</mx:VBox>
</mx:Application>
▽ CustomClient class
package {
public class CustomClient {
public function onMetaData(infoObject:Object):void {
trace("metadata");
}
public function onPlayStatus(infoObject:Object):void {
trace("onPlayStatus");
}
}
}
記述量は増えましたが、最初の例の VideoDisplay では出来なかった再生中の動画の seek は出来る模様。やっぱり Flashguru にも書いている様に VideoDisplay は独自に NetConnection は操作するみたいだが、NetStream オブジェクトへの操作機能は何もない様だ。What the heck !!!
p.s.
AIR 書き出ししたアプリケーションから Red5 v0.6 RC3 以前の Red 5 には NetConnection で接続出来なくなった。Flex Project では接続出来るのに、謎。AIR の beta 1 までは動いていたはずなので、Flex Builder beta 2 以降で objectEncoding の設定が変わったのか?RunTime の仕様?これに関しては冬休みに調査してみよう。
【使用技術】
Flex Framework, ActionScript 3.0, Red 5
【参考サイト】
Flash Guru 記事:Playing a live FMS stream using VideoDisplay in Flex2











