<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>DEV.CONVEXSTYLE.NET</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/" />
   <link rel="self" type="application/atom+xml" href="http://dev.convexstyle.net/atom.xml" />
   <id>tag:dev.convexstyle.net,2008://1</id>
   <updated>2008-06-25T05:50:55Z</updated>
   <subtitle>development blog of convexstyle’s work</subtitle>
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.35</generator>

<entry>
   <title>JUGEM Desktop x Flickr</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2008/06/jugem_desktop_x_flickr.html" />
   <id>tag:dev.convexstyle.net,2008://1.55</id>
   
   <published>2008-06-25T05:47:10Z</published>
   <updated>2008-06-25T05:50:55Z</updated>
   
   <summary>社内のブログサービス（JUGEM）で、以前開発していた JUGEM Desktop を 1.2 より 2.0 にアップデートしました。 Flickr 機能を追加し、自分の Flickr スクリーンネームでログインすれば、ブラウザ経由ではなく、AIR アプリケーションから直接ブログに最大８枚までの Flickr 写真とともに記事をエントリーすることができます。インタフェース的にはドラッグ＆ドロップで写真を記事に追加する感じです。 写真好きな人とか、Flickr は Englishで JUGEM は日本語で切り分けたい人とか、ブラウザ経由が面倒な人はどうぞ。 詳細：http://jugem.jp/fun/jugemdesktop/ 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...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="AIR" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flickr" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Work" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="27" label="ActionScript 3.0" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="2" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="14" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="6" label="Flickr" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="31" label="PHP" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[社内のブログサービス（<a href="http://jugem.jp/" target="_blank">JUGEM</a>）で、以前開発していた JUGEM Desktop を 1.2 より 2.0 にアップデートしました。

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

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

詳細：<a href="http://jugem.jp/fun/jugemdesktop/" target="_blank">http://jugem.jp/fun/jugemdesktop/</a>

<a href="http://jugem.jp/fun/jugemdesktop/" target="_blank"><img src="http://dev.convexstyle.net/images/entry/200806/20080624.jpg" width="450" height="397" alt="JUGEM Desktop 2.0" title="JUGEM Desktop 2.0" class="link" /></a>
<em>JUGEM Desktop 2.0</em>


【使用技術＆環境】
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 の紹介ページデザイン＆コーディングは<a href="http://www.grandgraphica.com/nohara/" target="_blank">野原君</a>が担当。色々どーもでした！]]>
      
   </content>
