イナヅマTVログ

2011.03.03
17:46
author: taikiken
2件のコメント

OSMF(Open Source Media Framework)でVideo再生

OSMF(Open Source Media Framework)を使ってビデオファイル(FLV, F4V)を再生してみるメモ。
Adobe Open Source : Open Source Media Framework
現在のstableはVer.1.5。
注目のStage Video対応は1.6からになります。

OSMFを使用すると対象Flash Playerは10.1からとなるらしい。
Flex SDK 4.1からosmf.swcは同梱されてるらしい。
Flash Builder 4 setup

Flex SDK 4.5.0.17689

package com.inazumatv.video
{
	import flash.display.DisplayObjectContainer;
 
	import org.osmf.elements.VideoElement;
	import org.osmf.events.MediaErrorEvent;
	import org.osmf.events.MediaPlayerStateChangeEvent;
	import org.osmf.events.PlayEvent;
	import org.osmf.events.TimeEvent;
	import org.osmf.media.MediaPlayer;
	import org.osmf.media.MediaPlayerSprite;
	import org.osmf.media.URLResource;
	import org.osmf.metadata.CuePoint;
	import org.osmf.traits.TraitEventDispatcher;
 
	public class PlayerSprite extends Object
	{
		private var _container:DisplayObjectContainer;
		private var _mps:MediaPlayerSprite;
		private var _videoElement:VideoElement;
		private var _mp:MediaPlayer;
 
		// ----------------------------------------
		//	CONSTRUCTOR
		// ----------------------------------------
		public function PlayerSprite(container:DisplayObjectContainer)
		{
			_container = container;
			init();
		}
		private function init():void
		{
			var source:String = 'rtmp://cp67126.edgefcs.net/ondemand/mp4:mediapm/osmf/content/test/cuepoints/spacealonehd_sounas_640_with_nav.f4v';
			_mps = new MediaPlayerSprite();
			_mp = mps.mediaPlayer;
 
			var resource:URLResource = new URLResource(source);
 
			_videoElement = new VideoElement();
			videoElement.resource = resource;
 
			var dispatcher:TraitEventDispatcher = new TraitEventDispatcher();
			dispatcher.media = videoElement;
			dispatcher.addEventListener(PlayEvent.PLAY_STATE_CHANGE, onPlayStateChange);
 
			mp.addEventListener(TimeEvent.CURRENT_TIME_CHANGE, onTimeUpdated);
			mp.addEventListener(TimeEvent.DURATION_CHANGE, onTimeUpdated);
			mp.addEventListener(MediaErrorEvent.MEDIA_ERROR, onMediaError);
 
			mp.addEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, onMediaPlayerStateChange);
 
			mp.media = videoElement;
 
			try{
				container.addChild(_mps);
			} catch (error:TypeError) {
				trace(error);
			}
		}
		// ----------------------------------------
		//	EVENT HANDLER
		// ----------------------------------------
		private function onMediaError(event:MediaErrorEvent):void
		{
			trace(event);
		}
		private function onMediaPlayerStateChange(event:MediaPlayerStateChangeEvent):void
		{
			trace(event.state);
		}
		private function onPlayStateChange(event:PlayEvent):void
		{
			trace(event.playState);
		}
		private function onTimeUpdated(event:TimeEvent):void
		{
			trace('time: ' + mp.currentTime + ' duration: ' + mp.duration);
		}
		// ----------------------------------------
		//	GETTER / SETTER
		// ----------------------------------------
		// MediaPlayer
		public function get mp():MediaPlayer
		{
			return _mp;
		}
		// MediaPlayerSprite
		public function get mps():MediaPlayerSprite
		{
			return _mps;
		}
		// VideoElement
		public function get videoElement():VideoElement
		{
			return _videoElement;
		}
	}
}

ダウンロードしたOSMFのサンプルを参考にコードを作成しました。
ビデオURLはサンプルファイルに書かれているものです。
ちょっぴり悲しいアニメーションです。

トレースの結果は以下のようになります。
タイムコードのトレースは省きました。

onMediaPlayerStateChange loading
 
onPlayStateChange playing
 
onMediaPlayerStateChange ready
onMediaPlayerStateChange buffering
onMediaPlayerStateChange playing
 
onPlayStateChange stopped
 
