ActionSctipt 3.0

MouseEvent in ActionScript 3.0

数週間前からようやく最新バージョンの ActionScript 3 を個人的に勉強し始めました。
手始めに、ActionScript というよりは、Object Oriented Programming の基本概念や Java などの本をこの数週間読みこんでいた。今後も引き続きこんな日々が続くと思う。結構、面白い。

Adobe の ActionScript に対する打ち出し方は ActionScript 1, 2 は従来の Flash Designer、ActionScript 3 はプログラム重視の Flash Developer らしいですが、確かに使ってみて、ActionScript 3 はデザインや表現などと絡める場合にはあまり適さず、ActionScript 2 の方が flexibility が 高いような気がする。(少なからず、今までのところ。)もともと売りは大規模なアプリケーションを UI でリッチな形で提供したい場合とか、これまで Java などで開発してたプログラマーの人が Flex で mxml と ActionScript 3 を使用して簡単に Rich Internet Application 開発出来る様にすることだと思うので、ActionScript 3 の流れは実際、理にはかなっているのかと思う。それでも、Adobe のセミナーなどで見て Flash Player 9 の新しい Virtual Machine の処理速度がかなり向上しているようだったので、ActionScript 3 のこれからの可能性は大きく感じる。何より、新しい言語スタイルに触れることは楽しい。

当分、自分への ActionScript 3 の整理を兼ねて、blog を定期更新していこうと思う。



まずは、MouseEvent。

この記事の続きを読む »

ページの一番上へ移動

E4X in ActionScript 3.0

従来の ActionScript 2.0 でサポートされていた XML Class は XML Document と名前を変更し flash.xml package 内に移行され、ActionScript 3.0 からは XML データを処理するために、ECMAScript for XML (E4X) specification がサポートされた。
E4X とは ECMA-357 standard の ECMA International によって標準化された XML を処理する ECMAScript 拡張言語。このクラス導入により、Flash 内での XML parse 処理が格段に容易になっただけではなく、標準化された言語仕様に基づくことで、Javascript 等の他言語へのノウハウのバイパスがスムーズになりそう。


ECMAScript for XML


今回は、現在個人制作で Flickr を使った簡単ツールを作っているため、この制作過程のものをサンプルとして使用し、Zend Framework で Flickr API から取得した情報を XML 形式で書き出し、この XML を E4X で parse する様にする。

【サンプルファイル】
http://www.convexstyle.net/samplefiles/E4X/test.xml
http://www.convexstyle.net/samplefiles/E4X/E4X.zip

この記事の続きを読む »

ページの一番上へ移動

ActionScript 2.0 と ActionScript 3.0 における名前空間処理

Flickr の個人アカウントページにある RSS Feed(RSS 2.0)は api.flickr.com 上に置かれており、http://api.flickr.com/crossdomain.xml で確認できるように、<allow-access-from domain="*"/> 設定なので、別サーバからでも crossdomain 問題を回避してこの XML を Flash 内で利用できる。Flickr では便利な API が準備されているので特に RSS を使用しなくても様々な事ができるが、簡単にブログパーツを作る際などはこの RSS が結構便利。

ということで、これを ActionScript 2.0 で解析し、同様な事を ActionScript 3.0 で行った。
サンプルの RSS Feed は下記の自分のモノを利用した。今回は、この RSS の構造から各 item ノード内のノード値と media:text ノード内のノード値を取得してみる。


Flickr screenshot
Flickr account screenshot


ActionScript 2.0(以下、AS 2.0) ではこの解析はすんなり行うことができる。
AS 2.0 の解析プログラムの例は以下の通りである。

【サンプルファイル】
download AS 2.0 file



stop();

// 初期設定
var path:String = "http://api.flickr.com/services/feeds/photos_public.gne?id=53418554@N00&
format=rss_200";
var xmlObj:XML = new XML();
xmlObj.ignoreWhite = true;

function parseXML(xml:XML):Void {
var mainNode:XMLNode = xml.firstChild.firstChild;
var channelNodesNum:Number = mainNode.childNodes.length;
for(var i:Number = 0; i < channelNodesNum; i ++) {
if(mainNode.childNodes[i].nodeName.toLowerCase() == "item") {
var itemNodesNum:Number = mainNode.childNodes[i].childNodes.length;
for(var j:Number = 0; j < itemNodesNum; j ++) {
if(mainNode.childNodes[i].childNodes[j].nodeName.toLowerCase() == "link") {
// link ノード のノード値取得
var linkNodeValue:String =
mainNode.childNodes[i].childNodes[j].firstChild.nodeValue;

trace(linkNodeValue);
}
if(mainNode.childNodes[i].childNodes[j].nodeName.toLowerCase() == "media:text") {
// media:text ノード のノード値取得
var mediaNodeValue:String =
mainNode.childNodes[i].childNodes[j].firstChild.nodeValue;

trace(mediaNodeValue);
}
}
}
}
}

xmlObj.onLoad = function(success:Boolean):Void {
if(success) {
parseXML(this);
} else {
trace("XML 解析エラー");
}
}
xmlObj.load(path);


しかしながら E4X に完全準拠した ActionScript 3.0 (以下、AS 3.0)では上記の様に単純に media:text をノード名に見立てて RSS を解析することは出来ない。なぜなら、AS 3.0 では名前空間という概念を含んでおりmedia:text は media という名前空間に属しているとみなされ、同様に、media:content、media:title、media:thumbnail、media:credit、media:category 等も同じ名前空間に属しているためである。

名前空間を使用した要素名・属性名の書き方
名前空間の識別子:要素名
名前空間の識別子:属性名