</entry>
<entry>
   <title>H.264 動画の Progressive 配信</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2008/04/h264_progressive.html" />
   <id>tag:dev.convexstyle.net,2008://1.54</id>
   
   <published>2008-04-04T01:44:36Z</published>
   <updated>2008-04-04T01:56:36Z</updated>
   
   <summary> 前回のエントリーで、Flash Media Server 3 を使用した Streaming 配信に関して記述しましたが、今度はウェブディレクトリより通常の Progressive 再生をしてみたのでメモ。 前回は NetStream.play の記述は ns.play(&quot;mp4:sample.mp4&quot;); や ns.play(&quot;mp4:sample.mov&quot;); の様な形式で記述し Streaming 再生させていたが、Progressive 再生では NetConnection.connect(null) にして同様な記述では H.264 の動画コーデックで作成された MPEG-4 や MOV を再生できないようだ。 もろもろ調べていたら flashcomguru の記事に同様な問題で、下記の様な記述が。 &quot;That did the trick and my mp4 files now...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="27" label="ActionScript 3.0" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="2" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="30" label="flv" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="24" label="video" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[<img src="http://dev.convexstyle.net/images/entry/200804/20080401.gif" width="400" height="275" alt="H.264 動画の Progressive 配信" title="H.264 動画の Progressive 配信" class="normal" />


<a href="http://dev.convexstyle.net/2008/03/h264_flash_media_server_3_stre.html">前回のエントリー</a>で、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 を再生できないようだ。

もろもろ調べていたら <a href="http://www.flashcomguru.com/index.cfm/2007/8/22/flash-h264-demos" target="_blank">flashcomguru の記事</a>に同様な問題で、下記の様な記述が。
"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 エラーが返ってきた。ここら辺の挙動はどうなのか。

<a href="http://www.flashcomguru.com/index.cfm/2007/8/22/flash-h264-demos" target="_blank">flashcomguru</a> からはサンプル fla をダウンロードでき、そちらでは FLVPlayback を使用しているので、source プロパティに拡張子を変更したファイルの絶対パス（例：http://hogehoge.com/flv/sample.mov.flv）を指定して動作させている。

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

]]>
      <![CDATA[▽ メインタイムライン
＊簡潔化のためにタイムラインにソースを記述。

<pre>
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.media.Sound;
import flash.media.SoundChannel;
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(null);// Progressive 再生の場合

/**
* 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 再生
	<strong>ns.play("sample.mp4.flv");// .mp4 の Progressive 配信</strong>
	<strong>ns.play("sample.mov.flv");// .mov の Progressive 配信</strong>
	
}


/**
* 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());
}
</pre>


▽ CustomClass

<pre>
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");
		}
		
	}
	
}
</pre>


【開発環境】
Flash CS3 Professional


【参考サイト】
<a href="http://www.flashcomguru.com/index.cfm/2007/8/22/flash-h264-demos" target="_blank">flashcomguru</a>]]>
   </content>
</entry>
<entry>
   <title>H.264 動画を Flash Media Server 3 より Streaming 再生</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2008/03/h264_flash_media_server_3_stre.html" />
   <id>tag:dev.convexstyle.net,2008://1.53</id>
   
   <published>2008-03-31T14:18:33Z</published>
   <updated>2008-03-31T15:15:14Z</updated>
   
   <summary> 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...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flash Media Server" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Server" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="27" label="ActionScript 3.0" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="2" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="29" label="Flash Media Server" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[<img src="http://dev.convexstyle.net/images/entry/200803/20080331.gif" width="400" height="275" alt="Flash Media Server 3 の Streaming 配信" title="Flash Media Server 3 の Streaming 配信" class="normal" />
<em>Flash Media Server 3 の Streaming 配信</em>

会社で Flash Media Server 3 を触る機会があり、H.264 のストリーミング再生を試してみたのでメモ。
H.264 は従来の On2 VP6 コーデックよりもパフォーマンスと効率が向上した動画圧縮規格で、Flash Player 最新版（Flash Player 9.0.115）であれば、従来の .flv や .mp3 に加え、H264 を使用した他の動画フォーマット（.mov、.avi、.mp4 など）を Streaming 再生させることが可能。<a href="http://www.adobe.com/flashon/" target="_blank">Adobe Flash on</a> で HD 画質の動画を普通に見れますが、この画質は恐ろしく奇麗過ぎる！もはや映画レベルの画質をウェブでコンテンツとして普通に配信出来ますね。Flash Media Streaming Server 3 はそこまで高くはなく購入出来るレベルなので、専用サーバ立てて portfolio サイトのコンテンツ配信ぐらいなら十分ですね。どこかの記事で読みましたが、H.264 を Red5 もサポート予定らしいので、ライセンス購入なしに高画質動画配信が可能になる可能性がありますね。

といういことで、Flash Media Server 3 の動画の Streaming 配信の際は、従来の NetConnection.connect の記述がフォーマットの違いによって微妙に異なるので下記に記述します。]]>
      <![CDATA[▽ メインタイムライン上のソース
＊簡潔にするため、class などを使わず直に書いています。
＊mp3 ファイルに関しては Sound オブジェクトなどで制御すべきですが、今回は接続方法のみに注目したためそのままで接続しています。
<pre>
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 再生
	<strong>ns.play("mp4:sample.mp4");// sample.mp4 を Streaming 再生する場合</strong>
        <strong>ns.play("mp4:sample.mov");// sample.mov を Streaming 再生する場合</strong>
	<strong>//ns.play("mp3:sample");// sample.mp3 を Streaming 再生する場合（mp3 に関しては video とは関係ないですが、基本的な考えは同じ）</strong>
	<strong>//ns.play("sample");// sample.flv を Steaming 再生する場合</strong>
	
}


/**
* 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());
}
</pre>

▽ CustomClient クラス
<pre>
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");
		}	
	}	
}
</pre>


▽ 注意点
FMS 3.0 のデフォルトのアプリケーション（vod）に接続すると、onBWDone という関数が各 client オブジェクトに対して call されて呼び出され、非同期エラー（AsyncErrorEvent）が返ってきました。これは main.asc で Application.onConnect 時に呼び出されている関数で、これもここでは CustomClient クラスに追記しました。main.asc はその他関連ファイルと共に、 main.far というパッケージ化されたファイル内に含まれているので、もし詳しく main.asc の内容を見たい方は、unzip main.far をすることで、内部のファイル一覧に解凍し、main.asc を見ることが出来るようになります。

今シーズンは素材用にと結構スノボー動画を <a href="http://hb.afl.rakuten.co.jp/hgc/0797d26b.bfc62843.0797d26c.410956d5/?pc=http%3a%2f%2fitem.rakuten.co.jp%2fmurauchi-denki%2f4973934446014%2f&m=http%3a%2f%2fm.rakuten.co.jp%2fmurauchi-denki%2fi%2f15935034%2f" target="_blank">Xacti CA-65</a> で撮影してましたが、やっぱりさらに高画質を目指したいので <a href="http://hb.afl.rakuten.co.jp/hgc/0797d3a7.5f7d0327.0797d3a8.bd146185/?pc=http%3a%2f%2fitem.rakuten.co.jp%2fedigi%2fjan-4973934450349%2f&m=http%3a%2f%2fm.rakuten.co.jp%2fedigi%2fi%2f10080860%2f" target="_blank">Xacti HD700</a> 辺りで撮影して、H.264 形式で配信もいいなとか思います。


【使用環境】
Flash CS3 Professional、Flash Media Server 3、Flash Player 9.0.115


【参考サイト】
<a href="http://www.adobe.com/devnet/flashmediaserver/articles/beginner_vod_fm3.html" target="_blank">Flash Media Server 3 の Streaming 方法</a>
<a href="http://livedocs.adobe.com/fms/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000110.html" target="_blank">main.far の詳細</a>]]>
   </content>
</entry>
<entry>
   <title>マルチアプリケーションを１つの AIR アプリケーションで管理</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2008/02/_air.html" />
   <id>tag:dev.convexstyle.net,2008://1.52</id>
   
   <published>2008-02-29T00:38:58Z</published>
   <updated>2008-02-29T00:56:24Z</updated>
   
   <summary>AIR アプリケーションで大きく分類して１つの機能のみを保持する場合は、特に意識せずに開発すればいいんですが、ふと、機能が横並び的に拡張して、親アプリケーション（mx:WindowedApplication や mx:Application）ではそのレイアウトのみを管理し、各子クラスがそれぞれ１つのアプリケーションの単位として考えられる場合はどうやるんだろう・・・と思ったので、調査してみた。 要は、各アプリケーションを表すアイコンがズラッと並んでいるだけで、各アイコンをクリックした時点で、各アプリケーションが起動する感じにしたい。 mx:Window 概略図...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="AIR" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="27" label="ActionScript 3.0" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="23" label="AIR" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="14" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[AIR アプリケーションで大きく分類して１つの機能のみを保持する場合は、特に意識せずに開発すればいいんですが、ふと、機能が横並び的に拡張して、親アプリケーション（mx:WindowedApplication や mx:Application）ではそのレイアウトのみを管理し、各子クラスがそれぞれ１つのアプリケーションの単位として考えられる場合はどうやるんだろう・・・と思ったので、調査してみた。
要は、各アプリケーションを表すアイコンがズラッと並んでいるだけで、各アイコンをクリックした時点で、各アプリケーションが起動する感じにしたい。

<img src="http://dev.convexstyle.net/images/entry/200802/20080229_sampleImage.gif" width="400" height="275" alt="mx:Window 概略図" title="mx:Window 概略図" class="normal" />
<em>mx:Window 概略図</em>]]>
      <![CDATA[最初は、「ポップアップ機能を使うんじゃないのか？」と思い、<a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/display/NativeWindowInitOptions.html" target="_blank">NativeWindowInitOption</a> や <a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/display/NativeWindow.html" target="_blank">NativeWindow</a> クラスを使用し、新規ウィンドウを立ち上げてみたが、これだと画像などを NativeWindow オブジェクトに addChild 出来るけど、そこからの拡張性がないようだ。<a href="http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=1353" target="_blank">ココ</a>でも取り上げられている様に、他の MXML Component を addChild しても描写はされないらしいし、シンプルにここで単純なコンテンツを表示する場合に適するのかなと思う。

▽ NativeWindow による通常のポップアップ
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:WindowedApplication 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="absolute"&gt;

	&lt;mx:Script&gt;
	&lt;![CDATA[
	
		import flash.display.Sprite;
		import flash.display.NativeWindow;
		import flash.display.NativeWindowDisplayState;
		import flash.display.NativeWindowInitOptions;
		import flash.display.NativeWindowResize;
		import flash.display.NativeWindowSystemChrome;
		import flash.display.NativeWindowType;
		import flash.events.Event;
		import flash.events.MouseEvent;

		[Embed(source='../asset/sampleImage.png')]
		private var SampleImage:Class;

		private var win1:NativeWindow;
		private var win2:NativeWindow;

		/**
		 * Window 1 を開くための関数
		 */
		private function openWindow1():void {		
			var targetX:Number = stage.nativeWindow.x + stage.nativeWindow.width;
			var targetY:Number = stage.nativeWindow.y;
			win1 = makeWindow(
							  false, 
							  false, 
						      false, 
							  NativeWindowType.NORMAL, 
							  false, 
							  NativeWindowSystemChrome.STANDARD, 
							  "Window 1",
							  300,
							  300
							  );
			win1.x = targetX;
			win1.y = targetY;
		 
			var imageSprite:Sprite = new Sprite();
			imageSprite.x = imageSprite.y = 0;
			imageSprite.addChild(new SampleImage());
			win1.stage.addChild(imageSprite);
		}

		/**
		 * Window 2 を開くための関数
		 */
		private function openWindow2():void {
			var targetX:Number = win1.x + win1.width;
			var targetY:Number = stage.nativeWindow.y;
			
			win2 = makeWindow(
							  false, 
							  false, 
							  false, 
							  NativeWindowType.NORMAL, 
							  true, 
							  NativeWindowSystemChrome.NONE, 
							  "window 2", 
							  300, 
							  300
							  );

			var imageSprite:Sprite = new Sprite();
			imageSprite.addChild(new SampleImage());
			win2.stage.addChild(imageSprite);
			win2.x = targetX;
			win2.y = targetY;
			win2.stage.addEventListener(MouseEvent.MOUSE_DOWN, onWin2MouseDown);

		}

		/**
		 * Window 2 をマウスダウンした際のイベントハンドラ関数
		 */
		private function onWin2MouseDown(evt:MouseEvent):void {
			win2.startMove();	
		}

		/**
		 * 新規ウィンドウを作成するための関数
		 * 
		 * @param Boolean maximizable
		 * @param Boolean minimizable
		 * @param Boolean resizable
		 * @param String  type
		 * @param Boolean transparent
		 * @param Boolean systemChrome
		 * 
		 * @return NativeWindow nativeWindow
		 */
		private function makeWindow(
									  maximizable:Boolean, 
									  minimizable:Boolean, 
									  resizable:Boolean, 
									  type:String, 
									  transparent:Boolean, 
									  systemChrome:String,
									  title:String,
									  width:Number,
									  height:Number
									  ):NativeWindow 
		{
			
			var options:NativeWindowInitOptions = new NativeWindowInitOptions();
			options.maximizable  = maximizable;
			options.minimizable  = minimizable;
			options.resizable    = resizable;
			options.type         = type;
			options.transparent  = transparent;
			options.systemChrome = systemChrome;
			
			var nativeWindow:NativeWindow = new NativeWindow(options);
			nativeWindow.title             = title;
			nativeWindow.stage.align       = StageAlign.TOP_LEFT;
			nativeWindow.stage.scaleMode   = StageScaleMode.NO_SCALE;
			nativeWindow.visible           = true;
			nativeWindow.stage.stageWidth  = width;
			nativeWindow.stage.stageHeight = height;
			
			return nativeWindow;		
		}
	
	]]&gt;
	&lt;/mx:Script&gt;
	
	&lt;!-- Window 1 用ボタン --&gt;
	&lt;mx:Button
		id="Window1_btn" 
		label="window 1 を開く" 
		x="10" 
		y="10" 
		click="openWindow1()" /&gt;
	
	&lt;!-- Window 2 用ボタン --&gt;
	&lt;mx:Button
		id="Window2_btn" 
		label="window 2 を開く" 
		x="10" 
		y="50" 
		click="openWindow2()" /&gt;

&lt;/mx:WindowedApplication&gt;
</pre>