onMediaPlayerStateChange buffering
onMediaPlayerStateChange ready

OSMFの要はorg.osmf.media.MediaPlayerだと思われます。
ただMediaPlayerDisplayObjectではないのでaddChildできません。
なのでMediaPlayerだけどDisplayObjectMediaPlayerSpriteが存在するのかも。

MediaPlayerSpriteを使わずMediaPlayerを使う場合は以下のようにします。

var source:String = 'assets/example.f4v';
var mp:MediaPlayer = new MediaPlayer();
var resource:URLResource = new URLResource(source);
var video:VideoElement = new VideoElement();
video.resource = resource;
mp.media = video;
container.addChild(mp.displayObject);

MediaPlayer.displayObjectをaddChildします。
なんかちょっと気持ち悪い使い方のような気がしますが…

【おまけ】
swcになってるパッケージのバージョンってどうやったら確認できるんだろ?

2011.02.27
21:41
author: taikiken
0件のコメント

Flex, Google Maps API for Flash で作った地図が表示されない!大変だぁ〜

Flash Builder 4 で Google Maps API for Flashで作ったGoogle Mapが表示されない、表示されるまでにとても時間がかかるトラブルに遭遇。
AIR アプリケーションを作ろうとしています。

【制作環境】
Flex SDK 4.5.0.17689
Google Maps API for Flash 1.20 (map_flex_1_20.swc)

表示される
UIComponentに直接addChildすると表示されます。

private function initApplecation():void
{
	var uic:UIComponent; = new UIComponent();
	addElement(_uic);
	var map:Map = makeMap();
	uic.addChild(map);
}
private function makeMap():Map
{
	var map:Map = _map = new Map();
	map.language = 'ja';
	map.key = "YOUR MAP KEY";
	map.url = "YOUR DOMAIN";
	map.sensor = 'false';
	map.setSize(new Point(600, 300));
	map.addEventListener(MapEvent.MAP_READY, onReady);
	map.addEventListener(MapEvent.MAP_INITIALIZE_FAILED, onFaile);
	return map;
}
private function onFaile(event:MapEvent):void
{
	trace(event);
}
private function onReady(event:MapEvent):void
{
	trace(event);
}

UIComponentにDisplayObjectContainer(MovieClipやSprite)をaddChildしてそれにMapをaddChildすると表示できません。

表示できない
MovieClipへaddChild

private function initApplecation():void
{
	var uic:UIComponent; = new UIComponent();
	addElement(_uic);
	var map:Map = makeMap();
 
	var mc:MovieClip = new MovieClip();
	uic.addChild(mc);
	mc.addChild(map)
}

表示できない
SpriteへaddChild

private function initApplecation():void
{
	var uic:UIComponent; = new UIComponent();
	addElement(_uic);
	var map:Map = makeMap();
 
	var sp:Sprite =  new Sprite();
	uic.addChild(sp);
	sp.addChild(map);
}

Google のサンプルコード例です。

<maps:Map xmlns:maps="com.google.maps.*" id="map" mapevent_mapready="onMapReady(event)" width="100%" height="100%" 
    url="http://code.google.com/apis/maps/" key="your_api_key"/>

以下のように解説されています。

簡単な例ですが、次の点に注意してください:

  1. 最初に <mx:Application> を宣言し、Flex アプリケーションに必要なコードのすべてを収容します。この <mx:Application> オブジェクト内で、xm 名前空間を宣言し、標準の Flex コンポーネントを参照します。
  2. Map オブジェクトを <mx:Application> の子として宣言し、maps 名前空間を定義して com.google.maps.* からコードを参照します。id、mapevent_mapready ハンドラ、API の key などのパラメータも定義します。これらのパラメータについては後で説明します
  3. 子の <mx:Script> オブジェクト内で ActionScript コードを定義します。
  4. その ActionScript コードで、mapevent_mapready イベントの受け取り時に地図を中心に配置します。

なにかこちらのやり方が間違っているのかもしれません。
MXMLには馴染めないせいもあって、宣言だけしたあとは全てActionScript(Class)へ記述する制作手法をとっているのですが、それがまずいのかもしれません。

ちなみにサブウインドウにも表示できませんでした。

