Flash

Express Install のブルー背景の回避方法

これまでは、開発・制作した swf ファイルのバージョンがユーザーのバージョンよりも高かった場合、一度 Adobe(旧、Macromedia)のサイトに移動して最新の Flash Player をインストールしてから目的とページに戻ってくるといった、非常に効率の悪いインストールが通常だった。
こうしたプロセスを通ってでもユーザーが全員また元のサイトに戻ってきてくれればいいが、Flash Player のインストールの最中にめんどくさくなってインストール自体を止めたり、インストールが完了しても元のサイトに戻ってこないユーザーも少なからずいることが想像される。自分が会社で開発しているサービスなどはこういったユーザーの行動は致命的なのでどうしたら回避できるだろうかと考えていたら、Adobe からあり難い事に『Express Install』というパッケージを配布していたので使ってみた。


Express Install は Adobe で開発した便利パッケージ。
様は、このパッケージにより、これまで Adobe(旧、Macromedia)のサイトに移動して
最新 Flash Player をインストールしなければならなかったプロセスを、ユーザーが訪れたサイト上で最新 Flash Player をインストールを完了できる様になり、インストール後は通常通り訪問先のサイトを見ることが可能になった。まだ多くのユーザーが Flash Player 7 をインストールしている現在、Flash Player 8 のみ対応のコンテンツを作成した場合などには、Express Install は大きな効果を発揮するだろう。


Adobe のサイトを参考にすれば、Express Install の設定はいたって簡単である。

【参考サイト】
http://www.adobe.com/jp/devnet/flashplayer/articles/expressinstall.html

【パッケージのダウンロード先】
http://download.macromedia.com/pub/flash/detection_kit/detectionkit.zip


これにより、Express Install は設定できたはずだが、1つ問題が生じるはずである。
それはインストールのダイアログが表示している時に、swf の背景色がブルーになっていることだ。特に、ダイアログを表示する swf は Adobe のサーバ上にあるブラックボックス的なものであり、私達ではどうにもすることは出来ない。特に気にしない場合にはこのままの背景で問題はないのだが、周りのデザインのこともあり、出来ればダイアログが表示しているときにも周りのデザインに溶け込ませたい背景を配置した場合には場合は、下記の様に多少の ActionScript の追加とカスタマイズにより、ブルー背景色を回避し、独自の背景を表示することが可能である。


【回避方法】
(1)
先ほどの Adobe サイトの手順に従って作成した場合、ドキュメント上に「AutoUpdater」、「AutoUpdaterLoaderClip」の2つの MovieClipがあると思うが、この2つの MovieClip をドキュメント上から削除する。ちなみに、色々 MovieClip のカスタマイズを ActionScript で試みてみたが無理な様だった。これにより、2つの外部 AS ファイル「playerProductInstall.as」、「playerProductInstallCallback.as」が書き出しの際に読み込まれなくなる。

(2)
下記の ActionScript を frame 1 に追加する。
これにより、Adobe で準備された MovieClip に影響されることなく同様な動作を引き継ぐことは可能である。ActionScript は上記の2つの AS ファイルと AutoUpdater MovieClip の構成を崩さないように意識する。



stop();

// 読み込み確認
function checkLoaded() {
if (hold.startUpdate.toString() == "[type Function]") {
clearInterval(id);
loadComplete();
}
}

// 読み込み完了
function loadComplete() {
hold.redirectURL = _root.MMredirectURL;
hold.MMplayerType = _root.MMplayerType;
hold.MMdoctitle = _root.MMdoctitle;
hold.startUpdate();
}

