Categories: Flex

Flex3でLoaderで読み込んだSWFをMovieClipに変換した際にnullになってしまう

外部SWFファイルを制御したい。
そんな想いからはじまる今回のお話。


外部SWFを読み込むにはSWFLoaderやImageなどの方法がある。
Flex で読み込んだ SWF を制御 [ActionScript3.0]
ここを参考にSWFLoaderを使った方法で試みた。
しかし、
myLoader.content as MovieClip;
の部分でMovieClipへの変換がうまくいっていないらしくtraceしてみるとnullになっている。
MovieClipにしないと制御ができないーーー!!
ちなみに、myLoader.content自体をtraceすると[object AVM1Movie]と表示されている。
今度は、
ロードした外部swfを操作する for actionscript3.0
ここを参考にして、Loader関数を使った方法で試みてみる。
しかし、やはり
var mc:MovieClip = loader.content as MovieClip;
の部分でnullになる。
そこでAVM1MovieをMovieClipに変換する方法を探すのにすごい時間がかかったので備忘録で書き残しておく。
解決策はこれ
AVM1Movie Controller in Flex
まず以下のソースをForcibleLoader.asとして保存しておく。
引用URL:ForcibleLoader.as

package
{
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.events.Event;
import flash.utils.ByteArray;
import flash.utils.Endian;
import flash.errors.EOFError;
public class ForcibleLoader
{
public function ForcibleLoader(loader:Loader)
{
this.loader = loader;
_stream = new URLStream();
_stream.addEventListener(Event.COMPLETE, completeHandler);
_stream.addEventListener(IOErrorEvent.IO_ERROR,
ioErrorHandler);
_stream.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
securityErrorHandler);
}
private var _loader:Loader;
public var _stream:URLStream;
public function get loader():Loader
{
return _loader;
}
public function set loader(value:Loader):void
{
_loader = value;
}
public function load(request:URLRequest):void
{
_stream.load(request);
}
private function completeHandler(event:Event):void
{
var inputBytes:ByteArray = new ByteArray();
_stream.readBytes(inputBytes);
_stream.close();
inputBytes.endian = Endian.LITTLE_ENDIAN;
if (isCompressed(inputBytes)) {
uncompress(inputBytes);
}
var version:uint = uint(inputBytes[3]);
if (version >> 3;
result += (5 + rectNBits * 4) / 8; // stage(rect)
result += 2;
result += 1; // frameRate(byte)
result += 2; // totalFrames(16bit-uint)
return result;
}
private function findFileAttributesPosition(offset:uint, bytes:ByteArray):uint
{
bytes.position = offset;
try {
for (;;) {
var byte:uint = bytes.readShort();
var tag:uint = byte >>> 6;
if (tag == 69) {
return bytes.position - 2;
}
var length:uint = byte & 0x3f;
if (length == 0x3f) {
length = bytes.readInt();
}
bytes.position += length;
}
}
catch (e:EOFError) {
}
return NaN;
}
private function flagSWF9Bit(bytes:ByteArray):void
{
var pos:uint = findFileAttributesPosition(getBodyPosition(bytes), bytes);
if (!isNaN(pos)) {
bytes[pos + 2] |= 0x08;
}
}
private function insertFileAttributesTag(bytes:ByteArray):void
{
var pos:uint = getBodyPosition(bytes);
var afterBytes:ByteArray = new ByteArray();
afterBytes.writeBytes(bytes, pos);
bytes.length = pos;
bytes.position = pos;
bytes.writeByte(0x44);
bytes.writeByte(0x11);
bytes.writeByte(0x08);
bytes.writeByte(0x00);
bytes.writeByte(0x00);
bytes.writeByte(0x00);
bytes.writeBytes(afterBytes);
afterBytes.length = 0;
}
private function updateVersion(bytes:ByteArray, version:uint):void
{
bytes[3] = version;
}
private function ioErrorHandler(event:IOErrorEvent):void
{
loader.contentLoaderInfo.dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
}
private function securityErrorHandler(event:SecurityErrorEvent):void
{
loader.contentLoaderInfo.dispatchEvent(new SecurityErrorEvent( SecurityErrorEvent.SECURITY_ERROR));
}
}
}

使い方としては、まずこのASファイルをimportします。
最初使い方を勘違いしていた私は

import ForcibleLoader;
private var loader:Loader;
private var mc:MovieClip = new MovieClip();
private var swfURL:String = "test.swf"; //ここにswfファイルのアドレスを書いとく
private var libMC:MovieClip = new MovieClip();
private function init(): void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, swfComplete);
var fLoader:ForcibleLoader = new ForcibleLoader(loader);
fLoader.load(new URLRequest(swfURL));
myLoader.addChild(loader); //ここでSWFLoaderに読み込んだSWFファイルを表示させる
}
private function swfComplete(event:Event):void{
this.mc = event.currentTarget.content as MovieClip;
trace( this.mc );
}

やってみたらみごと[object MovieClip]とでてくれましたー!
これでようやく読み込んだSWFファイルの制御をすることができます。
Adobe Flex Builder Standard 3.0 日本語版 Windows/Macintosh版

mogmet

View Comments

Share
Published by
mogmet