じゃあ、どうやって ViewStack などで画面遷移などを管理できる MXML Component をアプリケーションの単位として制御できるんだろうと調べていたら、<a href="http://livedocs.adobe.com/flex/3/langref/mx/core/Window.html" target="_blank">mx:Window</a> という MX タグがあることにたどり着いた。これは先ほどのNativeWindow クラスで新規ウィンドを開く様に、新規ウィンドを起動することができるのだが、MXML コンポーネントとして制御できるため、この中で mx:Viewstack や mx:Canvas や mx:Script やら他の MXML タグを通常通り使える。要は、１つのアプリケーションを作っている感覚で、複数のアプリケーションを作れる訳だ。なお、結構文献はまだまだ少ないみたいで、最初、NativeWindowSystemChrome.NONE、transparent=true などで透過やフレームなしの新規画面を立ち上げるのに苦労したので、その状態にした新規ウィンドを立ち上げた例を今回は記述する。


▽ mx:Window による通常のポップアップ
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:WindowedApplication 
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute" 
	showFlexChrome="false"&gt;
	
	
	&lt;mx:Style&gt;
		Application {
			background-image: "";
			background-color: "";
		}
	&lt;/mx:Style&gt;

	&lt;mx:Script&gt;
	&lt;![CDATA[
	
		import view.SampleView;
	
		import flash.display.NativeWindow;
		import flash.display.NativeWindowDisplayState;
		import flash.display.NativeWindowInitOptions;
		import flash.display.NativeWindowResize;
		import flash.display.NativeWindowSystemChrome;
		import flash.display.NativeWindowType;

		import mx.core.Window;

		public var testVar:String = "Hello World";
		private var window:Window;

		/**
		 * 新しいウィンドウを起動するための関数
		 */
		private function openWindow():void {

			window = makeWindow(
			                    SampleView, 
			                    false, 
			                    false, 
			                    false, 
			                    NativeWindowType.LIGHTWEIGHT, 
			                    true, 
			                    NativeWindowSystemChrome.NONE, 
			                    false, 
			                    false, 
			                    false, 
			                    300, 
			                    480
			                    );
			window.x = 10;
			window.y = 10;
			window.open();
			
		}

		/**
		 * ウィンドウ作成用関数
		 */
		private function makeWindow(
									  ClassName:Class, 
									  minimizable:Boolean,
									  maximizable:Boolean,
									  resizable:Boolean,
									  type:String,
									  transparent:Boolean,
									  systemChrome:String,
									  showStatusBar:Boolean,
									  showTitleBar:Boolean,
									  showGripper:Boolean,
									  width:Number,
									  height:Number
									  ):Window 
		{
		
			var window:Window    = new ClassName();
			window.minimizable   = minimizable;
			window.maximizable   = maximizable;
			window.resizable     = resizable;
			window.type          = type;
			window.transparent   = transparent;
			window.systemChrome  = systemChrome;
			window.showStatusBar = showStatusBar;
			window.showTitleBar  = showTitleBar;
			window.showGripper   = showGripper;
			window.minWidth      = width;
			window.minHeight     = height;

			return window;

		}

	]]&gt;
	&lt;/mx:Script&gt;

	&lt;!-- 新規ウィンドを開くためのボタン --&gt;
	&lt;mx:Button
		id="Win_btn" 
		label="Window を開く" 
		x="10" 
		y="10" 
		click="openWindow()" /&gt;

&lt;/mx:WindowedApplication&gt;
</pre>


【開発環境】
Flex Builder 3.0

【参考サイト】
<a href="http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=1353" target="_blank">http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=1353</a>
<a href="http://livedocs.adobe.com/flex/3/langref/mx/core/Window.html" target="_blank">http://livedocs.adobe.com/flex/3/langref/mx/core/Window.html</a>

【参考本】
<a href="http://www.amazon.co.jp/gp/redirect.html%3FASIN=4839926077%26tag=convexstyle-22%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/4839926077%253FSubscriptionId=ON9KBBBXNXGBYSAE9RG2" target="_blank"><img src="http://ecx.images-amazon.com/images/I/01bSOyVHuiL.jpg" width="58" height="75" alt="Adobe AIRプログラミングガイド" title="Adobe AIRプログラミングガイド" class="recommend-img" />]]>
   </content>
</entry>
<entry>
   <title>JUGEM Desktop</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2008/02/jugem_desktop.html" />
   <id>tag:dev.convexstyle.net,2008://1.51</id>
   
   <published>2008-02-03T14:57:19Z</published>
   <updated>2008-02-03T15:22:34Z</updated>
   
   <summary> Adobe Integrated Runtime Beta 3 上で動作する JUGEM Desktop というアプリケーションの開発に携わり 1/29 にリリースしました。ウェブカメラの動画を記憶ストリームとしてアプリケーションサーバー上に一時的に保存し、ユーザーアクションによって動画をウェブディレクトリに保存し、JUGEM 各ユーザーのブログコンテンツとして使用できるという仕様。今回は最近動画に力を入れている ASK.jp と連携しデコワクを使用するため、ASK で提供された API を使用し、最終的に記憶ストリーム（.flv）を ASK 側に POST する形を取りました。（ローカルの DV ファイルをアップロードするウェブ版は去年末に開発しました。） JUGEM Desktop の現状の機能自体は Flash Developer や Flex Developer の方にはいたって基本の機能で、すでにウェブ上のアプリケーションでもウェブカメラの動画投稿ができるものを多くみているし、個人的にもウェブでは３度程、記憶ストリームを利用したアプリケーションを仕事や個人ワークで開発しているので、目立って新しいことをしたという訳ではないですが、とにかく、JUGEM というブログサービス（対何十万人）を相手にするための対サービス型のアプリケーション開発は結構シビアで目に見えない部分で苦労しました。後、AIR アプリケーションは&quot;既存のスキルをローカルアプリケーションに使用でき簡単に開発できる&quot;という風に聞いていましたが、やってみると Flex Framework をきっちり理解していないと難しいなと痛感。自分見たくゼロから Flex を始めた方はまずは...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="AIR" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Work" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[<a href="http://jugem.jp/fun/jugemdesktop/" target="_blank"><img src="http://dev.convexstyle.net/images/entry/200801/JUGEMDesktop.jpg" width="450" height="400" alt="JUGEM Desktop" title="JUGEM Desktop" class="link" /></a>

<a href="http://labs.adobe.com/downloads/air.html" target="_blank">Adobe Integrated Runtime Beta 3</a> 上で動作する <a href="http://jugem.jp/fun/jugemdesktop/" target="_blank">JUGEM Deskto</a>p というアプリケーションの開発に携わり 1/29 にリリースしました。ウェブカメラの動画を記憶ストリームとしてアプリケーションサーバー上に一時的に保存し、ユーザーアクションによって動画をウェブディレクトリに保存し、<a href="http://jugem.jp/" target="_blank">JUGEM</a> 各ユーザーのブログコンテンツとして使用できるという仕様。今回は最近動画に力を入れている <a href="http://video.ask.jp/index.do" target="_blank">ASK.jp</a> と連携し<a href="http://decowaku.jp/" target="_blank">デコワク</a>を使用するため、ASK で提供された API を使用し、最終的に記憶ストリーム（.flv）を ASK 側に POST する形を取りました。（ローカルの DV ファイルをアップロードする<a href="http://info.jugem.jp/?eid=10511" target="_blank">ウェブ版</a>は去年末に開発しました。）

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

ということで、使っていただくと分かると思いますが機能的には全くまだまだです。
開発は１人作業なので時間が限られているのですが、引き続き 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]]>
      
   </content>