// インストールの際のイベントハンドラ
function installStatus(statusValue) {
if (statusValue == "Download.Complete") {
// Flash Player のインストールが完了した際の処理を記述する。
trace("ダウンロードが完了);
} else if (statusValue == "Download.Cancelled") {
// Flash Player のインストールをキャンセルした際の処理を記述する。
// 通常、ページ内の特定ページに移動させる。
getURL("http://*********.com/cancel.html");
} else if (statusValue == "Download.Failed") {
// Flash Player のインストールが失敗した際の処理を記述する。
// 通常、ページ内の特定ページに移動させる。
getURL("http://*********.com/failure.html");
}
}

// Flash Player インストーラーの起動
System.security.allowDomain("fpdownload.macromedia.com");

// キャッシュ回避
var cacheBuster = Math.random();
var updateSWF="http://fpdownload.macromedia.com/pub/flashplayer/update/current/swf/autoUpdater.swf?" + cacheBuster;

// 「AutoUpdater」構成の作成
updater = _root.createEmptyMovieClip("expressInstallHolder", 5);
updater.installStatus = _root.installStatus;
hold = updater.createEmptyMovieClip("hold", 1);
var id = setInterval(checkLoaded, 10);
hold.loadMovie(updateSWF);

(3)
新規レイヤーを作成し、自分のサイトに適当な背景画像をドキュメント上に配置する。

(4)
書き出しをし、HTML タグを Adobe の参考サイトを基に、Javascript の特定の場所に組み込む。また、Flash Player の Express Install が必要ない場合の通常 Flash コンテンツの HTML タグも同様に、この Javascript 内に組み込む様にする。

【追記】
Microsoft Internet Explorer のアップデートにより、アクティブコンテンツのセキュリティーが強化されてしまった。アクティブコンテンツである Flash コンテンツもこの影響を受けており、Flash コンテンツ上で 1 度ワンクリックしなければFlash コンテンツはアクティブにならなくなってしまった。ボタンがある場合などは、どうしてもユーザーがクリックするが、1 度目は Flash コンテンツ自体をアクティブにすることのみで、onRelease などのボタンイベントは発生しない。これはユーザーに混乱を招くだけではなくユーザビリティを低下してしまうので、避けたいところである。対策としては Flash を表示する HTML タグをすべて外部 Javascript ファイルにおいて document.write メソッドで書き出すことで簡単に回避されるが、さらに Adobe で準備している Javascript Library を使用することで、必要なパラメータを Adobe 独自の関数に渡すだけで Flash コンテンツを HTML 上に生成する。

【参考サイト】
http://www.adobe.com/jp/devnet/activecontent/articles/devletter.html


(5)
Flash Player のバージョンが低いブラウザでテストし、以下の様に、背景画像のあるダイアログ画面が表示したら成功である。


Express Install サンプル写真
サンプル画像:3ミリより


ページの一番上へ移動

Flickr の新着 RSS 読み込み時の crossdomain 問題回避方法

昔、www.flickr.com は crossdomain.xml で に設定されていた記憶があった(この記憶も定かではないですが。。。)ので、Flickr の新着アップロード写真の RSS を flash 内でダイレクトに parse して、あるアプリケーションでビジュアライズしていたのですが、自分のサーバにアプリケーションをアップロードしてテストしたら、最近は crossdomain.xml 自体が www.flickr.com のサーバにはすでに存在せず、当然の結果ですが、別サーバにある自分のアプリケーションから flickr の新着用 RSS を crossdomain のセキュリティ問題で読み込みに失敗。
今は Flickr の API Key を使えば簡単に crossdomain を回避して何でも作れるんですが、世界中の多くの人が写真をアップロードしていく Flickr の新着 RSS はタイムリーに変化していく、アプリケーションの作り手にはかなり面白いリソースであるため、どうしてもこの RSS を使用したい願望から、ソリューションはサーバ側で proxy 処理をすることにしました。

Flickr の新着 RSS 読み込み時の crossdomain 問題回避方法
Flickr の新着 RSS 読み込み時の crossdomain 問題回避方法


単純な RSS の読み込みなので reverse proxy の様な Apache レベルの設定ではなく、PHP で proxy 処理を作成。PEAR の HTTP_Request を使用して簡単に実装できました。以下が簡単な実装例の PHP スクリプトサンプルです。



<?php

require_once('HTTP/Request.php');
define('XML_URL', 'Flickr の新着写真用 RSS Feed の URL');
$cacheOut = md5(microtime());
$req =& new HTTP_Request(XML_URL.'&'.$cacheOut);

if(!PEAR::isError($req->sendRequest())) {
header('Content-type: text/xml; charset=UTF-8');
echo $req->getResponseBody();
}

?>


これを Flash 側で XML.load で読み込めば、別サーバの RSS も、crossdomain を回避してすんなり xml を読み込めます。また、ここから flash 内で parse した thumbnail は http://static.flickr.com/64/228329290_7e7fb1c681_s.jpg の様に static.flickr.com のサーバ上にあるんですが、これは何故か crossdomain を意識せずに flash 内に読み込まれました。liveHTTPheaders で http の通信を調べてみたんですが、flash 側から static サーバにアクセスした際に crossdomain を見ていないので、この点に関しては謎です。


【使用技術】
PEAR(HTTP_Request)、PHP 5、Flickr の新着 RSS、Flash 8

ページの一番上へ移動

エンドが取れない FLV のエンドを取る方法

携帯動画をサーバで動的に FLV に変換したリ、mov などの動画ファイルを QuickTime Pro などのオーサリングソフトフェアで FLV 書き出しした場合、"モノ"によってはエンドが取れない FLV が混在する。言い変えれば60秒の動画が 59.382 秒とかで実質止まってしまうのである。(このエンドを取れない動画は特定の携帯機種に依存しているのか、変換時の問題なのか、動画作成時の問題なのかよく分からないので、この問題に関して分かってる人は教えていただきたい!)


エンドが取れない FLV のエンドを取る方法
エンドが取れない FLV のエンドを取る方法


動画のエンドを取る方法は、NetStream Object の onStatus イベントハンドラへ渡る情報オブジェクトの code プロパティが NetStream.Play.Stop に一致するのを確認するのが一般的だと思うのですが、エンドの取れない動画に関してはこの一致を確かめる事が出来ない。つまり、例えば、10個の動画を次々と流していく時に、NetStream の onStatus イベントに頼っていると、エンドの取れない動画で止まってしまうのである。

ここで代案として行ったのは、Flash Video Exporter ユーティリティ (バージョン 1.1 以降) で動画を FLV 変換する事で動画に組み込まれる Meta データの duration 値と NetStream の time プロパティを絶えず比較して、動画のエンドを確認する方法がである。こっちの方が経験上、問題を回避する可能性が大きいだろう!この NetStream の time プロパティと duration を絶えず比較する方法だが、おそらく onEnterFrame か setInterval のどちらかだと思うのだが、試した際 onEnterFrame の場合はフレームレートに依存するがあまりにも早く反応してしまうのでここでは適さず、今回は setInterval で 500 ミリセカンド毎に(このミリセカンドくらいがちょうど良かった。)比較用関数を呼び出すことにした。


サンプルソースは下記の通りである。
(このソースは、分かりやすさ優先で1つの動画が終了した時点で clearInterval しているが、連続する場合は次の動画を再生する関数と、clearInterval は使用しないようにする。)



// NetConnection オブジェクト設定
var nc:NetConnection = new NetConnection();
nc.connect(null);

// NetStream オブジェクト設定
var receive_ns:NetStream = new NetStream(_root.nc);
receive_ns.play("FLV 名");
video_obj.attachVideo(receive_ns);

// onStatus イベントハンドラ
receive_ns.onStatus = function(infoObj:Object):Void {
switch(infoObj.code) {
case "NetStream.Buffer.Full":
if(!initFlg) {
checkTime();
initFlg = true;
}
break;
default:
trace(infoObj.code);
}
}

// Meta 情報から duration を取得
var duration:Number;
receive_ns.onMetaData = function(infoObj:Object):Void {
duration = Math.floor(infoObj["duration"]);
}

// NetStream.time と duration の比較
function checkTime():Void {
function checkEachTime():Void {
if(receive_ns.time >= duration) {
clearInterval(progNum);
trace("動画が終了");
}
trace(receive_ns.time);
}
var progNum:Number = setInterval(checkEachTime ,500);
}


今回は動的に動画を作成したりする環境で、動画を1つ1つ確認できない環境下での動画の連続再生に適しているだろう。もし動画が確実にエンドを取るのを確認できる場合にはonStatus イベントハンドラのNetStream.Play.Stop で操作する方が効率いいだろう。
個人的には NetStream の onStatus が、http 通信下の不安定な状況下で予想外の挙動をするので setInterval を使うようにしている。他にも方法があると思うので、この問題を回避したという方は教えていただきたい。

ページの一番上へ移動

Flash Remoting のデバッグ方法

Flash で http 非同期通信する Flash Remoting には AMFPHP、PHPObject、Flap、Coldfusion Component とか複数ありますが、個人的には AMFPHP が好きなのでよく使っているんですが、問題は Flash Remoting で生じるデバッグ方法。

Flash Remoting のデバッグ方法構成図
Flash Remoting のデバッグ方法構成図

Remoting 関連のデバッグには大抵 NetConnection Debugger を使ってデバッグしますが、動作が不安定であんまり使用したくありません。そのため PHP 側でテキストを作成しデバッグする"FileDumper"というクラス使用し、サーバ上でこのテキストを vi で直接開いてエラー情報を直接認識した方がかなり効率的で time-effective!実際にアプリケーション作成時にかなり助かってます。

以下、FileDumper サンプルソースになります。

この記事の続きを読む »

ページの一番上へ移動

convexStyle リニューアル

まだ完全では無いが、約 2 年ぶりに convexStyle をリニューアル。英語で過去をアーカイブ化したかった。


convexStyle リニューアル


【使用技術】
Flash 8 Professional、 ActionScript 2.0、 AMFPHP、 MySQL、 XML、 HTML、 Javascript、 CSS、 Photoshop 7、Illustrator 10

【担当領域】
上記と同じ

ページの一番上へ移動

Array.Shuffle

PHP だと shuffle 関数であっさり Array をシャッフルしてくれるけど、Flash は別。
かなり基本的な内容だけど、class で使い回し MovieClip を上手く操作すれば表現面に重宝できるので記述。


shuffleArray class


class shuffleArray {
private var _origLen:Number;
private var _origArr:Array;
public function shuffleArray() {

}
public function setArray(arr:Array):Void {
this._origLen = arr.length;
this._origArr = arr;
}
public function getArray():Array {
var newArr:Array = new Array();
for(var i:Number = 0; i < this._origLen; i++) {
var ranNum:Number = Math.floor(Math.random() * this._origArr.length);
newArr[i] = this._origArr.splice(ranNum, 1);
}
return newArr;
}
}

Flash 内で使用する場合


var shuffleArray:shuffleArray = new shuffleArray();
var sampleArray:Array = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
shuffleArray.setArray(sampleArray);
sampleArray = shuffleArray.getArray();


【参照】
http://www.sephiroth.it/proto_detail.php?id=149

ページの一番上へ移動

Picto list

2 ヶ月程前に開発・リリースした picto という Jugem のブログの機能の Flash ベースの絵文字エディタなんですが、凄い勢いでユーザーさんが作成してくれたので一覧表示にしてみました。これまで Jugem ユーザーの管理画面内でしか見れなかったので一般にも見れるようになりました。中にはプロ級のユーザーさんもいるんですが、全ユーザーさんの作成速度が速いので、一覧にすればもっと見る機会が増えるかと。新着絵文字100件、人気絵文字100件、人気ユーザー100件表示です。


picto list
The screenshot of picto list


p.s.
JugemKey にログインしていると一発で picto に「お気に入り登録」することが可能になりました。

【使用技術】
Flash 8 Professional、ActionScript 2.0、AMFPHP 1.2、PHP CLI、MySQL、Fedora Core 4、HTML、Javascript、Photoshop CS 2


【担当領域】
同上

ページの一番上へ移動

AMFPHP 1.9-beta

Flash Remoting には様々なものがありますが、自分がよく使用しているのが AMFPHP。前までは Stable 版の AMFPHP 1.2 を使っていましたが、今年に入って個人作品レベルではづっと AMFPHP 1.9-beta を使い始め、非常に使い勝手が良くなったなあと感心。使い勝手が良くなったのは method table が無くなって関数の定義をする必要がなくなったことや、AMF 3.0 をサポートし Flex から Remote Object で接続できる様になったことなどがありますが、特に Service Browser はこれまでのデバッグ時間を確実に軽減してくれるので最高!


Service Browser は自分で作成する Remoting 用のサービスファイル(class ファイル)内で fatal error やロジックエラーがある場合の確認や、パラメータを取る場合、直接パラメータに値を渡して返り値を確認できます。データベースから select して取得した連想配列も確認できます。従来は不安定な NetConnection Debugger や個人的にクラスを埋め込んでテキスト書き出ししてデバッグを確認していましたが、Service Browser を使用したらすぐに確認できるので開発効率が相当良くなりました。FMS の administrator console っぽい直感的なインタフェースもいいし。


Service Browser のデモはココ

ページの一番上へ移動

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 したら他のイベントクラスは必要なかったし汎用性があると思うけど、作成時はこんなもんだったんで今後直します。

この記事の続きを読む »

ページの一番上へ移動

SWFUpload

会社でも以前話題になったんですが、それ以前からFlickr の画像アップローダーが生かしてるな~って思ってどうしてるんだろう思ってんですが、SWFUpload っていう便利クラスがあるんですね。どう実現してるのか知りたくて横取り丸で Flickr の通信を見た際にこんな swf があったんで、バイト数を External Interface とかで JS 側に渡してるのかなって思ってたんですが、こんな便利クラスがあるんだったら使ってみようってことで試してみました。


SWFLoad
SWFLoad

Flickr Uploader
Flickr Uploader

この記事の続きを読む »

ページの一番上へ移動

FLV の相対パス

凄い基本的な話なのですが、FLV を使用するときは絶対パスでのプログレッシブ再生か FMS を利用したストリーミング配信でのみ開発したことがあったのですが、先日相対パスで読み込もうとしたら読み込めず、httpHeaders で調べたら 404 が返っておかしな挙動をしていたのでメモ。

理由は単純なんですが、仕様を明確に目にしたかったので調べたらこのページにこんな記述が。

注意:ビデオクリップがFLV形式の場合、FLVファイルのパスは相対パス(SWFを基準にした相対位置)で指定されるので、サーバ上で使用するのと同じディレクトリ構造をローカルでも使用できます。

この記事の続きを読む »

ページの一番上へ移動

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 的な使い勝手で今更ながら感動です。


この記事の続きを読む »

ページの一番上へ移動

HTTP_Request で HTTP レスポンス情報の評価

明けましておめでとうございます。

前回に引き続き、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 でも同様な処理を行ったがそんなに処理速度が変わらなかった。何か他の方法は無いだろうか。

この記事の続きを読む »

ページの一番上へ移動

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 辺りで改善されそうな内容ですが、一時的な改善策としてこんな感じらしい。念のため、ソースは下記に。

この記事の続きを読む »

ページの一番上へ移動

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 の内部は変わらない。

この記事の続きを読む »

ページの一番上へ移動