private function initApplecation():void
{
	var map:Map = makeMap();
 
	var window:NativeWindow =  new makeWindow();
	window.stage.addChild(map);
}
private function makeWindow():NativeWindow
{
	var option:NativeWindowInitOptions = new NativeWindowInitOptions();
	option.resizable = false;
	option.systemChrome = NativeWindowSystemChrome.NONE;
	option.transparent = false;
	option.type = NativeWindowType.LIGHTWEIGHT;
 
	 var window:NativeWindow = new NativeWindow(option);
	window.width = 600;
	window.height = 300;
	window.x = 0;
	window.y = 0;
	window.alwaysInFront = true;
 
	window.activate();
	return window;
}

*表示されない場合も MapEvent.MAP_READY は発生します。
コンソールには Google Maps API for Flash のログが表示されています。

2011.02.24
01:05
author: taikiken
0件のコメント

Flash Builder 4, Java heap space エラーの対処法2 Flash Builder.ini

Flash Builder 4, Java heap space エラー
対処法として sdk/bin 内の jvm.config のメモリを増やしてしばらくは良かったのですがしだいに忌まわしい”Java heap space”が発生しはじめました。
アプリの起動・再起動を繰返してなんとかビルドしてたのですがとうとう Flash Builder 様もクラッシュされること数回。

どうも原因はsdk側のメモリではなくアプリ様のご様子。

環境設定をみてもメモリを増やすらしき設定を見つけられません。
Google先生にお聞きするとUS Adobe Forumに神のお言葉が…

Flash Builderフォルダの”Flash Builder.ini”にメモリの設定があるからそれを増やしなさい、とのこと。

ところがMacのFlash Builderフォルダ内にはファイルが見つかりません。
spotlight様も探せません。

おそるおそるパッケージを開くと、ありました Flash Builder.ini
メモリを1024mbに増やして保存しました。

パッケージはアプリ(app)を右クリック->パッケージの内容を表示で確認できます。

なんで、こんなとこにあんだよー
とぶつくさぶつくさ。

その後は快調にお仕事をされている Flash Builder 様なのでした。

update

またまた頻発する Java heap space.
え〜い、大判振舞だと 2048mb に変更したら Flash Builder 様は起動時にエラーをお吐きになり立ち上がることができなくなってしまいました。
その後は Java heap space がでたらFlash Builderを再起動で対応しています。
めんどくさいやつ!

update

プロジェクト -> クリーン
でも解消できた。

再起動より簡単なのでコチラを使うことにする。

でも、どの条件でエラーが発生するのか分からないので気持ち悪い。

現在の”Flash Builder.ini”の設定

-Xms1024m
-Xmx1024m
-XX:MaxPermSize=256m
-XX:PermSize=256m

2011.02.23
02:00
author: taikiken
0件のコメント

GTween, ColorAdjustPlugin saturationをproxyで

NyaさんがGTweenのColorAdjustPlugin saturationでTweetされたのに「proxyでできるかも」とreplyしたら、もう試されたとのこと。

やり取りは以下の通り。

【緩募】誰か!どなたかGTweenに詳しい方!frog.saturation = 0; みたいにできませんか? http://bit.ly/ejkH6R #piyopiyo

@ProjectNya proxyを使うとできるかもです。今ちょっと環境がないので、あとで試してみます。

@taikiken 使ってみたんですが、上手く行かず。あわわ。

その後お試しされたファイルをダウンロードさせていただけることに。
そのファイルを試させていただくまえに、ちょっと自分でゴニョゴニョしてみました。