</entry>
<entry>
   <title>独自 showBusyCursor 表示方法</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2008/01/_showbusycursor.html" />
   <id>tag:dev.convexstyle.net,2008://1.50</id>
   
   <published>2008-01-20T14:37:53Z</published>
   <updated>2008-01-20T14:53:30Z</updated>
   
   <summary>RPC 処理や HTTPService 処理中に表示される busy カーソル。 s2flex2-components や RemoteObject を使用して Flex（AIR）アプリケーションとサーバプログラムを Remoting で連携して何かを処理する場合、showBusyCursor=&quot;true&quot; にすることで、サーバプログラムが任意の処理を行っている際にデフォルトのくるくる回るカーソルを表示することができるが、独自のカーソルやプログレスバーを表示したい場合があるので、その独自のカーソルやプログレスバーを表示する方法をメモ。...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="AIR" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="27" label="ActionScript 3.0" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="23" label="AIR" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="2" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="17" label="Flash Remoting" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="14" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[RPC 処理や HTTPService 処理中に表示される busy カーソル。
<a href="http://s2flex2.sandbox.seasar.org/ja/" target="_blank">s2flex2-components</a> や <a href="http://livedocs.adobe.com/labs/flex3/langref/mx/rpc/remoting/RemoteObject.html" target="_blank">RemoteObject</a> を使用して Flex（AIR）アプリケーションとサーバプログラムを Remoting で連携して何かを処理する場合、showBusyCursor="true" にすることで、サーバプログラムが任意の処理を行っている際にデフォルトのくるくる回るカーソルを表示することができるが、独自のカーソルやプログレスバーを表示したい場合があるので、その独自のカーソルやプログレスバーを表示する方法をメモ。]]>
      <![CDATA[考え方はいくつかあるのかと思うが、今回はシンプルにデフォルトのカーソルを非表示にし、処理が開始した時点で作成したカーソルやプログレスバーを表示設定し、result イベントハンドラや fault イベントハンドラが呼び出された時点で非表示設定させるだけのものにする。


▽ カーソルやプログレスバーは・・・

今回は Flash CS３で作成した簡単なプリローダ的デザイン要素を作成し、swf を asset として Embed し、<a href="http://livedocs.adobe.com/labs/flex3/langref/mx/core/UIComponent.html" target="_blank">UIComponent</a> を extends する。プログレスバーなら graphics.drawRect 辺りを上手く利用する。


<pre>
package {
	
	import mx.core.UIComponent;
	import flash.display.Sprite;
	
	public class CustomBusyCursor extends UIComponent {
		
		[Embed(source='cursor.swf')]
		private var CustomCursor:Class;
		
		public function CustomBusyCursor() {
			var cursor:Sprite = new CustomCursor();
			addChild(cursor);
		}		
	}
}
</pre>


▽ MXML ソースサンプル
今回は s2flex2-components を使用して簡単にログインのサンプル。ボタンをクリックしログイン処理を開始する。Remoting には <a href="http://www.5etdemi.com/blog/archives/2006/12/amfphp-19-beta-get-it-now/" target="_blank">AMFPHP 1.9-beta</a> を利用し、class 名は Login で test/Login.php として保存し、ログイン用の関数を loginUser とする。
（PHP 側の詳しいプログラムに関しては特に今回は関係が無いので省く。）


<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	xmlns:s2="http://www.seasar.org/s2flex2/mxml"
	layout="absolute"&gt;

	&lt;mx:Script source="BusyCursor.as" /&gt;

	&lt;mx:VBox&gt;
		&lt;mx:Form&gt;
			&lt;mx:FormItem label="ユーザー ID:"&gt;
				&lt;mx:TextInput id="userId" /&gt;
			&lt;/mx:FormItem&gt;
			&lt;mx:FormItem label="パスワード:"&gt;
				&lt;mx:TextInput id="password" displayAsPassword="true" /&gt;
			&lt;/mx:FormItem&gt;
			&lt;mx:Button label="ログイン" click="login()" /&gt;
		&lt;/mx:Form&gt;
	&lt;/mx:VBox&gt;

	&lt;s2:S2Flex2Service
		id="loginService" 
		gatewayUrl="http://hogehoge.com/amfphp/gateway.php" 
		destination="test.Login" 
		result="login_onResult(event)" 
		fault="login_onFault(event)" /&gt;

&lt;/mx:Application&gt;
</pre>


▽ ActionScript ソース
loginService.loginUser に２つのパラメータを渡してログインする。


<pre>
import mx.controls.Alert;
import CustomBusyCursor;

private var cBusyCursor:CustomBusyCursor;

private function login():void {
	var userId:String   = userId.text;
	var password:String = password.text;
	
	if(userId == "" || password == "") {
		Alert.show("必須項目を入力してください。", "ログインエラー");
		return;
	}
	
	cBusyCursor   = new CustomBusyCursor();
	cBusyCursor.x = Math.floor(width / 2);
	cBusyCursor.y = Math.floor(height / 2);
	addChild(cBusyCursor);
	
	loginService.loginUser(userId, password);
		
}

private function login_onResult(evt:Object):void {
	removeChild(cBusyCursor);
	
	if(evt.result) {
		trace("ログイン成功");
	} else {
		trace("ログイン失敗");
	}
	
}

private function login_onFault(evt:Object):void {
	removeChild(cBusyCursor);
	
	trace("ログイン失敗");	
}
</pre>


【使用技術】
Flex Framework, Flex Builder 3 beta, ActionScript 3, AMFPHP 1.9 - beta, s2flex2-components


【参考サイト】
FxUG 記事：<a href="http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=1303&post_id=5463" target="_blank">flexの処理の一時的な中断</a>]]>
   </content>
</entry>
<entry>
   <title>HTTP_Request で HTTP レスポンス情報の評価</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2008/01/http_request_http.html" />
   <id>tag:dev.convexstyle.net,2008://1.49</id>
   
   <published>2008-01-07T10:45:05Z</published>
   <updated>2008-01-07T10:52:44Z</updated>
   
   <summary>明けましておめでとうございます。 前回に引き続き、flickr.interestingness.getList API と Flash の関係について。 flickr.interestingness.getList はクオリティの高い写真を日付ごとに最大 500 件取得できる点ですが、中には Source URL で取得出来る最も重要な b サイズ（でかい画像サイズ）の画像がアップロードしたユーザーが画像を削除した際に取得出来ない場合があるようで、過去にさかのぼるにつれてその頻度は高いようです。 Flash で Viewer を作る以上、そういった画像は極力省きたいので一度 PHP などのプログラム側で HTTP レスポンスからの情報を評価する必要があります。Flickr の仕様上、画像が存在しない場合はHTTP リスポンスコードで 302（Moved Temporarily）が返って画像が無い場合の GIF 画像（photo_unavailable.gif）が返ってしまうので、Flash ではこういった GIF 画像も画像と認識して読み込んでしまい表現上都合が良くないので、cron で定期的にそういった画像を省いた状態で新規に xml を新たに書き出した方が良さそう。でもいちいちリクエストをするので処理は重いのがネックですね。curl --head でも同様な処理を行ったがそんなに処理速度が変わらなかった。何か他の方法は無いだろうか。...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flickr" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="2" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="6" label="Flickr" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="15" label="php" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[明けましておめでとうございます。

<a href="http://dev.convexstyle.net/2007/12/_for_each_in.html" target="_blank">前回</a>に引き続き、<a href="http://www.flickr.com/services/api/flickr.interestingness.getList.html" target="_blank">flickr.interestingness.getList API</a> と Flash の関係について。
flickr.interestingness.getList はクオリティの高い写真を日付ごとに最大 500 件取得できる点ですが、中には Source URL で取得出来る最も重要な b サイズ（でかい画像サイズ）の画像がアップロードしたユーザーが画像を削除した際に取得出来ない場合があるようで、過去にさかのぼるにつれてその頻度は高いようです。
Flash で Viewer を作る以上、そういった画像は極力省きたいので一度 PHP などのプログラム側で HTTP レスポンスからの情報を評価する必要があります。Flickr の仕様上、画像が存在しない場合はHTTP リスポンスコードで 302（Moved Temporarily）が返って画像が無い場合の GIF 画像（photo_unavailable.gif）が返ってしまうので、Flash ではこういった GIF 画像も画像と認識して読み込んでしまい表現上都合が良くないので、cron で定期的にそういった画像を省いた状態で新規に xml を新たに書き出した方が良さそう。でもいちいちリクエストをするので処理は重いのがネックですね。curl --head でも同様な処理を行ったがそんなに処理速度が変わらなかった。何か他の方法は無いだろうか。]]>
      <![CDATA[▽ HTTP リスポンスコードを評価するサンプルクラス

<pre>
require_once('HTTP/Request.php');
class sampleClass {
    /**
    * コンストラクタ関数
    */
    public function __construct() {
    }
    /**
    * HTTP リスポンスコードを評価する関数
    */
    public function isPhotoExisted($b_image) {
        $req =& new HTTP_Request($b_image);
        if(!PEAR::isError($req-&gt;sendRequest())) {
            $code = $req-&gt;getResponseCode();
            if($code == 302) {
               return false;
            }
        } else {
            return false;
        }
        return true;
    }
}
</pre>

▽ 実行コードサンプル

<pre>
$sampleObj = new sampleClass();
$isExisted = $sampleObj-&gt;isPhotoExisted('http://farm1.static.flickr.com/29/65010636_f8ad1dc77c_b.jpg');
</pre>

【参考サイト】
<a href="http://d.hatena.ne.jp/akid/20060103/p1" target="_blank">http://d.hatena.ne.jp/akid/20060103/p1</a>
]]>
   </content>
