노무현 대통령 배너

로드한 파일이 AS2.0인지 AS3.0인지 런타임에 확인하는 방법

by on 8.22, 2010, under AS3.0 API

이런 경우를 가정해 봅시다. 여러분은 이번에 새로운 이 러닝(e-learning) 프로젝트에 개발자로 참여하게 되었습니다. 이 러닝이라 별로 하고 싶진 않았지만 영업 파트에서 다른 프로젝트와 연계된 작업이라고 하는통에 떠 안을 수 밖에 없었습니다. 그러나 여러분의 회사는 이 러닝 전문회사가 아닌데다가 실제로 플래시를 다루는 직원은 여러분 회사에 여러분 외에는 없습니다. (이런 경우 은근히 많을거라 생각합니다.)

그래서 결국 플래시로 프레임웍, 즉, UI는 여러분이 제작하게 되었고, (이 러닝 업계에서는 프로토타입을 만든다는 표현을 하죠) 차시별 작업은 경험이 많다고 하는 외주 팀에게 하청을 주기로 하였습니다. 여러분은 이제 제법 클래스를 이용해 프로젝트를 수행할 수 있게 되었고, AS2.0 으로 프로젝트를 만들지 않으므로 AS3.0 으로 이 러닝 프로젝트를 수행하려고 합니다. 흔하디 흔한 이 러닝 프로젝트지만 여러분은 좀 다르게 만들고 싶어하죠.

그런데 여기서 문제가 발생합니다.

차시개발을 하는 팀이 AS3.0을 모른다네요. 그렇죠. AS3.0을 다룰 수 있는 차시개발자들을 만나는 일은 두 발로 서는 고양이를 만나는 일과 비슷한 확률일 겁니다. 그렇다면 차시개발은 AS2.0 으로 작업하고, 프로토타입과 UI 는 AS3.0 으로 갑니다. 인트로 무비 같은것을 차시개발자들이 해주는 경우는 별로 없으므로 인트로 무비도 여러분이 AS3.0 으로 제작합니다.

결국 AS2.0과 3.0 파일을 동시에 보여줘야 하는 상황이 되었습니다. 여기까지도 문제는 없죠. AS3.0 에서 Loader 객체를 이용하면 AS2.0 으로 컴파일된 swf 파일도 로드가 가능하다는 것을 잘 알고 있으니까요.[01]

그러나 정말 어려운 문제는 실제 코딩을 하다가 드러나게 됩니다. 애니메이션의 재생, 정지 등을 구현하기 유튜브의 비디오 플레이어와 비슷한 형태의 swf 플레이어를 만들어야 하고, 탐색(seeking) 기능을 넣기 위해서 전체 타임라인의 프레임 갯수를 알아야할 필요가 생겼습니다.

이런 형태의 seeking controller 말이죠!!

여러분이 만들기로 했던 인트로 swf 파일은, UI를 담당하는 swf 파일과 동일한 AS3.0 으로 컴파일되어있기 때문에 아래와 같이 로드 완료 이벤트를 받은 후 이벤트 target.content 를 MovieClip 으로 캐스팅 해서 간단히 사용할 수가 있습니다.

0
1
2
3
4
5
6
7
var objLoader:MovieClip;
loader.contentLoaderInfo.addEventListener( Event.INIT, initHandler );
function initHandler( $e:Event ):void
{
	objLoader = $e.target.content as MovieClip;
	// 이 시점 이후로 objLoader 객체는 무비클립과 동일하게 사용할 수 있음
	trace( objLoader.totalFrames, objLoader.stage.frameRate ); // 이렇게 totalFrames, frameRate 등의 속성을 직접 참조가능
}

그러나 차시개발 외주팀에서 보내준 AS2.0 버전의 swf 파일은 이게 안됩니다. 애초에 AS2.0 에서는 속성명 부터가 다르죠.[02]

그래서 어쩔 수 없이 차시개발팀에게 약간의 코드를 넘겨주고 그쪽에서 만드는 모든 AS2.0 파일의 1프레임에 넣도록 요청했습니다. 로드 완료 후 첫 프레임에 진입할때 LocalConnection을 이용해 프레임웍(AS3.0 으로 만들어진 로더)에게 _totalframes 따위의 정보를 넘겨주는거죠. LocalConnection 은 생각보다 성능이 괜찮았습니다. 채널명 중복만 주의하면 거의 에러 없이 정확히 동작합니다. 그렇다면 로드 완료 이벤트 후에 AS2.0 과 AS3.0 의 경우를 분기해서 각각 처리하면 될 것 같습니다.

그런데 산넘어 산이네요. 로드한 파일이 AS2.0인지 AS3.0인지 대체 어떻게 알죠?

* * * * *