[swfobj src=”http://www.inazumatv.com/contents/wp-content/uploads/2011/02/gtween-proxy-02.swf” width=”550″ height=”400″ id=”gtw-saturation” name=”gtw-saturation” class=”gtw-saturation” align=”none” allowfullscreen=”false” required_player_version=”10.0.0″]GTweenでsaturation+proxy[/swfobj]

コードは以下。
saturationを+100, -100, 0にするボタンを3つ置きました。
MovieClip frog_mcをステージに置いています。
durationを0にすると動作しないので限りなく0に近い数字を設定しました。

import com.gskinner.motion.GTween;
import com.gskinner.motion.easing.*;
import com.gskinner.motion.plugins.*;
import flash.events.MouseEvent;
 
ColorAdjustPlugin.install();
var gtw:GTween = new GTween(frog_mc);
gtw.ease = Sine.easeOut;
 
saturationPlus_btn.label = "saturation +100";
saturationPlus_btn.addEventListener(MouseEvent.CLICK, onSaturationPlus);
function onSaturationPlus (e:MouseEvent):void {
	gtw.end();
	gtw.duration = 0.5;
	gtw.proxy.saturation = +100;
}
saturationMinus_btn.label = "saturation -100";
saturationMinus_btn.addEventListener(MouseEvent.CLICK, onSaturationMinus);
function onSaturationMinus (e:MouseEvent):void {
	gtw.end();
	gtw.duration = 1;
	gtw.proxy.saturation = -100;
}
saturationZero_btn.label = "saturation 0";
saturationZero_btn.addEventListener(MouseEvent.CLICK, onSaturationZero);
function onSaturationZero (e:MouseEvent):void {
	gtw.end();
	gtw.duration = 0.0000001;
	gtw.proxy.saturation = 0;
}

できそうな気がする。
Nyaさんのファイルを試してみよう。

2011.02.20
14:27
author: taikiken
0件のコメント

ActionScript 3, URLRequestをcacheさせないためのtimestamp

URLRequestを使ってサーバーからデータを取得する時に問題となるのがキャッシュ。
これswfでもAIRでも同様の大問題です。
GET, POSTなどでパラメタを変更してリクエストしているのに毎回同じ値が返ってきてしまいます。

AIRには cacheResponse, useCache といかにも使えそうなプロパティが用意されているのですが、false 設定してもやっぱりキャッシュされます。

header に "no-cache" を追加してもキャッシュされてしまいます。

var req:URLRequest = new URLRequest('examle.com');
var header:URLRequestHeader = new URLRequestHeader("pragma", "no-cache");
var headerCacheCtrl:URLRequestHeader = new URLRequestHeader("cache-control", "no-chache");
var headerExpires:URLRequestHeader = new URLRequestHeader("expires", "Sun, 10 Jan 1990 01:01:01 GMT");
 
req.requestHeaders.push(header);
req.requestHeaders.push(headerCacheCtrl);
req.requestHeaders.push(headerExpires);

リクエストにタイムスタンプも追加してるのになぜなぜ?と右脳と左脳をフル回転させました。

タイムスタンプの設定をしくじっておりました。

【キャッシュされてしまうタイムスタンプ設定】

var req:URLRequest = new URLRequest('examle.com');
var variables:URLVariables = new URLVariables();
variables.timestamp = new Date().getTime().toString();
 
req.data = variables;

【キャッシュされないタイムスタンプ設定】

var req:URLRequest = new URLRequest('examle.com' + '?' + new Date().getTime().toString());

解決すればなんてことない勘違い。
URLそのものにタイムスタンプを付加しないといけませんよねぇ。

以前はどうしてたんだろうとコードをあさってみたらちゃ〜んとURLにくっ付けてました。
なんで今回だけ勘違いしてたんかんなぁ。

ちなみにURLにタイムスタンプをつけたら cacheResponse, useCache "no-cache" もいりません。

いましめのためにブログっておきます。

2011.02.19
02:06
author: taikiken
1件のコメント

Flash Builder 4, Java heap space エラー

Flash Builder 4を使っていたら “Java heap space” とエラーがでてプレビューもできなくなってしまいました。
Javaメモリーエラーのようです。
アプリ、マシンの再起動を試みましたがエラーは解消できません。

Technophi : Flash Builder 4 – Java Heap Space Issues

こちらのサイトに解決法が投稿されていました。

Flash Builder sdk フォルダ内の設定ファイルにメモリサイズの設定があるようです。

1. Open the following files:
a) /install_dir/sdks/3.5.0/bin/jvm.config
b) /install_dir/sdks/4.0.0/bin/jvm.config

2. Locate the following line found under # Arguments to VM:
java.args=-Xmx384m -Dsun.io.useCanonCaches=false

3. Increase the memory size to a larger value like the following example:
java.args=-Xmx512m -Dsun.io.useCanonCaches=false

私の環境ではsdkに4.1, 4.5系が2種入っているのでそちらの設定も書き直しました。

sdk/bin フォルダ内 jvm.config をエディタで開く。
java.args=-Xmx384m -Dsun.io.useCanonCaches=false を探し384を大きな数字に変更。