</entry>
<entry>
   <title>for each in</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2007/12/_for_each_in.html" />
   <id>tag:dev.convexstyle.net,2007://1.48</id>
   
   <published>2007-12-30T13:32:14Z</published>
   <updated>2007-12-30T14:50:52Z</updated>
   
   <summary>数ヶ月前に個人的に一発奮起して 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 的な使い勝手で今更ながら感動です。...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flash" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flickr" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="27" label="ActionScript 3.0" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="2" label="Flash" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="6" label="Flickr" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[数ヶ月前に個人的に一発奮起して <a href="http://hb.afl.rakuten.co.jp/hgc/06eb8bf6.02b83b22.06eb8bf7.91ea6d30/?pc=http%3a%2f%2fitem.rakuten.co.jp%2fnaniwa%2f5089242%2f&m=http%3a%2f%2fm.rakuten.co.jp%2fnaniwa%2fi%2f10011487%2f" target="_blank">Canon 30D</a> を購入したのですが、それ以来写真の面白さにのめり込んでしまいました。<a href="http://www.flickr.com/" target="_blank">Flickr</a> を写真サイトのメインとして使っているんですが、今までのベスト写真アーカイブを表示する photoViewer を自前で作成しようと思い、その前に Flickr のベストフォトを取得する <a href="http://www.flickr.com/services/api/flickr.interestingness.getList.html" target="_blank">flickr.interestingness.getList API</a> をベースに基本ロジックを作成しています。

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


]]>
      <![CDATA[下記のソースの様に、Flickr API の REST の結果を for each in でかなり簡単に解説出来ます。

▽ ActionScript サンプル（xml は flickr.interestingness.getList API の Rest 結果）

<pre>
var sampleXml:XML = &lt;photos page="2" pages="89" perpage="10" total="881"&gt;
	&lt;photo id="2636" owner="47058503995@N01" 
		secret="a123456" server="2" title="test_04"
		ispublic="1" isfriend="0" isfamily="0" /&gt;
	&lt;photo id="2635" owner="47058503995@N01"
		secret="b123456" server="2" title="test_03"
		ispublic="0" isfriend="1" isfamily="1" /&gt;
	&lt;photo id="2633" owner="47058503995@N01"
		secret="c123456" server="2" title="test_01"
		ispublic="1" isfriend="0" isfamily="0" /&gt;
	&lt;photo id="2610" owner="12037949754@N01"
		secret="d123456" server="2" title="00_tall"
		ispublic="1" isfriend="0" isfamily="0" /&gt;
&lt;/photos&gt;;

var xmlList:XMLList = sampleXml.photo;
for each(var obj:Object in xmlList) {
	trace("id: " + obj.@id);
	trace("owner: " + obj.@owner);
	trace("secret: " + obj.@secret);
	trace("server: " + obj.@server);
	trace("title: " + obj.@title);
	trace("ispublic: " + obj.@ispublic);
	trace("isfriend: " + obj.@isfriend);
	trace("isfamily: " + obj.@isfamily);
	trace("============================");
}
</pre>


このソース自体はかなり基本的な形ですが、処理のコンパクト化はこのサンプルでも明確です。後は、XML の解析部分をモデルクラスにして、自前の viewer 用に少しカスタマイズすれば汎用性がありますね。

p.s.
group 94 のクリエイター Thomas Spiessens の<a href="http://www.opcd.net/#/burano_-_at_number_34/" target="_blank">写真サイト</a>もいい！
]]>
   </content>
</entry>
<entry>
   <title>VideoDisplay では NetStream.seek 機能は実現出来ないのか？</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2007/12/videodisplay_netstreamseek.html" />
   <id>tag:dev.convexstyle.net,2007://1.47</id>
   
   <published>2007-12-26T09:23:22Z</published>
   <updated>2007-12-26T10:00:35Z</updated>
   
   <summary>アプリケーションサーバ（今回は Red 5 を使用）から streaming 配信で flv ファイルを Flex Framework の VideoDisplay Component に表示しようと思ったが、イベントドリブン的なプログラム内で、任意のタイミングにより FLV を seek させて動画の PlayHead を管理しようと思ったがうまく処理が動かなかった。（上手くいくかもしれないですが、自分ではどうにも出来なかった。） 例えば、下記の様なクリックイベントで flv の streaming 配信させる簡単なスクリプトを組んでみる。これでも streaming 配信は可能なのだが、NetStream.seek の様な PlayHead の移動をさせる機能を持ち得ていないので、最初から再生させるには flv の再生が終了するのを待って再度クリックしないと先頭から再生しない模様。もっとも VideoDisplay の仕様的に、AutoRewind も streaming には対応してないみたいだし、試した限りでは、再生中はクリックしても特に何も変化せず動画は普通に再生し続けた。 ▽ MXML ソース...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="27" label="ActionScript 3.0" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="14" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[アプリケーションサーバ（今回は Red 5 を使用）から streaming 配信で flv ファイルを Flex Framework の VideoDisplay Component に表示しようと思ったが、イベントドリブン的なプログラム内で、任意のタイミングにより FLV を seek させて動画の PlayHead を管理しようと思ったがうまく処理が動かなかった。（上手くいくかもしれないですが、自分ではどうにも出来なかった。）

例えば、下記の様なクリックイベントで flv の streaming 配信させる簡単なスクリプトを組んでみる。これでも streaming 配信は可能なのだが、NetStream.seek の様な PlayHead の移動をさせる機能を持ち得ていないので、最初から再生させるには flv の再生が終了するのを待って再度クリックしないと先頭から再生しない模様。もっとも VideoDisplay の仕様的に、AutoRewind も streaming には対応してないみたいだし、試した限りでは、再生中はクリックしても特に何も変化せず動画は普通に再生し続けた。

▽ MXML ソース
<pre>
&lt;mx:Script&gt;
&lt;![CDATA[
private function playVideo():void {
    var flvname:String = "rtmp://hogehoge.com/app/sample.flv";
    local_video.source = flvname;
    local_video.play();
}
]]&gt;
&lt;/mx:Script&gt;

&lt;mx:VBox&gt;
    &lt;mx:VideoDisplay id="local_video" width="320" height="320" /&gt;
    &lt;mx:Button label="再生" click="playVideo()" /&gt;
&lt;/mx:VBox&gt;
</pre>
]]>
      <![CDATA[今回はもろもろ動画の PlayHead を操作したかったのでどうしようか考えたのですが、色々と調べた結果、UIComponent に Video オブジェクトを addChild し、その Video オブジェクトに attachNetStream する NetStream を通常の ActionScript の操作で制御する方が都合が良さそうな様なのでメモ。（他のやり方など知っている方は是非教えてください！）

今回は下記の様にかなりシンプルなソースにしましたが、実際には UIComponent を extends してクラス化した方が後々便利です。


▽ MXML ソース
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="absolute" 
	creationComplete="init()"&gt;
	
	&lt;mx:Script&gt;
	&lt;![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");
		}

	]]&gt;
	&lt;/mx:Script&gt;
	
	&lt;mx:VBox&gt;
		&lt;mx:Canvas id="videoContainer" width="400" height="400" /&gt;
		&lt;mx:Button label="再生" click="playVideo()" /&gt;	
	&lt;/mx:VBox&gt;
	
&lt;/mx:Application&gt;
</pre>



▽ CustomClient class
<pre>
package {
    public class CustomClient {
        public function onMetaData(infoObject:Object):void {
            trace("metadata");
        }
        public function onPlayStatus(infoObject:Object):void {
        	trace("onPlayStatus");	
        }
    }
}
</pre>



記述量は増えましたが、最初の例の VideoDisplay では出来なかった再生中の動画の seek は出来る模様。やっぱり <a href="http://www.flashcomguru.com/index.cfm/2007/1/17/Playing-a-live-FMS-stream-using-VideoDisplay-in-Flex2http://www.flashcomguru.com/index.cfm/2007/1/17/Playing-a-live-FMS-stream-using-VideoDisplay-in-Flex2" target="_blank">Flashguru</a> にも書いている様に 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 記事：<a href="http://www.flashcomguru.com/index.cfm/2007/1/17/Playing-a-live-FMS-stream-using-VideoDisplay-in-Flex2http://www.flashcomguru.com/index.cfm/2007/1/17/Playing-a-live-FMS-stream-using-VideoDisplay-in-Flex2" target="_blank">Playing a live FMS stream using VideoDisplay in Flex2</a>]]>
   </content>