そのため、まず、取得したいノードがどの名前空間に属しているか設定する必要がある。
今回は media:text は media という名前空間の text という要素名なので、これを E4X に基づいて記述する。link ノードのノード値に関しては通常の E4X の RSS 解析で簡単に取得できる。
AS 3.0 の解析プログラムの例は以下の通りである。

【サンプルファイル】
download AS 3.0 file



stop();

// クラスファイル読み込み
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.xml.XML;
import flash.events.*;
import flash.error.*;

// URLLoader 設定
var ULoader:URLLoader = new URLLoader();
configureListeners(ULoader);

function configureListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, completeHandler);
}

// complete イベントハンドラ 設定
function completeHandler(event:Event):void {
var xmlObj:XML = new XML(ULoader.data);
var nodeNum:Number = xmlObj..item.length();
for(var i:Number = 0; i < nodeNum; i ++) {
// link のノード値取得
var linkNodeValue:String = xmlObj..item[i].link.text();
trace(linkNodeValue);
// media:text のノード値取得
var ns:Namespace = xmlObj..item[i].namespace("media");
var mediaNodeValue:String = xmlObj..item[i].ns::text;
trace(mediaNodeValue);
}
}

// URLRequest 設定
var path:String = "http://api.flickr.com/services/feeds/photos_public.gne?id=53418554@N00&
format=rss_200";
var URequest:URLRequest = new URLRequest();
URequest.url = path;
try {
ULoader.load(URequest);
} catch(e) {
trace(e.message);
}

まず、AS 3.0 では複数ある item ノードを childNodes などを使わず、「..」を使用することにより Array として取得できる。(元の XML オブジェクト)..item で簡単に取得可能。その Array の length は(元の XML オブジェクト)..item.length である。また、item ノードの子ノードである media:text は namespace 関数によって名前空間を取得し、「::」でその要素名を特定できる。そのため、(元の XML オブジェクト)..item[incrementの数].namespace("名前空間")::要素名、つまり、(元の XML オブジェクト)..item[incrementの数].namespace("media")::text で取得できる。


E4X 準拠の XML 解析は最初は多少戸惑ったが、仕様さえ理解すれば AS 2.0 より数倍簡単に解析できてしまう事が素晴らしい!また他の言語でも E4X に準拠していく流れからすると、ActionScript 単体で完結するのではなく、他の言語に応用できるのが個人的には無駄が無く納得した。なお、今回は説明中心のため、あえて link と media:text を取得して trace だけしているが、この情報を Array に格納して
Flash 内で表示さえさせればブログパーツは簡単にできてしまう。また、media:text もしくは description のノード値はコレだけでは使えないのでさらに String を解析するし必要な部分を取得する必要がある。ここでも AS 2.0 と AS 3.0 では処理的に大きな違いがある。何故なら AS 3.0 から正規表現が使えるようになり、より効率よくなっているからである。次はここについて説明しようと思う。

最後に RSS 2.0 が面倒な場合は Feed URL の最後の「&format=rss_200」を消してしまえばよりシンプルな形になるのでこっちを解析した方が多少楽。


【使用環境】
Flash 8 Professional、Flash 9 Public Alpha

ページの一番上へ移動

ActionScript 3.0 での objectEncoding 概念

実家に里帰りして、桜祭りで AE-1 で写真撮影。リラックス出来ました。


ActionScript 3.0 でヘテムルのインフラを使い FMS アプリケーションに接続するテストをしてみた。接続の考え方は ActionScript 3.0 以前と同じなので ActionScript 3.0 の記述形式さえ書ければ特に問題ないが、objectEncoding の概念を理解していなくて接続に少し手間取ってしまった。理解されている方は特に問題ないのですが、自分は知らなかったのと検索してもあまり詳しく書いていなかったのでメモ。

ActionScript 3.0 での objectEncoding 概念
ActionScript 3.0 での objectEncoding 概念概略図


アプリケーションサーバと Flash アプリケーションの通信のデータフォーマットは Action Message Format(AMF)でバイナリデータを送受信しているのだが、Flash Player 9 リリース以前はアプリケーションサーバへの接続には AMF のバージョンが 0(AMF0)を使用していたが、Flash Player 9 リリース以降の Flex 2.0 の様なアプリケーションサーバへの接続にはデフォルトで AMF のバージョンが 3(AMF3)が使用されている。Flash Player 9 は ActionScript 3.0 用の VM を搭載している様に、AS 3.0 ではすでにデフォルトで AMF3 がサポートされているので、ヘテムルでプレインストールしている Flash Media Server 2.0 や Flex 1.5 の様な Flash Player 9 以前にリリースされたアプリケーションサーバは AMF0 のみをサポートしているという矛盾から、今回接続が上手くいかなかった。

対応策は簡単で、ActionScript 3.0 内で明示的に NetConnection オブジェクトで FMS アプリケーションに接続する際の AMF のバージョンを objectEncoding プロパティで AMF0 に変更することで接続は出来るようになる。これは最近結構使っている RED 5 でのアプリケーション接続時も同様。

以下、簡単なサンプルソース(fmsEx.as)。