상황이 상당히 구체적으로 들어갔지만, 플래시 개발자들이라면 한번쯤 만나게 되는 상황 입니다. 제 경험담이냐고요? 가장 윗 부분에서 영업팀 때문에 프로젝트를 떠안은건 아니었지만, 코딩 상황은 제 경험담 그대로 입니다. 이 이야기, 꽤 오래전부터 “반드시 포스팅 해야지” 하고 마음먹고 있었습니다. ^^

Loader 객체로 가져온 swf 파일의 액션스크립트의 버전을 확인하려면, 아래와 같이 할 수 있습니다.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// import 는 생략
 
var _url:String = "file.swf"; // 로드당하는 swf 파일
var _loader:Loader = new Loader();
_loader.contentLoaderInfo.addEventListener( Event.INIT, initHandler );
_loader.load( new URLRequest( _url ) );
 
function initHandler( $e:Event ):void
{
	if( isAVM1Movie( $e.target.content ) )
	{
		// AS2.0 으로 처리
	}
	else
	{
		// AS3.0 으로 처리
	}
}
 
//로드된 파일이 ActionScript 2.0 인지 확인
function isAVM1Movie( $swf:Object ):Boolean
{
	return ( $swf is AVM1Movie ) ? true : false;
}

이런식으로 간단하게 is 연산자를 사용하여 로드한 swf 의 액션스크립트 버전을 확인할 수 있습니다.

그리고 아래와 같이 flash.utils 패키지에 있는 getQualifiedClassName() 메서드로 정규화된 클래스 이름을 반환 받아 == 항등 연산자로 비교해 볼 수도 있습니다.

0
1
2
3
4
 // 이 코드도 마찬가지로 동작합니다. 어느쪽을 사용해도 무방.
function isAVM1Movie( $swf:Object ):Boolean
{
	return ( getQualifiedClassName( $swf ) == "flash.display::AVM1Movie" ) ? true : false;
}
이 글을 복사해서 퍼가시는건 허용하지 않습니다. 글의 주소를 다른곳에 알려주시는 것은 환영합니다.
  1. 그와는 반대로 AS2.0 에서는 AS3.0 으로 컴파일된 swf 파일을 loadMovie() 하지 못한다는것은 다 알고 계실겁니다. []
  2. AS2.0 의 속성명에 대부분 붙어있던 _ 언더바(언더스코어)가 AS3.0 에서는 모두 없어졌잖아요. 게다가 AS2.0 의 _totlaframes와 AS3.0의 totalFrames는 가운데 F의 대소문자가 다릅니다. 이런식으로 미묘하게 조금씩 다르죠. []

관련된 글

:, , , , , ,

8 Comments for this entry

  • vulcanNo Gravatar

    아직 겪어보진 않았지만 언젠간 꼭 필요한 내용일거 같네요~
    좋은글 감사합니다.^^

  • 이민철No Gravatar

    저도 겪었던 상황이네요!
    저는 첫번째 방법인 is로 해결하였습니다!

  • 쫑쫑쫑No Gravatar

    loaderInfo 에 actionScriptVersion 로도 판별가능해요 +_+ ~

  • 세계의끝No Gravatar

    좋아~ LoaderInfo.actionScriptVersion 도 추가
    이녀석은 버전을 uint 로 반환하니까 아래와 같이 switch .. case 로 하는게 좋겠다.

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    var _url:String = "as3.swf"; // 로드당하는 swf 파일
    var _loader:Loader = new Loader();
    _loader.contentLoaderInfo.addEventListener( Event.INIT, initHandler );
    _loader.load( new URLRequest( _url ) );
     
    function initHandler( $e:Event ):void
    {
    	switch ( getActionScriptVersion( $e.target.content.loaderInfo ) )
    	{
    		case 2:
    			trace( "AS2.0 으로 처리" );
    			break;
    		case 3:
    			trace( "AS3.0 으로 처리" );
    			break;
    		default:
    			trace( "예외 처리" );
    	}
    }
     
    function getActionScriptVersion( $loaderInfo:LoaderInfo ):uint
    {
    	return $loaderInfo.actionScriptVersion;
    }
  • 웹군.No Gravatar

    세계의 끝님의 카페에서 남긴 답글에 감탄하여
    블러그에 들어왔습니다. ^___________^
    오…신세계에 온 것 같네요. 멋지심.

    한가지 의문점은..여기 페이지 에러가 나면서 샘플로 보여준신 코드들이 설명글과 뒤엉키는 건..제 브라우저가 버전.6이라 그런가요?

    • 세계의끝No Gravatar

      저는 IE를 거의 사용하지 않는터라 여태 몰랐는데, IETester 에서 테스트를 해 보니 JQuery에서 뭔가 에러가 있군요.
      IE 계열에서 모두 스크립트 에러가 나지만, 그중에서도 IE6만 코드 부분이 망가지네요.
      제보 감사합니다.
      수정은 해 보겠지만, 그래도 IE6은 빨리 탈출하세요. ^^

1 Trackback or Pingback for this entry

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Meta