</entry>
<entry>
   <title>Moxie での S2Flex2-components 設定方法</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2007/12/moxie_s2flex2components.html" />
   <id>tag:dev.convexstyle.net,2007://1.46</id>
   
   <published>2007-12-16T13:45:51Z</published>
   <updated>2007-12-16T14:07:49Z</updated>
   
   <summary>Flex Builder Beta 2 &quot;Moxie&quot;での AIR アプリケーション開発で PHP 側のコントローラ（gateway.php）と Remoting でのデータのやり取りを行う AS 側でコントローラ的プログラムを開発しようかなと思ったんで、何を使おうか考えていたのですが、最初の２つ（RemotingObject、Lightweight Remoting Framework）は自分なりの理由で回避して S2Flex2-components を使用することにした。...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="14" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[Flex Builder Beta 2 "Moxie"での AIR アプリケーション開発で PHP 側のコントローラ（gateway.php）と Remoting でのデータのやり取りを行う AS 側でコントローラ的プログラムを開発しようかなと思ったんで、何を使おうか考えていたのですが、最初の２つ（<a href="http://www.sephiroth.it/tutorials/flashPHP/flex_remoteobject/" target="_blank">RemotingObject</a>、<a href="http://osflash.org/as3lrf" target="_blank">Lightweight Remoting Framework</a>）は自分なりの理由で回避して
 <a href="http://s2flex2.sandbox.seasar.org/ja/" target="_blank">S2Flex2-components</a> を使用することにした。

]]>
      <![CDATA[（１) RemotingObject コンポーネント
これはまず config.xml で gateway URL を設定しないといけないのが面倒で、プログラムも多少冗長的で面倒。

（２) Danny Patterson　の AS3 Lightweight Remoting Framework
View ときっちりロジックを分けたかったので、AS 側で完結できるんで便利かな〜と思ったんだけど、処理が増えた時に管理が面倒そうでやっぱ汎用性に欠ける。

（3)S2Flex2-components
これは s2flex2-components.swc を Flex Builder の Source-Path に追加すれば Flex コンポーネントとして使えるし、処理毎に一括にまとめられるので便利で管理しやすい。


しかし、確か Beta 1 までは Source-Path に追加して、application に xmlns:s2="http://www.seasar.org/s2flex2/mxml" 名前空間を追加すれば　&lt;s2:S2Flex2Service /&gt; で呼び出されていた気がしたけど、Beta 2 では何故か Build 時のエラーとして「Could not resolve &lt;s2:S2Flex2Service&gt; to a component implementation.]と表示された。
解決策が分からないので他の方法でいこうか迷ったんですが、検索したらコンパイル時に認識されないという様な事を書いている人がいたので、s2flex2-components.swc を下記の libs ディレクトリに明示的にコピーしてプロジェクトを Build したら動いた。


【Windows のコピーディレクトリ】
C:¥Program Files¥Adobe¥Flex Builder 3/sdks/3.0.0/frameworks/libs/s2flex2-components.swc

【MAC のディレクトリ】
/Applications/Adobe Flex Builder 3/sdks/3.0.0/frameworks/libs/s2flex2-components.swc


ちなみに Adobe Labs で <a href="http://labs.adobe.com/technologies/flex/flexbuilder3/" target=""_blank>Adobe Flex Builder 3 Public Beta 3</a>　がリリースされましたね。いよいよ Flex 3 の正式版近し！


【参考サイト】
<strong>RemoteObject</strong>
<a href="http://www.sephiroth.it/tutorials/flashPHP/flex_remoteobject/" target="_blank">http://www.sephiroth.it/tutorials/flashPHP/flex_remoteobject/</a>

<strong>AS3 Lightweight Remoting Framework</strong>
<a href="http://osflash.org/as3lrf" target="_blank">http://osflash.org/as3lrf</a>

<strong>S2Flex2-components</strong>
<a href="http://s2flex2.sandbox.seasar.org/ja/" target="_blank">http://s2flex2.sandbox.seasar.org/ja/</a>
<a href="http://d.hatena.ne.jp/hirossy1977/20070507/1178548033" target="_blank">http://d.hatena.ne.jp/hirossy1977/20070507/1178548033</a>]]>
   </content>
</entry>
<entry>
   <title>Jugem x ASK.JP</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2007/12/jugem_x_askjp.html" />
   <id>tag:dev.convexstyle.net,2007://1.45</id>
   
   <published>2007-12-10T09:29:44Z</published>
   <updated>2007-12-10T09:36:16Z</updated>
   
   <summary>久々のブログエントリー。 そして久々に会社の既存サービスに Flash を一切使わない機能をゴリゴリ開発。 ブログサービス jugem に ASK.JP の動画投稿 API を使用してローカル動画投稿機能を実装してみました。Open な API では無いですがよく出来ている API だったので、スムーズに開発出来ました。既存のサービスのソースも追えたので、結構良い勉強になりました。 【使用技術】 PHP、Smarty、PEAR、MySQL、CSS、Javascript、HTML、PhotoShop、ASK API 【担当領域】 PHP、Smarty、PEAR、MySQL、Javascript、ASK API 辺り...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="API" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="Work" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="25" label="api" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="15" label="php" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="24" label="video" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[久々のブログエントリー。


そして久々に会社の既存サービスに Flash を一切使わない機能をゴリゴリ開発。
ブログサービス <a href="http://jugem.jp/" target="_blank">jugem</a> に <a href="http://video.ask.jp/index.do" target="_blank">ASK.JP</a> の動画投稿 API を使用してローカル動画投稿機能を実装してみました。Open な API では無いですがよく出来ている API だったので、スムーズに開発出来ました。既存のサービスのソースも追えたので、結構良い勉強になりました。


<a href="http://info.jugem.jp/?eid=10511" target="_blank"><img src="http://dev.convexstyle.net/images/entry/200712/20071210.gif" width="400" height="120" alt="Jugem x ASK.JP" title="Jugem x ASK.JP" class="link" /></a>


【使用技術】
PHP、Smarty、PEAR、MySQL、CSS、Javascript、HTML、PhotoShop、ASK API


【担当領域】
PHP、Smarty、PEAR、MySQL、Javascript、ASK API 辺り]]>
      
   </content>