package {

import flash.display.*;
import flash.net.*;
import flash.events.*;

public class fmsEx extends Sprite {

private var _nc:NetConnection;

// コンストラクタ
public function fmsEx() {
_nc = new NetConnection();
_nc.objectEncoding = ObjectEncoding.AMF0;
_nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
_nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
_nc.connect(rtmp://******.fms.heteml.jp/アプリケーション名/[任意]インスタンス名);
}

// NetConnection の NetStatusEvent 用関数
private function netStatusHandler(evt:NetStatusEvent):void {
switch(evt.info.code) {
case "NetConnection.Connect.Success":
// FMS アプリケーションへの接続に成功
break;
case "NetConnection.Connect.Failed":
// FMS アプリケーションの接続に失敗
break;
case "NetConnection.Connect.Rejected":
// FMS アプリケーション接続権限がありません
break;
case "NetConnection.Connect.Closed":
// FMS アプリケーションが無事に閉じました
break;
default:
// その他
}
}

// NetConnection の SecurityError 用関数
private function securityErrorHandler(evt:SecurityErrorEvent):void {
// セキュリティエラー
}
}
}


【開発環境】
Flex Builder 2.01、ActionScript 3.0、Flash Media Server 2.0、Flex SDK
*テストでは Red5 使用。


【参考サイト】
livedocs.adobe.com

ページの一番上へ移動

FlashVars in ActionScript 3.0

ActionScript 3.0 で開発中、何気に FlashVars の変数を取得しようと思ったんだけど、そういえば!

従来のActionScript 2.0 で FlashVars で渡ってきた変数を _root からアクセスして簡単に取得するやり方は ActionScript 3.0 だったら_root が removed されてるから当てはまらないですよね。どうするんだっけと思い検索したらやっぱり変更していたのでメモ。

Shape, Sprite, Bitmap, SimpleButton, TextField, MovieClip class 等は DisplayObject(display list に見なされるすべてのクラスの基盤クラス)の subclass に当たり、この DisplayObject が読み込まれる大本の swf の loaderInfo プロパティ から FlashVars は取得できる出来る。正確に言うならば extends して作った自分のクラスから辿って、 "Myclass.root.loaderInfo.parameters" から取得できる。

サンプルファイルは下記の通り。


// HTML 側
<object>
<param name="FlashVars" value="myname=convexstyle" />
<embed src="***.swf" FlashVars="myname=convexstyle" *** />
</object>


// ActionScript 側
package {
import flash.display.Sprite;
public class test extends Sprite {
private var myname:String;
public function test() {
var flashVars:Object = this.root.loaderInfo.parameters;
myname = flashVars['myname'];
trace("my name is" + myname);// my name is convexstyle と trace される。
}
}
}

ページの一番上へ移動

KeyboardEvent in ActionScript 3.0

キーボードのイベントって AS 1.0~2.0 は何気に swf を html 上でクリックしてアクティブにしていましたが、AS 3.0 ってきっちり明示しないとだめでしたね。この本には普通に書いてましたが、洋書を参考にビジュアライズしてたら見逃して、ちょっと悩んでしまったのでメモ。

swf コンテンツをクリック(自分は stage をクリックしたイベントを取得)したイベント内で stage の focus プロパティで動かしたいオブジェクト(interactiveObject)を"stage.focus = interactiveObject" してキーボードイベントを interactiveObject に対してアクティブにする。今回は interactiveObject 用に square class を設定しました。


参考スクリプトは下記に。

この記事の続きを読む »

ページの一番上へ移動

Lightweight Remoting Framework

Lightweight Remoting Frameworkdanny patterson さんがリリースした ActionScript 3.0 のみで使用できる Remoting Framework で、サーバへの Remoting 接続が容易にできる。
ActionScript Project しか試してないけど、swc もあるんで、おそらく Flex Project 内でも使用できるではないだろうか。

使い方は凄い簡単で osflash を確認してもらえばすぐに使い方が理解できると思うんですが、この Framework というか Design Pattern を理解すれば、Custom Event とか Event Dispatcher の流れが分かるのでソースは目を通したら結構為になる。メインクラスで管理したい addEventListener で設定する任意のイベント(イベントハンドラ系)をどの様に独自にカスタマイズして dispatch するとかきっちり理解できた。

最新版は直接ブラウザからファイルを保存するか、svn checkout で取得できる。


*彼の著書 "Advanced ActionScript 3 with Design Patterns"

ページの一番上へ移動

Flickr RSS 解析 in AS 3.0

個人の Flickr RSS って便利になりましたね。
最近ふとFlickr の RSS を見たら、以前は M サイズ画像情報のみだったので URL の規則性ですべての画像データ情報を取得していたけど、今はサムネール画像・M サイズ画像・オリジナル画像のパーマリンク、幅、高さがすべて表記されてるんですね。これだと簡単に個人のブログパーツやスライドショーや photogallery くらいはすぐ作れるし、E4X で簡単に XML を解析できるようになったので再利用をかねて個人用に ActionScript 3.0 の解析 class(ParseFlickrXML)を作ってみた。Flickr API を使うならこのクラスがいいと思うけど、自分の RSS を解析するだけだとこれでいいかなと。

ちなみに結構前に作ったので今思うのは、XML の解析用のクラス(ParseFlickrXML)自体が EventDispatcher クラスを extends したら他のイベントクラスは必要なかったし汎用性があると思うけど、作成時はこんなもんだったんで今後直します。

この記事の続きを読む »

ページの一番上へ移動

SQLite in AIR

Apollo Mini Camp で Apollo for Adobe Flex Developers 等の著者の Mike Chambers さんが AIR から SQLite を導入すると話していましたが、AIR より実際に導入されたので、現在開発中の AIR アプリケーションに実際に実装してみた。もともと必要な情報を FileStream クラスでローカルに xml の様なファイル書き出ししようかと考えていたが、データをもっと Secure に扱いかったので SQLite を使用。まだまだもっと使えて欲しいなあ…という部分もけっこうあるんですが、まあ、Beta の段階だしね。

使用方法は、基本的な SQL 構文の知識と AIR で実装されている SQLConnection class、
SQLStatement class、SQLResult class、File 系の class 辺りを連携させることで、至って簡単に使用することで実現できる。

この記事の続きを読む »

ページの一番上へ移動

VideoDisplay では NetStream.seek 機能は実現出来ないのか?

アプリケーションサーバ(今回は 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>


この記事の続きを読む »

ページの一番上へ移動

for each in

数ヶ月前に個人的に一発奮起して Canon 30D を購入したのですが、それ以来写真の面白さにのめり込んでしまいました。Flickr を写真サイトのメインとして使っているんですが、今までのベスト写真アーカイブを表示する photoViewer を自前で作成しようと思い、その前に Flickr のベストフォトを取得する flickr.interestingness.getList API をベースに基本ロジックを作成しています。

ActionScript 3.0 から for each in が追加されて XML の解析が凄い簡単かつ明瞭になりました。従来は XML の処理は firstChild や childNodes など毎回冗長的に記述していかなければならなかったですが、E4X と for each in の連携によって XMLList オブジェクトを解析するのは PHP でいう foreach 的な使い勝手で今更ながら感動です。


この記事の続きを読む »

ページの一番上へ移動

独自 showBusyCursor 表示方法

RPC 処理や HTTPService 処理中に表示される busy カーソル。
s2flex2-componentsRemoteObject を使用して Flex(AIR)アプリケーションとサーバプログラムを Remoting で連携して何かを処理する場合、showBusyCursor="true" にすることで、サーバプログラムが任意の処理を行っている際にデフォルトのくるくる回るカーソルを表示することができるが、独自のカーソルやプログレスバーを表示したい場合があるので、その独自のカーソルやプログレスバーを表示する方法をメモ。

この記事の続きを読む »

ページの一番上へ移動

JUGEM Desktop

JUGEM Desktop

Adobe Integrated Runtime Beta 3 上で動作する JUGEM Desktop というアプリケーションの開発に携わり 1/29 にリリースしました。ウェブカメラの動画を記憶ストリームとしてアプリケーションサーバー上に一時的に保存し、ユーザーアクションによって動画をウェブディレクトリに保存し、JUGEM 各ユーザーのブログコンテンツとして使用できるという仕様。今回は最近動画に力を入れている ASK.jp と連携しデコワクを使用するため、ASK で提供された API を使用し、最終的に記憶ストリーム(.flv)を ASK 側に POST する形を取りました。(ローカルの DV ファイルをアップロードするウェブ版は去年末に開発しました。)

JUGEM Desktop の現状の機能自体は Flash Developer や Flex Developer の方にはいたって基本の機能で、すでにウェブ上のアプリケーションでもウェブカメラの動画投稿ができるものを多くみているし、個人的にもウェブでは3度程、記憶ストリームを利用したアプリケーションを仕事や個人ワークで開発しているので、目立って新しいことをしたという訳ではないですが、とにかく、JUGEM というブログサービス(対何十万人)を相手にするための対サービス型のアプリケーション開発は結構シビアで目に見えない部分で苦労しました。後、AIR アプリケーションは"既存のスキルをローカルアプリケーションに使用でき簡単に開発できる"という風に聞いていましたが、やってみると Flex Framework をきっちり理解していないと難しいなと痛感。自分見たくゼロから Flex を始めた方はまずは Flex で詰まりそう。特に、Flash 完結したアプリケーションを AIR 書き出しするために Flex Framework を使用する場合と違い、ユーザーインタラクションがある場合はなおさらかなと思います。MVC 設計を意識し今後の開発での汎用性を意識していたけど、自分のスキルがまだまだです。でも思いました。今まで企業サイト・サービス・個人ワークで目的は違えど何とか新しいクリエイティビティを表現したい!と開発やデザインしてきましたが、AIR アプリケーションの様に、決まった動作を論理的に考えて開発するのも気持ちいい!なあと。一発ギャグ的なアプリケーションもいいけれど、「ウェブライフをより便利に!」って考えて作った方が AIR はより最適かなと思います。例えば、teknision が開発した Finetune Desktop は自分には凄い使い勝手がよく、I-Pod Shuffle 的にいい音楽を偶然探すには最適です。

ということで、使っていただくと分かると思いますが機能的には全くまだまだです。
開発は1人作業なので時間が限られているのですが、引き続き Flex を勉強しながら時間がある限り新しい機能を追加していきます。Flex Beta 3 もまだまだ問題点とかが多いけれど、正式版が出る時に fix されているのを期待したい!


【使用技術】
Flex Builder 3 Beta 3, Flash CS 3 Professional, Flex Component Kit, AIR API, ActionScript 3.0, PHP 4, AMFPHP, ASK API, Smarty, PEAR, MySQL, SQLite, Application server on Linux, Photoshop CS 3


【担当領域】
Flex Builder 3 Beta 3, Flash CS 3 Professional, Flex Component Kit, AIR API, ActionScript 3.0, PHP 4, AMFPHP, ASK API, Smarty, PEAR, MySQL, SQLite, Application server

ページの一番上へ移動

マルチアプリケーションを1つの AIR アプリケーションで管理

AIR アプリケーションで大きく分類して1つの機能のみを保持する場合は、特に意識せずに開発すればいいんですが、ふと、機能が横並び的に拡張して、親アプリケーション(mx:WindowedApplication や mx:Application)ではそのレイアウトのみを管理し、各子クラスがそれぞれ1つのアプリケーションの単位として考えられる場合はどうやるんだろう・・・と思ったので、調査してみた。
要は、各アプリケーションを表すアイコンがズラッと並んでいるだけで、各アイコンをクリックした時点で、各アプリケーションが起動する感じにしたい。

mx:Window 概略図
mx:Window 概略図

この記事の続きを読む »

ページの一番上へ移動

H.264 動画を Flash Media Server 3 より Streaming 再生

Flash Media Server 3 の Streaming 配信
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 の記述がフォーマットの違いによって微妙に異なるので下記に記述します。

この記事の続きを読む »

ページの一番上へ移動

H.264 動画の Progressive 配信

H.264 動画の Progressive 配信


前回のエントリーで、Flash Media Server 3 を使用した Streaming 配信に関して記述しましたが、今度はウェブディレクトリより通常の Progressive 再生をしてみたのでメモ。

前回は NetStream.play の記述は ns.play("mp4:sample.mp4"); や ns.play("mp4:sample.mov"); の様な形式で記述し Streaming 再生させていたが、Progressive 再生では NetConnection.connect(null) にして同様な記述では H.264 の動画コーデックで作成された MPEG-4 や MOV を再生できないようだ。

もろもろ調べていたら flashcomguru の記事に同様な問題で、下記の様な記述が。
"That did the trick and my mp4 files now use a naming convention of Rendition.mov.flv, even though it complained that the file can't be opened. trust me it can once you run it in a browser."

要は、.mp4 や .mov も .flv として見立てて、ファイルの拡張子を例えば sample.mp4.flv や sample.mov.flv に変更し、NetStream.play の記述を ns.play("sample.mp4.flv"); やns.play("sample.mov.flv"); に変更し、サーバにアップロードすれば動作する。
*ただし .flv の時は 拡張子を削除して ns.play("sample.mp4"); や ns.play("sample.mov"); の様に記述したいところだが、ns.play("sample.mp4"); では動作したが、ns.play("sample.mov"); では 404 エラーが返ってきた。ここら辺の挙動はどうなのか。

flashcomguru からはサンプル fla をダウンロードでき、そちらでは FLVPlayback を使用しているので、source プロパティに拡張子を変更したファイルの絶対パス(例:http://hogehoge.com/flv/sample.mov.flv)を指定して動作させている。

次の Flash Player 辺りで改善されそうな内容ですが、一時的な改善策としてこんな感じらしい。念のため、ソースは下記に。

この記事の続きを読む »

ページの一番上へ移動

JUGEM Desktop x Flickr

社内のブログサービス(JUGEM)で、以前開発していた JUGEM Desktop を 1.2 より 2.0 にアップデートしました。

Flickr 機能を追加し、自分の Flickr スクリーンネームでログインすれば、ブラウザ経由ではなく、AIR アプリケーションから直接ブログに最大8枚までの Flickr 写真とともに記事をエントリーすることができます。インタフェース的にはドラッグ&ドロップで写真を記事に追加する感じです。

写真好きな人とか、Flickr は Englishで JUGEM は日本語で切り分けたい人とか、ブラウザ経由が面倒な人はどうぞ。

詳細:http://jugem.jp/fun/jugemdesktop/

JUGEM Desktop 2.0
JUGEM Desktop 2.0


【使用技術&環境】
Flex Builder 3.0、Flash CS 3 Professional、ActionScript 3.0、AMFPHP 1.9、PHP、PEAR、Smarty、MySQL、Linux、Flickr API、PhotoShop CS 3


【担当領域】
Flash、プログラム、データベース、サーバ、デザイン(AIR アプリ側)
*JUGEM の紹介ページデザイン&コーディングは野原君が担当。色々どーもでした!

ページの一番上へ移動

Flashvars モジュール化

FlashVars は ActionScript 3.0 からオブジェクトとして処理出来るので、汎用的にモデルクラスにオブジェクト突っ込もうと思ってモジュール作成。

色んなやり方があるとは思うけど、FlashVars の可否に関わらず、view で Event を dispatch しておいて、controller がある場合はそれを model クラスルートクラスが格納する仕組み。これだとすべての view クラスが model の参照を持っている前提で必要な時だけすべての view 系のクラスからいつでもオブジェクトを取得出来るので、key(FlashVars の変数名)さえ渡せばどこでも使用出来る。基本の view が dispatch して controller がそれを listen して model を操作っていう MVC パターンでのモジュール化。

サンプルはドキュメントクラス Main でそこで MVC を作成している例。
(CF ってのは convexstyle framework の略なので気にせず!)

package {
	public class Main extends CFComponentMC {
		import controller.CFController;
		import flash.events.Event;
		import model.CFModel;
		import view.CFView;
		import view.events.FlashvarsEvent;
		public function Main() {
			this.addEventListener(Event.ADDED_TO_STAGE, onInit, false, 0, true);
		}
		private function onInit(evt:Event):void {
			var m:CFModel      = new CFModel();
			var v:CFView         = new CFModel();
			var c:CFController = new CFModel();
			// この FlashvarsEvent を FlashvarsController が listen している
			v.dispatchEvent(new FlashvarsEvent(FlashvarsEvent.SAVE, this.stage.loaderInfo.parameters));
		}
	}
}
package {
	public class FlashvarsController extends CFController {
		import controller.CFController;
		import view.events.FlashvarsEvent;
		public function FlashvarsController() {
			super();
			this._view.addEventListener(FlashvarsEvent.SAVE, handleFlashVarsSave, false, 0, true);
		}
		private function handleFlashVarsSave(evt:FlashvarsEvent):void {
			this._model.flashvars = evt.flashvars;
		}
	}
}

個人的にはこのやり方が気持ちいいな。
取得の際は、key(ここでは test)で取得するだけなので、どの View クラスでも気兼ねなく使える。

if(!ObjectUtil.isNull(this._model.flashvars["test"])) {
    // do action
}

この記事の続きを読む »

ページの一番上へ移動

Zend_Amf_Server

Zend Framework + AS3/Flex ユーザーの自分にとっては Zend と Adobe が提携して Zend_Amf_Server がリリースされたので、おっ!って感じで早速使ってみた。

これまでは AMF 通信の際は AMFPHP 1.9 を使っていて特にこれで問題は無いけれど、Zend Framework がインクルードされている環境では Zend_Amf_Server はすぐに使えるし、個別にパッケージをダウンロード出来るのでそれだけアップロードしても使用可能。Zend Framework ベースでデータベース連携とかするなら PHP 5 / MySQL 5 とか推奨なので、環境が無い場合はこれまで通り AMFPHP + PEAR 辺りで Flash と連携して特に問題ないと思う。一応、Cairngorm Framework とともに使ってみたけど使い勝手に特に問題ないし、外国人の開発陣も結構興奮している模様なんで、次のアプリケーション開発で環境が整う場合には、設定とか簡単だし Zend_Amf_Server を使ってみよう。

使い方。

(1)任意のサーバディレクトリに server.php(名前は何でも OK。)を作成し、下記の様に AMFServer を作成する。ブラウザ経由でこのページに直接アクセスしダウンロードが開始されるか、システムコマンドでアクセスして <p>Zend Amf Endpoint</p> と表示されたら設定完了。ただしこのままだと AMFServer が設定されただけなので、実際に Flash/Flex から呼び出す関数を持った PHP class(ここでは、Test.class.php)を setClass 関数で AMFServer インスタンスにアタッチする。また、名前空間を使用し複数のクラスをセットしたり、特定のディレクトリごとすべて含める事が出来る。これを設定する事で、Flex 側から RemoteObject の source プロパティで PHP 側のクラスファイルを記述する必要が無くなる。また、setClassMap 関数で明示的に DTO にも対応させることができるのは AMFPHP とは設定は多少違う。

AMFServer 用の php ファイル設定(http://あなたの URL/server.php)

<?php
require_once('Zend/Amf/Server.php');
require_once('class/Test.class.php');

// Zend_Amf_Server Object
$server =& new Zend_Amf_Server();
$server->setClass('Test');
//$server->setClassMap('TestVO', 'TestVO');
$response =& $server->handle();
echo $response;
?>

Test class(AMFPHP 用クラスファイル)
*今回は簡単な helloWorld 関数を持った Test クラスを作成する。

<?php
class Test {
    /**
    * Construct Function
    */
    public function __construct() {
    }
    /**
    * Function to helloWorld
    * @param  String name
    * @return String
    */
    public function helloWorld($name') {
        return 'Hello, ' . $name;
    }
}
?>

この記事の続きを読む »

ページの一番上へ移動

Zend_Amf_Server + AS3

個人的に勉強していた Zend_Amf_Server を実レベルの仕事で初めて Flash Remoting として使ってみた。プロジェクトは Flash ゲームで、もう 1 人の Flash デベロッパーと連携してゲーム以外の AS3 のバックエンド/モデルクラス/ビュークラス/コントローラ系のプログラム、Remoting 系、PHP/MySQL 開発、サーバ少々を担当。

Zend_Amf_Server は物凄くいいですね。何がいいかって Zend を普通のウェブアプリケーション感覚で開発できるので連携するバックエンド部分を MVC で組めるし、Zend_View_Smarty とか Zend_Db_Table とか Zend_Registry とか Flash と連携することを意識しないで使えるから超楽だ。Zend を使ってる Flash デベロッパーなら学習コストなし。PHP/MySQL 系のウェブアプリケーションに作っていた Zend のクラス群を Flash Remoting 用にそのまま引っ張ってきて再利用できたので、よっぽどシステムがでかくなければ簡単に作れちゃう感じですな。

で、Zend_Amf_Server で注意したい点を忘れないようにメモッておく。

この記事の続きを読む »

ページの一番上へ移動

AddThis + AS3, AddThis モジュール化

まずは関係ない話ですが、ようやくワークビザが政府に正式に認可されて4年間は合法的に働ける様になりました。今世界的な不況でビザの認可が相当厳しいらしく日本人に対しては永住権もなかなか下りないみたいだし、ワークビザ取得は相当ラッキーみたいです。

自分はオーストラリアの首都シドニーにいるんですが、ウェブ業界は日本より遅れているだろうとか考えていたんだけれど、一定の分野だといやいや自分が相当遅れている事に気づいて、最近必死に遅れたものを取り返そうともがいてる毎日を送っています。ただし働き方や考え方や制作スタイルも違うから日本の考えを捨てるのに苦労してるけど、大変だけど毎日それなりに充実な毎日を送っています。日本人の技術者ってみんな技術があるから海外でも十分通用するというのが実感だけど、それ以上に語学力が凄い重要だな!って思います。何をするにも技術的なことを説明するのがとにかく難しい。「ここはこういう技術の解決策で、こういう風にしたい。」とか「こんなシュッシュって動くモーションに仕上げたい。」とかアイディア出しのミーティングそのものとか。日本語でも説明が難しいし、カナダに4年間留学してたからそれなりに英語に自信はあったけど、オーストラリア訛りと専門的な話はまだまだだなあとか感じます。こうしたらもっと良くなるのにっていうことを意図を伝えれないばっかりに諦めざる得ない部分もあるし、ウェブに限らず海外で仕事している人達ってこういう歯がゆさを感じてるんだろうなって思います。それにしてもビール飲んで話している時はあんなに英語の調子いいのに。。とにかくこのままでは日本に帰れないので、4年はオーストラリアには居ないと思うけど、毎日頑張ってそれなりのものを克服していかないとと思う日々です。一度日本を離れると身軽に色んな国で働いてみたいと思えるし、もうちょっと自信がついたらオーストラリアを離れて他の国に移りたいとか思ってます。

AddThis

で、話を技術に戻して Flickr, Google ぐらい(日本の時は Amazon, Rakuten も)のサービスしかメインで使っていない自分は、ウェブサービスの動向への感覚が物凄い鈍いんですが、海外のウェブ制作会社に依頼がくる Flash コンテンツにウェブサービスへの導線を求められる時、AddThis っていうサービスを経由して登録するのが結構主流みたいです。自分は AddThis 自体全く知らなかったんですが、Flash コンテンツに複数のウェブサービスへの導線を加えたいという要望が多々あるので調べてみました。日本でもこのサービスを使ってるのかな!?

この記事の続きを読む »

ページの一番上へ移動

Papervision3D:各 View 要素からの参照方法(考え方)

例えば、下記の様な構成が papervision3D コンテンツにあったとして、

PaperVision3D View 概要図

Item.as から TestView3D.as 内の BasicView, viewport3D, CameraObject3D, CameraObject3D.target, Mouse3D などを参照したい場合、Item クラスは DisplayObject3D の子クラスなので参照を持っていない。

これまではインターフェースに下記の様な function setAsset(view:BasicView, viewport:Viewport3D, camera:CamerObject3D) 的な関数を設定して各 DisplayObject3D の子クラスを作成し、各構成要素が override して受け渡していたんだけど、いちいち設定したり構成が深くなると面倒くさかったりしていた。

この記事の続きを読む »

ページの一番上へ移動

FlvPlayBack Component エラー + AS3

最近のプロジェクトを通して納期の都合上 FlvPlayBack を本格的に使ってみたのだけど、「存在しない Flv の URL を source に指定するとエラーが取得出来ない。」という挙動に悩まされた。色々なパターンで様々な挙動をするので気づいた点を忘れない様にメモ。

FlvPlayBack の source プロパティに存在しない URL を設定した場合に Error が Throw されるんですが、これは try/catch で処理すればと思って色々トライしてみたんですが、全然 catch してくれませんでした。source を指定して FlvPlayBack を play する流れで、おそらく処理的なタイムラグなのか play がコールされた後に source 側で Error を Throw するのでどうしてもプログラム上でエラーを catch 出来ないのではないのかなとか考えてます。

例えば、http://www.test.com/no.flv という存在しない URL を FlvPlayBack の source に設定すると下記の様なエラーが起こってしまい、完全にプロセスが止まってしまいます。

compPlayer.source = "http://www.test.com/no.flv";
try
{
    compPlayer.play();
}
catch(e:Error)
{
    trace("@@@ ERROR @@@ " + e);
}
Error opening URL 'http://www.test.com/no.flv'
VideoError: 1000: Unable to make connection to server or to find FLV on server
    at fl.video::VideoPlayer/stop()
    at fl.video::FLVPlayback/http://www.adobe.com/2007/flash/flvplayback/internal::showFirstStream()
    at fl.video::FLVPlayback/http://www.adobe.com/2007/flash/flvplayback/internal::handleVideoEvent()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at fl.video::VideoPlayer/http://www.adobe.com/2007/flash/flvplayback/internal::setState()
    at fl.video::VideoPlayer/http://www.adobe.com/2007/flash/flvplayback/internal::httpNetStatus()

この様な静的な URL の設定の場合は書き間違えさえしなければ問題ないのですが、動的に処理する時には問題なので、ここの方が setTimeOut で解決しているみたいなので自分も同様に Timer を使って処理を加えて対応してみました。しかし、機能を切り出しモック的に対応すると動作が正常に動いても、本番環境では安定した挙動をしませんでした。一応色々な状況の挙動を試してみたので、下記に記述しておこう。

この記事の続きを読む »

ページの一番上へ移動

FlvPlayBack Component エラー + AS3(解決)

先日のエントリー(FlvPlayBack Component エラー + AS3)で記述した FlvPlayBack Component で存在しない Flv へアクセスした際の Error が Catch 出来なかったことについて、どなたか分かりませんが有難いコメントを頂きまして解決しましたので、メモ。関数の詳細を見落としてたー!!

FlvPlayBack に getVideoPlayer(index:Number) というメソッドがあって、クラス内に FlvPlayBack が 1 つのみある状態(activeVideoPlayerIndex が 0 )なので getVideoPlayer(0) で VideoPlayer オブジェクト を作成し、このオブジェクトの netStream という getter メソッドで NetStream オブジェクトを取得し、後は通常の NetStatusEvent で状態を listen して対応するという事らしいです。今回は存在しない Flv の URL を設定された時対処したかったので、NetStatusEvent の info.code が NetStream.Play.StreamNotFound になる時に対応出来ました。NetStream オブジェクトを通常の様に管理できるので close, seek, resume などのメソッド等も同様に対応できる様。

これで明快ですね!

この記事の続きを読む »

ページの一番上へ移動

RemoteProxy + Zend_Amf in AS3

Proxy class を extends した RemoteProxy class を作って Zend_Amf_Server にアクセス。
所謂、RemoteProxy Pattern を使用して RPC で Zend_Amf_Server 側の controller の関数をコール。

NetConnection オブジェクトで Zend_Amf_Server にアクセスする際に NetConnection.Connect.Success が NetStatusEvent で返ったのを確実に確認してから RPC しようと思ってたんだけど、NetConnection.Connect.Success って返らないんですね。NetConnection.Call.Failed などはきちんと返るんですが、接続成功時は NetStatusEvent の evt.info.code が何故か取得出来ない。

この記事の続きを読む »

ページの一番上へ移動

DoubleClick-InStream + AS3

DoubleClick-InStream

通常の Flv ビデオを FlvPlayBack や Video オブジェクトで再生する際に、何からの宣伝やコマーシャル用のプリロールやミッドロールやポストロールビデオを流す際に便利な DoubleClick-InStream。プラットフォームは Flash Player、Silverlight、Windows Media Player、Real Player に対応しています。リクエストする URL にアクセスすると doubleclick サーバが xml にリダイレクトして、広告タイプによって値を返してきて、それを Flash 側でどの様に表示するかをリスポンスの後に設定します。自分は FlvPlayBack を使用して他の Flv と連携する Flash in Flash タイプを使用したので、doubleclick サーバにアクセスすると勝手に Flv とリンク先が返ってきました。

自分も 100 %理解した訳ではなくドキュメントを読んでも分からない部分があったんですが、今回のプロジェクトでは上手く通常の Flv と宣伝用 Flv を難しいコードを記述すること無く同期出来たので、自分の為に忘れない様にメモ。

(1)インストール

MXP で入れるタイプと SDK で入れるタイプが google code より提供されています。タイプも Google In-StreamDoubleClick In-Stream があるようで、自分は Google In-Stream を使用したんですが、後者は書くソースが違って結果は同じようです。

(2)リクエストとリスポンス

下記の様な URL にアクセスします。ブラウザでアクセスすると Windows Media Player が起動しますが、Component や SDK ベースのコードベースでアクセスすると、内的な処理は XML で返ってるようです。その後の処理はどうなってるかはよく分かりません。

http://ad.doubleclick.net/pfadx/AngelaSite;kw=dclkvideo;sz=120x350;ord=3577745;

Google In-Stream の場合は AdsLoaderAdsRequest クラスを使用してアクセスするので、URLLoader クラスと URLRequest クラスのを使用する方法といたって基本は同じです。


(3)マッピング

リスポンスは AdsRequest.adType の値によって変わるようなので、この値を基に AdsLoader.load した際のイベントハンドラ内でどのようなメディアが返ってくるか判断します。Video の表示は VideoAdsManager を使用して行います。ここで凄いな!って思ったのは、videoAdsManager.load(flvPlayBack or VideoObject) / videoAdsManager.play(flvPlayBack or VideoObject) を設定するだけで、勝手に Flv が通常の FlvPlayBack や Video オブジェクトに表示されちゃうことです。後は AdEvent.COMPLETE イベントハンドラが呼ばれたら Flv の表示は終了なのでこのタイミングで任意の処理をします。1つ忘れては行けないことは videoAdsManager.clickTrackingElement に任意の DisplayObject を設定してやることです。そうしないとエラーになります。自分の場合はプリロールなので、AdEvent.COMPLETE が dispatch された時点で、次の通常の Flv を表示する様にコーディングしました。

(4)集計

ドキュメントによれば load や complete のトラッキングや AFV(Adsense for Video) でクリックのインプレッションをトラッキングしてくれるそうです。

この記事の続きを読む »

ページの一番上へ移動

RemoteProxy class を考えてみる。

Flash プロジェクトで大抵外部にアクセスするのは画像・XML・API・Remoting・バイナリ通信・たまにテキスト辺りだと思うので、プロジェクト毎に各 View クラスの 親クラスに必要な Proxy クラスを拡張した RemoteProxy のインスタンスを protected で出し入れしておくとかなり楽な気がする。Loader・URLLoader や独自ラッパークラスのインスタンス生成を View 毎にする必要が無くなる。

RemoteProxy の強みは何と言っても Dynamic クラスのため、プロパティや関数を動的に作成することが出来ること。いちいちその都度その都度外部にアクセスするために public 関数を独自に定義するを必要が無い。要は callProperty で設定する関数の syntax や setProperty で渡す変数名を個人的な決め毎で設定しておけば、かなりの確率で再度設定する必要が無い。

例えば、Zend_Amf_Server の UserController の debug という関数を呼び出すとすると、View クラスでは

this._cfZendAmfProxy.addEventListener(CFZendAmfProxyEvent.RESULT, _resultHandler, false, 0, true);
this._cfZendAmfProxy.addEventListener(IOErrorEvent.IO_ERROR, _ioErrorHandler, false, 0, true);
this._cfZendAmfProxy.UserController_debug('Hello World');

で、RemoteProxy class 内部は

flash_proxy override function callProperty(method:*, ...params):*
{
    _call(method, params);
}
private function _call(method:*, params:*):void
{
    var methodName:String = method.toString();
    if(methodName.indexOf("_"))
        methodName = methodName.split("_").join(".");		
    this._nc.call(methodName, this._responder, params[0]);
}

また、Zend_Amf_Server の UserController の sendMail という関数を呼び出すとすると、View クラスでは

this._cfZendAmfProxy.addEventListener(CFZendAmfProxyEvent.RESULT, _resultHandler, false, 0, true);
this._cfZendAmfProxy.addEventListener(IOErrorEvent.IO_ERROR, _ioErrorHandler, false, 0, true);
this._cfZendAmfProxy.UserController_debug(mailVO);

という感じで RemoteProxy class の内部は変わらない。

この記事の続きを読む »

ページの一番上へ移動