アプリを起動。
これだけではエラーは消えなかったのですが、いくつかファイルを保存しているうちにエラーは消えました。
なんだったのかなぁ〜。

2011.02.12
08:47
author: taikiken
0件のコメント

ActionScript 3, Event処理を簡単に – Signals, カスタムイベント その2

Signalsを実践投入すると後には戻れないほど便利なことが分かってきました。
もうaddEventListener, removeEventListenerを書きたくなんかありません。

前回はなんだか良くわからなかった Signal の使い方がぼんやり見えてきました。

org.osflash.signals.Signalはカスタムなイベントを作るためのクラスのようです。
API Documentによればコンストラクタの引数はオプションです。

Signal(... valueClasses)
Creates a Signal instance to dispatch value objects.

これが何をするのかが分からなかったのですが、リスナーの引数の型を指定するようです。

Usage

import org.osflash.signals.Signal;
 
var signal:Signal = new Signal(String);
signal.add(onSignal);
 
function onSignal (s:String):void {
	trace(s); 
}
 
signal.dispatch("ワン");

リスナーに対してイベントインスタンス以外の情報(引数)を渡すのはちょっとややこしいのですがSignalsを使えば簡単に実現できます。

2011.02.11
12:20
author: taikiken
0件のコメント

Flash Builder ショートカット覚書

Flash Builder のショートカット、たまに忘れて右往左往する俺のためメモ。

【検索】
アクティブなページを検索
command + f

検索ウインドウを閉じて
次を検索
command + k

前を検索
command + shift + k

【全文検索】
command + shift + f
*これかなり便利。プロジェクト内を全検索してくれる
update 2012-05-08
Flash Builder 4.6ではこのショートカットはなくなっている様子。
代わりにWorkspaceを検索する(同じことだけど)ショートカットが追加されている模様。
command + shift + g

【編集】
文字を選択して使います

宣言を開く
fn + F3
*型指定などのクラスファイルへ移動
*関数を設定している場所へ移動
引数でclouser指定している関数ってどんなだったけ?なときに愛用中。

リソースを開く
command + shift + r

名前を変更(リファクタリング)
command + option + r
*クラス名とか適当に決めておいて後で正式名称に変更したりと大活躍

コメント(//) ON / OFF
command + /

コメント(/* */) ON / OFF
command + shift + c

クイックフィックス(import してないクラスや宣言していない関数、変数を作成してくれる)
command + 1

インデントを修正(変更したい行へカーソル移動)
command + i

文字の後ろにカーソルを移動
コードヒント
command + space

単語補完(候補)
control + .

update

Mac だと command + space がスポットライト検索のショートカットに割当てられているので、
環境設定 > Spotlight
でショートカット・キーコンビネーションを変更しています。

おまけ
© : Copyright シンボル
command + option + g

update
import ステートメントのソート
command + shift + O

2011.02.08
11:12
author: taikiken
1件のコメント

フルサイズFlashをブラウザウインドウにフィットさせる覚書

ブラウザウインドウいっぱいに広がるFlashコンテンツを作成するためのオレメモ。

Flashコンテンツを幅・高さ100% / 100% にしブラウザウインドウ内いっぱいいっぱいに表示させるためにすること。

swfobject
幅・高さとも100%に設定

swfobject.embedSWF("example.swf", "swfcontent", "100%", "100%", "10.0.0","expressinstall.swf")

HTML
IE 8のバグ対策:IE 7モード

<head>
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<div id="swfcontent">
このタグをFlash objectタグで置換え
</div>

CSS

html, 
body {
	margin: 0;
	padding: 0;
	width: 100%;
	height: 100%;
	overflow: hidden;
}
#swfcontent {
	outline: none;
	min-height: 600px;
	min-width: 900px;
	margin: 0;
	padding: 0;
	width: 100%;
	height: 100%;
	position: absolute;
}

Firefox対策のためにoutline: none;, position: absolute;
position: absolute;は今は必要無さそうだけど入れても弊害は無さそうなので…

以下は必要に応じて
・ブラウザのスクロールバーを消す:overflow: hidden;
・最小幅・高さを指定min-heigh,min-width:

Actionscript

import flash.display.StageAlign;
import flash.display.StageScaleMode;
 
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

StageScaleMode.NO_SCALEにしたらRESIZEを監視して自力でどうするかのScriptが必要。