</entry>
<entry>
   <title>unable to bind to property</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2007/10/unable_to_bind_to_property.html" />
   <id>tag:dev.convexstyle.net,2007://1.44</id>
   
   <published>2007-10-26T05:24:08Z</published>
   <updated>2007-10-26T05:34:35Z</updated>
   
   <summary>動的なプロパティを持つ Object を集めた ArrayCollection Object を TileList に Bind し、itemRenderer で表示レイアウトをカスタマイズしようとすると、Debug の際に console 画面に下記の様なエラーが。 warning: unable to bind to property &apos;label&apos; on class &apos;Object&apos; (class is not an IEventDispatcher) warning: unable to bind to property &apos;src&apos; on class &apos;Object&apos; (class...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="14" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[動的なプロパティを持つ Object を集めた ArrayCollection Object を TileList に Bind し、itemRenderer で表示レイアウトをカスタマイズしようとすると、Debug の際に console 画面に下記の様なエラーが。

<pre>
warning: unable to bind to property 'label' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'src' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'label' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'src' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'label' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'src' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'label' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'src' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'label' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'src' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'label' on class 'Object' (class is not an IEventDispatcher)
warning: unable to bind to property 'src' on class 'Object' (class is not an IEventDispatcher)
</pre>
]]>
      <![CDATA[■ エラーが生じるサンプルソース
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	viewSourceURL="source/index.html"
	layout="absolute"&gt;
	
	&lt;mx:Script&gt;
		&lt;![CDATA[
			
			[Bindable]
				[Embed(source='asset/image01.jpg')]
				private var image01:Class;
			[Bindable]
				[Embed(source='asset/image02.jpg')]
				private var image02:Class;
			[Bindable]
				[Embed(source='asset/image03.jpg')]
				private var image03:Class;
			[Bindable]
				[Embed(source='asset/image04.jpg')]
				private var image04:Class;
			[Bindable]
				[Embed(source='asset/image05.jpg')]
				private var image05:Class;
			[Bindable]
				[Embed(source='asset/image06.jpg')]
				private var image06:Class;

		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:ArrayCollection id="sampe_ac"&gt;
		&lt;mx:Object label="image01" src="{image01}" /&gt;
		&lt;mx:Object label="image02" src="{image02}" /&gt;
		&lt;mx:Object label="image03" src="{image03}" /&gt;
		&lt;mx:Object label="image04" src="{image04}" /&gt;
		&lt;mx:Object label="image05" src="{image05}" /&gt;
		&lt;mx:Object label="image06" src="{image06}" /&gt;
	&lt;/mx:ArrayCollection&gt;

	&lt;mx:Component id="sample_renderer"&gt;
		&lt;mx:VBox verticalAlign="middle" horizontalAlign="center"&gt;
			&lt;mx:Label fontWeight="bold" text="{data.label}" /&gt;
			&lt;mx:Image source="{data.src}" /&gt;
		&lt;/mx:VBox&gt;
	&lt;/mx:Component&gt;

	&lt;mx:TileList 
		columnWidth="150" 
		rowHeight="150" 
		columnCount="3" 
		dataProvider="{sample_arr}" 
		itemRenderer="{sample_renderer}" /&gt;

&lt;/mx:Application&gt;
</pre>


ブラウザには表示はされるけど、嫌なエラーなので検索してみると、同様な記事が FXUG にありました。
・<a href="http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=641" target="_blank">記事</a>

なにやら<strong>動的なプロパティを持つ Object は明示的に Bindable にしてあげない</strong>といけないらしい。なので、明示的に Object のプロパティを Bindable にする AS Class を作成し、Bindable な Array に各 Object を追加して、その Array を先程の ArrayCollection Object の代わりに TileList の dataProvider に Bind することでエラーが出なくなった。


■ Object のプロパティ を Bindable にする AS Class
<pre>
package
{
	public class SetData
	{
		[Bindable]
			public var label:String;
			
		[Bindable]
			public var src:Class;

		public function SetData(label:String, src:Class) {
			this.label = label;
			this.src   = src;
		}
	}
}
</pre>


■ 最終的なソース
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	viewSourceURL="source/index.html"
	layout="absolute"&gt;
	
	&lt;mx:Script&gt;
		&lt;![CDATA[
			
			[Bindable]
				[Embed(source='asset/image01.jpg')]
				private var image01:Class;
			[Bindable]
				[Embed(source='asset/image02.jpg')]
				private var image02:Class;
			[Bindable]
				[Embed(source='asset/image03.jpg')]
				private var image03:Class;
			[Bindable]
				[Embed(source='asset/image04.jpg')]
				private var image04:Class;
			[Bindable]
				[Embed(source='asset/image05.jpg')]
				private var image05:Class;
			[Bindable]
				[Embed(source='asset/image06.jpg')]
				private var image06:Class;

			[Bindable]
				private var sample_arr:Array = [
					new SetData("image01", image01),
					new SetData("image02", image02),
					new SetData("image03", image03),
					new SetData("image04", image04),
					new SetData("image05", image05),
					new SetData("image06", image06)
				]
		]]&gt;
	&lt;/mx:Script&gt;

	&lt;mx:Component id="sample_renderer"&gt;
		&lt;mx:VBox verticalAlign="middle" horizontalAlign="center"&gt;
			&lt;mx:Label fontWeight="bold" text="{data.label}" /&gt;
			&lt;mx:Image source="{data.src}" /&gt;
		&lt;/mx:VBox&gt;
	&lt;/mx:Component&gt;

	&lt;mx:TileList 
		columnWidth="150" 
		rowHeight="150" 
		columnCount="3" 
		dataProvider="{sample_arr}" 
		itemRenderer="{sample_renderer}" /&gt;

&lt;/mx:Application&gt;
</pre>]]>
   </content>
</entry>
<entry>
   <title>SQLite in AIR</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2007/10/sqlite_in_air.html" />
   <id>tag:dev.convexstyle.net,2007://1.43</id>
   
   <published>2007-10-16T15:20:25Z</published>
   <updated>2007-10-16T15:35:18Z</updated>
   
   <summary>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 系の...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="AIR" scheme="http://www.sixapart.com/ns/types#category" />
         <category term="ActionSctipt 3.0" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="23" label="AIR" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[Apollo Mini Camp で <a href="http://www.amazon.co.jp/Apollo-Adobe-Flex-Developers-Pocket/dp/0596513917/SubscriptionId=ON9KBBBXNXGBYSAE9RG2%22" target="_blank">Apollo for Adobe Flex Developers</a> 等の著者の <a href="http://mikechambers.com/blog/" target="_blank">Mike Chambers</a> さんが AIR から SQLite を導入すると話していましたが、AIR より実際に導入されたので、現在開発中の AIR アプリケーションに実際に実装してみた。もともと必要な情報を FileStream クラスでローカルに xml の様なファイル書き出ししようかと考えていたが、データをもっと Secure に扱いかったので SQLite を使用。まだまだもっと使えて欲しいなあ…という部分もけっこうあるんですが、まあ、Beta の段階だしね。

使用方法は、基本的な SQL 構文の知識と AIR で実装されている <a href="http://livedocs.adobe.com/labs/flex/3/langref/flash/data/SQLConnection.html" target="_blank">SQLConnection</a> class、
<a href="http://livedocs.adobe.com/labs/air/1/aslr/flash/data/SQLStatement.html" target="_blank">SQLStatement</a> class、<a href="http://livedocs.adobe.com/labs/flex/3/langref/flash/data/SQLResult.html" target="_blank">SQLResult</a> class、<a href="http://livedocs.adobe.com/labs/flex/3/langref/flash/filesystem/File.html" target="_blank">File</a> 系の class 辺りを連携させることで、至って簡単に使用することで実現できる。

]]>
      <![CDATA[サンプルソースは下記の通り。
（このサンプルソースではエラー処理は簡略化のため結構省いてます。）

<pre>

&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:WindowedApplication 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="absolute" 
	width="100%" 
	height="100%" 
	creationComplete="init()"&gt;
	
	&lt;mx:Script&gt;
		&lt;![CDATA[
			
			import flash.events.Event;
			import flash.data.SQLConnection;
			import flash.data.SQLStatement;
			import flash.data.SQLResult;
			import flash.filesystem.File;
			import mx.controls.Alert;
			
			private var file:File;
			private var conn:SQLConnection;
			private var stmt:SQLStatement;
			
			// データベース初期設定用関数
			private function init():void {
				file = new File();
				file = File.applicationStorageDirectory.resolve("data");
				if(!file.isDirectory) file.createDirectory();
				file = file.resolve("sample.sqlite");
				
				conn = new SQLConnection();
				conn.addEventListener(SQLEvent.OPEN, onDBOpen);
				conn.addEventListener(SQLErrorEvent.ERROR, onDBError);
				conn.open(file);
			}
			private function onDBOpen(evt:SQLEvent):void {
				Alert.show("DB 接続成功");
			}
			private function onDBError(evt:SQLErrorEvent):void {
				Alert.show("DB 接続失敗: " + evt.text);
			}
			
			// テーブル作成用関数
			private function createTable(evt:MouseEvent):void {
				var sql:String = "CREATE TABLE tbl_sample (";
				sql += "id INTEGER PRIMARY KEY, ";
				sql += "title VARCHAR(32) NOT NULL, ";
				sql += "rec_time datetime NOT NULL)";
				execSQL(sql, function():void { Alert.show("Table 作成成功") });
			}
			
			// データ入力用関数
			private function insertData(evt:MouseEvent):void {
				if(title_txt.text == "") {
					Alert.show("タイトルを入力してください。");
					return;
				}
				var sql:String = "INSERT INTO tbl_sample (title, rec_time) ";
				sql += "VALUES ('"+ title_txt.text +"', datetime('now','localtime'))";
				execSQL(sql, function():void { Alert.show("データ入力成功") });
			}
			
			// データ選択用関数
			private function selectData(evt:MouseEvent):void {
				var sql:String = "SELECT * FROM tbl_sample ORDER BY id DESC";
				execSQL(sql, getResult);
			}
			
			private function getResult(evt:SQLEvent):void {
				var d:String = "";
				var result:SQLResult = stmt.getResult();
				for each(var obj:Object in result.data) {
					for(var col:String in obj) {
						d += "column name: " + col + " value: " + obj[col] + "\n";	
					}
				}
				data_txt.text = d;
			}
			
			// SQL 実行用関数
			private function execSQL(sql:String, closure:Function):void {
				if(!conn.connected) return;
				stmt = new SQLStatement();
				stmt.sqlConnection = conn;
				stmt.addEventListener(SQLEvent.RESULT, closure);
				stmt.addEventListener(SQLErrorEvent.ERROR, onDBError);
				stmt.text = sql;
				stmt.execute();
			}
		]]&gt;
	&lt;/mx:Script&gt;
	
	&lt;mx:VBox&gt;
		&lt;mx:FormItem label="タイトル（３２文字まで）"&gt;
			&lt;mx:TextInput id="title_txt" width="300" height="20" maxChars="32" /&gt;
		&lt;/mx:FormItem&gt;
		&lt;mx:HBox&gt;
			&lt;mx:Button label="テーブルを作成する" click="createTable(event)" /&gt;
			&lt;mx:Button label="データを入力する" click="insertData(event)" /&gt;
			&lt;mx:Button label="データを表示する" click="selectData(event)" /&gt;
		&lt;/mx:HBox&gt;
		&lt;mx:Spacer height="30" /&gt;
		&lt;mx:FormItem label="データ表示"&gt;
			&lt;mx:TextArea id="data_txt" width="400" height="200" /&gt;
		&lt;/mx:FormItem&gt;
	&lt;/mx:VBox&gt;
&lt;/mx:WindowedApplication&gt;
</pre>

]]>
   </content>
</entry>
<entry>
   <title>ViewStack</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2007/10/viewstack.html" />
   <id>tag:dev.convexstyle.net,2007://1.42</id>
   
   <published>2007-10-10T14:25:56Z</published>
   <updated>2007-10-10T14:34:42Z</updated>
   
   <summary>自分の様に Flash 開発に慣れている場合、Flash の時間軸の概念に基づいて画面遷移やコンテンツの切り替えを行う。簡単に言えば、ログインは frame1、メインコンテンツは frame2、ログアウトは frame3 にそれぞれ gotoAndStop() しフレームを移動させることによって画面遷移を行う。 しかし、Flex の開発になった途端、結構な Flash をやる方はこの時間軸の考えが無くなり少し混乱することがあるんじゃないか。最近、自分は会社で本格的に AIR アプリ制作と、その他個人で Flex 開発をしていて、少なからずこのポイントで悩んだのでメモ。 色々と検索してみると、同様な記事が FXUG にありました。 ・記事１ ・記事２ 全く分からなかった時は ActionScript で制御するのか、でも凄い効率悪いし Flex Framework を使っている意味無いしとか感じていましたが、ViewStack ですべてのモヤモヤが解消されました。他にも SWFLoader の方法もありますが、個人的には ViewStack が今回の用途に合っていたのでこっちを使用してみた。...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="14" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[自分の様に Flash 開発に慣れている場合、Flash の時間軸の概念に基づいて画面遷移やコンテンツの切り替えを行う。簡単に言えば、ログインは frame1、メインコンテンツは frame2、ログアウトは frame3 にそれぞれ gotoAndStop() しフレームを移動させることによって画面遷移を行う。
しかし、Flex の開発になった途端、結構な Flash をやる方はこの時間軸の考えが無くなり少し混乱することがあるんじゃないか。最近、自分は会社で本格的に AIR アプリ制作と、その他個人で Flex 開発をしていて、少なからずこのポイントで悩んだのでメモ。

色々と検索してみると、同様な記事が FXUG にありました。
・<a href="http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=62&forum=2&viewmode=flat&order=ASC&start=0" target="_blank">記事１</a>
・<a href="http://www.fxug.net/modules/xhnewbb/viewtopic.php?viewmode=thread&topic_id=1155&forum=16&post_id=4800#4800" target="_blank">記事２</a>

全く分からなかった時は ActionScript で制御するのか、でも凄い効率悪いし Flex Framework を使っている意味無いしとか感じていましたが、ViewStack ですべてのモヤモヤが解消されました。他にも SWFLoader の方法もありますが、個人的には ViewStack が今回の用途に合っていたのでこっちを使用してみた。]]>
      <![CDATA[<img src="http://dev.convexstyle.net/images/entry/200710/viewstack.gif" width="400" height="275" alt="ViewStack" title="ViewStack" class="normal" />
<em>ViewStack サンプル図</em>


基本的なソースは下記の通り。
これでポジションとか細かい設定を気にせず、MouseEvent に基づいて ViewStack 内の切り替えが自由になる。

<pre>

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"&gt;
	&lt;mx:Panel title="ViewStack サンプル" width="500" height="300" paddingTop="5" paddingBottom="5" paddingLeft="5" paddingRight="5"&gt;
		&lt;mx:HBox width="100%" horizontalAlign="center"&gt;
			&lt;mx:Button label="ログイン" click="myViewStack.selectedChild=login" /&gt;
			&lt;mx:Button label="メイン" click="myViewStack.selectedChild=main" /&gt;
			&lt;mx:Button label="ログアウト" click="myViewStack.selectedChild=logout" /&gt;
		&lt;/mx:HBox&gt;
		&lt;mx:ViewStack id="myViewStack" width="100%" height="100%" borderColor="#000000" borderStyle="solid" creationPolicy="auto"&gt;
			&lt;mx:Canvas id="login" width="100%" height="100%" backgroundColor="#FFFFCC"&gt;
				&lt;mx:Label text="ここはログインエリアです！" /&gt;
			&lt;/mx:Canvas&gt;
			&lt;mx:Canvas id="main" width="100%" height="100%" backgroundColor="#CCFFFF"&gt;
				&lt;mx:Label text="ここはメインエリアです！" /&gt;
			&lt;/mx:Canvas&gt;
			&lt;mx:Canvas id="logout" width="100%" height="100%" backgroundColor="#FFCCFF"&gt;
				&lt;mx:Label text="ここはログアウトエリアです！" /&gt;
			&lt;/mx:Canvas&gt;
		&lt;/mx:ViewStack&gt;
	&lt;/mx:Panel&gt;
&lt;/mx:Application&gt;
</pre>

もっと汎用性を持たせるなら、mx:Canvas 部分それぞれをクラス化して管理すると、開発効率や修正作業が断然上がりますね！
<pre>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:ns1="*"&gt;
	&lt;mx:Panel title="ViewStack サンプル" width="500" height="300" paddingTop="5" paddingBottom="5" paddingLeft="5" paddingRight="5"&gt;
		&lt;mx:HBox width="100%" horizontalAlign="center"&gt;
			&lt;mx:Button label="ログイン" click="myViewStack.selectedChild=login" /&gt;
			&lt;mx:Button label="メイン" click="myViewStack.selectedChild=main" /&gt;
			&lt;mx:Button label="ログアウト" click="myViewStack.selectedChild=logout" /&gt;
		&lt;/mx:HBox&gt;
		&lt;mx:ViewStack id="myViewStack" width="100%" height="100%" borderColor="#000000" borderStyle="solid" creationPolicy="auto"&gt;
			&lt;ns1:Canvas1 id="login" /&gt;
			&lt;ns1:Canvas2 id="main" /&gt;
			&lt;ns1:Canvas3 id="logout" /&gt;
		&lt;/mx:ViewStack&gt;
	&lt;/mx:Panel&gt;
&lt;/mx:Application&gt;
</pre>]]>
   </content>
</entry>
<entry>
   <title>Adobe ケーススタディー</title>
   <link rel="alternate" type="text/html" href="http://dev.convexstyle.net/2007/10/adobe.html" />
   <id>tag:dev.convexstyle.net,2007://1.41</id>
   
   <published>2007-10-09T14:49:42Z</published>
   <updated>2007-10-09T15:01:42Z</updated>
   
   <summary>Adobe ケーススタディーに会社の&quot;カラメル&quot;のワークが載りました。自分は大した事はしてないですが、少しだけ Flash で絡んだのでオマケ程度に載ってます。 関係ないですが、社長と自分の動きがかぶっていたので、社長が作りました。外人は誰だか分かりませんが、ウケタので載せておきます。 Adobe ケーススタディー...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Interview" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="21" label="Adobe" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://dev.convexstyle.net/">
      <![CDATA[<a href="http://www.adobe.com/cfusion/showcase/index.cfm?event=casestudydetail&casestudyid=348283&loc=ja" target="_blank">Adobe ケーススタディー</a>に会社の"<a href="http://calamel.jp/" target="_blank">カラメル</a>"のワークが載りました。自分は大した事はしてないですが、少しだけ Flash で絡んだのでオマケ程度に載ってます。

関係ないですが、社長と自分の動きがかぶっていたので、<a href="http://hbkr.jp/" target="_blank">社長</a>が作りました。外人は誰だか分かりませんが、ウケタので載せておきます。

<a href="http://www.adobe.com/cfusion/showcase/index.cfm?event=casestudydetail&casestudyid=348283&loc=ja" target="_blank"><img src="http://dev.convexstyle.net/images/entry/200710/adobe_interview_s.jpg" width="400" height="175" alt="Adobe ケーススタディー" title="Adobe ケーススタディー" class="link" /></a>
<em>Adobe ケーススタディー</em>]]>
      
   </content>
</entry>

</feed>
