Chromeless 플레이어용 ActionScript 3.0 래퍼

이 도움말은 외부 개발자가 작성하고 제출했습니다. YouTube API 및 도구팀은 매튜 리치몬드님께 시간을 내어 전문적인 의견을 제공해 주셔서 감사드립니다.


매튜 리치몬드, The Chopping Block, Inc.
2008년 10월

소개

이 도움말에서는 Chrome이 없는 YouTube 플레이어를 위한 안정적인 ActionScript 3.0 래퍼를 소개하고 간략히 설명합니다. 래퍼는 ActionScript의 ExternalInterface 클래스와 YouTube의 JavaScript API를 활용합니다.

디자이너/개발자는 Google의 YouTube 플레이어 도구와 Chromeless 플레이어를 사용해 YouTube 기능을 온라인 프로젝트에 빠르고 쉽게 통합할 수 있습니다. 이 접근 방식은 동영상 호스팅이 허용되지 않는 고정 예산의 소규모 프로젝트뿐만 아니라 YouYube 잠재고객으로부터 벗어나지 않고 맞춤형 최종 사용자 경험을 원하는 고객을 위한 대규모 프로젝트에 적합합니다.

ActionScript 3.0 래퍼 스크린샷
그림 1: ActionScript 3.0 래퍼 스크린샷

YouTube의 Flash API 및 내장 플레이어는 액션스크립트 2.0으로 작성되었으며, 액션스크립트 2.0에서도 잘 작동합니다. 하지만, 프로젝트가 액션스크립트 3.0인 경우에는 원활한 통합이 좀 더 복잡해집니다. ActionScript 2.0 플레이어를 ActionScript 3.0 swf에 쉽게 로드할 수 있지만, 로드된 플레이어에 기능 호출을 직접 전달하거나 통신할 수는 없습니다. YouTube 서버에서 제공되는 swf 파일이 동영상을 자체적으로 로드하기 때문에 더욱 복잡해집니다. 래퍼는 이 사실을 완전히 인식하고 그에 따라 반응해야 합니다. 다행히 ActionScript 언어에는 중첩되었지만 연결 해제된 이러한 부분을 다시 연결하는 두 가지 실용적인 해결 방법, LocalConnection 클래스 또는 ExternalInterface 클래스가 포함되어 있습니다. 이 데모에서는 후자에 중점을 둘 것입니다. ExternalInterface는 문서화된 JavaScript API와 원활하게 작동하므로 XHTML 페이지 내의 다른 모든 항목과 잘 작동하기 때문입니다.

중요 리소스

시작하기 전에 사용할 수 있는 관련 리소스 및 파일 목록을 확인하세요. 이 도움말에서 다루는 많은 주제에 관한 자세한 내용은 아래 링크를 참고하세요.

심층 분석

래퍼 데모 개요

액션스크립트 클래스 파일
그림 3: JavaScript 파일
액션스크립트 클래스 파일
그림 2: 액션스크립트 클래스 파일

ActionScript 3.0 래퍼는 기본적으로 두 개의 상호 연결된 부분, 즉 src/choppingblock/video/ (그림 2)에 있는 ActionScript 3.0 클래스 파일과 deploy/_assets/js/ (그림 3)에 있는 'youTubeLoader.js' JavaScript 파일로 구성됩니다. Flash/Flex 소스 파일은 YouTubeLoader ActionScript 클래스의 인스턴스를 만듭니다. XHTML 페이지는 플래시 파일을 삽입하고 youTubeLoader JavaScript 파일 내의 함수에 등록합니다. 여기에서 YouTubeLoader가 플래시 파일 내에서 실행하는 모든 작업은 JavaScript 함수를 통해 제어된다는 점을 이해하는 것이 중요합니다.

Flash 내의 모든 기능은 JavaScript API를 통해 제어되므로 Flash의 'Test Movie' 플레이어 내에서 YouTube 콘텐츠를 로드할 수 없습니다. XHTML 페이지에 삽입되고 youTubeLoader JavaScript 함수에 올바르게 연결된 경우에만 작동합니다.

참고: 이러한 호출을 테스트하려면 웹서버에서 파일을 실행하거나 Flash Player의 보안 설정을 수정해야 합니다. Flash Player는 로컬 파일과 인터넷 간의 호출을 제한하기 때문입니다.

YouTubeLoader 객체 만들기

Flash/Flex 프로젝트에서 YouTubeLoader 객체의 인스턴스를 만들려면 먼저 필요한 파일의 패키지 (폴더)가 프로젝트와 동일한 디렉터리에 있거나 (그림 2 참고) 프로젝트 클래스 경로로 정의되어 있는지 확인해야 합니다. 그러면 패키지 파일을 가져올 수 있습니다.

import choppingblock.video.*;

이렇게 하면 액션스크립트 파일이 'YouTubeLoader.as' 및 'YouTubeLoaderEvent.as' 클래스에 액세스할 수 있습니다. 이제 YouTubeLoader 클래스와 필요한 이벤트 리스너의 인스턴스를 만들 수 있습니다.

import choppingblock.video.*;

public class YouTubeDemo extends Sprite {

  private var _youTubeLoader:YouTubeLoader;	
  
  // ------------------------------------
  // CONSTRUCTOR
  // ------------------------------------
  
  public function YouTubeDemo () {
    
    // create YouTubeLoader object
    _youTubeLoader = new YouTubeLoader();
    
    // add event listener to call youTubePlayerLoadedHandler method on load
    _youTubeLoader.addEventListener(YouTubeLoaderEvent.LOADED, youTubePlayerLoadedHandler);
    
    // create the actual loader 
    _youTubeLoader.create();
    
    // add object to the display stack
    addChild(_youTubeLoader);
  };
  
  // ------------------------------------
  // EVENT METHODS
  // ------------------------------------
  
  /**
  Called via player loaded event, lets you know you are all clear to send player commands.
  */
  private function youTubePlayerLoadedHandler (event:YouTubeLoaderEvent):void{
    //trace("YouTubeDemo: youTubePlayerLoadedHandler");
    
    // you are now clear to start making calls to the YouTubeLoader object
  };
};

이제 JavaScript 파일이 올바르게 연결되어 있으면 youTubePlayerLoadedHandler가 성공적으로 호출되고 요청을 시작할 준비가 됩니다.

swf 삽입 및 youTubeLoader JavaScript 연결

swf 파일이 XHTML 파일에 삽입되고 youTubeLoader JavaScript에 연결될 때까지 YouTube에서 콘텐츠를 로드할 수 없습니다. JavaScript API를 사용하여 액세스할 플레이어는 SWFObject를 사용하여 삽입하는 것이 좋습니다. 이렇게 하면 최종 사용자의 Flash Player 버전 (JavaScript API를 사용하려면 Flash Player 8 이상이 필요함)을 확인할 수 있으며 Internet Explorer를 사용하여 플레이어를 볼 때 '클릭하여 컨트롤을 활성화하세요' 상자가 사라집니다.

XHTML 파일의 <head> 부분에서 swfobject 및 youTubeLoader 파일을 연결합니다.

<script type="text/javascript" src="_assets/js/swfobject.js"></script>
<script type="text/javascript" src="_assets/js/youTubeLoader.js"></script>

SWFObject를 사용하여 JavaScript API가 사용 설정된 ActionScript 3.0 swf를 삽입한 다음 swf 참조를 youTubeLoader JavaScript API에 전달하는 예는 아래를 참고하세요.

<script type="text/javascript">

  var flashvars = {};
  var params = {
    menu: "false",
    allowScriptAccess: "always",
    scale: "noscale"
  };
  var attributes = {
    id: "youtubewrapper"
  };

  swfobject.embedSWF("YouTubeIntegrationDemo.swf", "flashcontent", "960", "500", "9.0.0", "_assets/swf/expressInstall.swf", flashvars, params, attributes);
  
  //init the youTubeLoader JavaScript methods
  SWFID = "youtubewrapper"
    
</script>

Chromeless 플레이어가 XHTML 페이지와 다른 도메인에 호스팅되므로 플레이어 SWF가 포함된 HTML 페이지에서 함수를 호출할 수 있도록 하려면 코드의 allowScriptAccess 매개변수가 필요합니다.

전달하는 유일한 속성은 삽입 객체의 ID입니다. 이 경우 youtubewrapper입니다. 이 ID는 youTubeLoader.js 파일에서 getElementById()를 사용하여 플레이어에 대한 참조를 가져오기 위해 사용합니다.

swfobject.embedSWF는 YouTube에서 플레이어를 로드하여 페이지에 삽입합니다.

swfobject.embedSWF(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj)

  • swfUrlStr - SWF의 URL입니다. JavaScript API 호출을 사용 설정하기 위해 일반 YouTube SWF URL에 enablejsapiplayerapiid 매개변수를 추가했습니다.
  • replaceElemIdStr - 삽입 콘텐츠로 대체할 HTML DIV ID입니다. 위의 예에서는 ytapiplayer입니다.
  • widthStr - 플레이어의 너비입니다.
  • heightStr - 플레이어의 높이입니다.
  • swfVersionStr - 사용자가 콘텐츠를 보려면 필요한 최소 버전입니다. 이 경우 버전 8 이상이 필요합니다. 사용자가 8 이상이 아니면 HTML DIV에 기본 텍스트 줄이 표시됩니다.
  • xiSwfUrlStr - (선택사항) 빠른 설치 SWF의 URL을 지정합니다. 이 예에서는 사용되지 않습니다.
  • flashVarsObj - (선택사항) 이름:값 쌍으로 FlashVars를 지정합니다. 이 예에서는 사용되지 않습니다.
  • parObj - (선택사항) 삽입 객체의 매개변수입니다. 이 경우에는 allowScriptAccess를 설정했습니다.
  • AttObj - (선택사항) 삽입 객체의 속성입니다. 이 경우 ID를 myytplayer로 설정했습니다.

자세한 설명은 SWFObject 문서를 참조하세요.

SWFID ≡ 는 JavaScript API에서 사용할 삽입 객체의 ID 참조를 저장합니다. swf에 제공한 삽입 객체의 ID와 동일한 ID를 사용해야 합니다.

SWFID ≡ "youtubewrapper"

이제 프로젝트를 테스트할 수 있습니다. YouTubeLoader 객체가 Chromeless 플레이어를 로드하고 YouTubeLoaderEvent.LOADED 이벤트 핸들러가 성공적으로 호출됩니다. 이제 동영상을 요청하고 YouTubeLoader 객체와 상호작용할 준비가 되었습니다.

플레이어와 상호작용

Chromeless 플레이어용 ActionScript 3.0 래퍼를 만드는 이 접근 방식은 ActionScript의 ExternalInterface 클래스를 활용하므로 이제 YouTube JavaScript Player API 내의 모든 작업을 사용하여 로드된 플레이어를 제어할 수 있습니다. deploy/_assets/js/에 있는 'youTubeLoader.js' 자바스크립트 파일(그림 3)을 보면 대부분의 사용 가능한 함수가 포함되어 있음을 알 수 있습니다. 각 작업 함수는 먼저 checkObj 함수를 테스트하여 SWFID 변수가 실행 전에 올바르게 설정되었는지 확인합니다.

//------------------------------------
// UTILITY METHODS
//------------------------------------

function checkObj () {
  // alert("youTubeLoader.js : checkObj");
  if (SWFID) {
    createObj();
    return true;
  } else{
    alert("YouTubeLoader: In order to call methods within a swf, you must first set the variable \"SWFID\"!");
    return false;
  };
}
  
//------------------------------------
// YOUTUBE METHODS
//------------------------------------

function loadVideoById(id, startSeconds) {
  // alert("youTubeLoader.js : loadVideoById");
  if (checkObj()) {
    obj.loadVideoById(id,startSeconds);
  };
};

function cueNewVideo(id, startSeconds) {
  // alert("youTubeLoader.js : loadVideoById");
  if (checkObj()) {
    obj.cueVideoById(id, startSeconds);
  }
}

function clearVideo() {
  // alert("youTubeLoader.js : clearVideo");
  if (checkObj()) {
    obj.clearVideo();
  }
}

// plus 17 more...

Chromeless 플레이어용 ActionScript 3.0 래퍼의 최종 목표는 ActionScript 3.0 Flash/Flex 프로젝트 내에서 YouTube API와 원활하게 상호작용하는 것이므로 src/choppingblock/video/에 있는 'YouTubeLoader.as' 클래스 파일에 정확히 동일한 공개 메서드를 추가했습니다(그림 2). 즉, Flash/Flex 내에서 YouTubeLoader 객체에 정확히 동일한 작업을 직접 호출할 수 있습니다. 클래스 파일 내부를 살펴보면 다음을 확인할 수 있습니다.

// ------------------------------------
// YOUTUBE METHODS
// ------------------------------------

public function loadVideoById (id:String, startSeconds:Number = 0):void{
  //trace("YouTubeLoader: loadVideoById");
  ExternalInterface.call("loadVideoById", id, startSeconds);
};

public function cueNewVideo (id:String, startSeconds:Number = 0):void{
  //trace("YouTubeLoader: cueNewVideo");
  ExternalInterface.call("cueNewVideo", id, startSeconds);
};

public function clearVideo ():void{
  //trace("YouTubeLoader: clearVideo");
  ExternalInterface.call("clearVideo");
};

// plus 17 more...

ActionScript 메서드는 ExternalInterface 클래스를 사용하여 JavaScript API 내에서 적절한 함수를 호출합니다.

동영상 요청

이제 플레이어 참조를 사용하여 함수를 호출하여 액션스크립트 3.0 파일 내에서 동영상을 요청할 수 있습니다. 예를 들어 사용자가 버튼을 클릭할 때 동영상을 재생하려면 버튼에 MouseEvent.CLICK 이벤트 리스너를 추가하면 됩니다. 다음 행을 추가하면 됩니다.

// assuming your button was called 'myButton'
myButton.addEventListener(MouseEvent.CLICK, youtubeLoadVideoHandler);

요청을 처리할 이벤트 핸들러 메서드를 만듭니다. 다음 행을 추가하면 됩니다.

private function youtubeLoadVideoHandler (event:MouseEvent):void{
  
  // assuming that '_youTubeLoader' is a reference to your YouTubeLoader object
  _youTubeLoader.loadVideoById( "u1zgFlCw8Aw" );
};

Flash/Flex 파일 외부에서 해당 자바스크립트 함수를 직접 호출하여 선택적으로 동영상을 요청할 수 있습니다. 다음 행을 추가하면 됩니다.

 <a href="javascript:loadVideoById('u1zgFlCw8Aw')">Play</a> 

추가 통화 발신

추가 호출은 동영상 요청과 정확히 동일하게 작동합니다. ActionScript 3 내에서 플레이어 참조를 사용하여 메서드를 호출하면 됩니다. 사용 가능한 메서드의 전체 목록은 아래에 제공되어 있습니다.

이벤트 수신하기

플레이어 참조에 이벤트 리스너를 추가하여 이벤트를 구독합니다. 예를 들어 플레이어 상태가 변경될 때 알림을 받으려면 YouTubeLoaderEvent.STATE_CHANGE의 이벤트 리스너를 추가합니다. 다음 행을 추가하면 됩니다.

// assuming that '_youTubeLoader' is a reference to your YouTubeLoader object
_youTubeLoader.addEventListener(YouTubeLoaderEvent.STATE_CHANGE, youTubePlayerStateChangeHandler);

요청을 처리할 이벤트 핸들러 메서드를 만듭니다. 다음 행을 추가하면 됩니다.


private function youTubePlayerStateChangeHandler (event:YouTubeLoaderEvent):void{
  //trace("YouTubeIntegrationDemo: youTubePlayerStateChangeHandler");
  
  _stateField.text = event.state;
};

사용 가능한 작업

YouTubePlayer API 메서드를 호출하려면 먼저 ActionScript 파일 내에 YouTubePlayer 클래스의 인스턴스를 만들고 제어하려는 YouTubePlayer 객체의 참조를 저장해야 합니다. 이를 위해서는 다음을 호출하면 됩니다.

var _youTubeLoader:YouTubeLoader;
_youTubeLoader = new YouTubeLoader();

공개 메서드

player.loadVideoById(id:String, startSeconds:Number = 0):void
지정된 ID를 기반으로 동영상을 로드하고 재생합니다.
player.cueNewVideo(id:String, startSeconds:Number = 0):void
지정된 ID를 기반으로 동영상이 로드되지만 자동으로 재생되지 않습니다.
player.clearVideo():void
현재 큐에 추가된/로드된 동영상을 지웁니다.
player.setSize(w:Number, h:Number):void
YouTubePlayer 인스턴스의 크기를 설정합니다.
player.play():void
현재 신호를 주거나 로드된 동영상을 재생합니다.
player.pause():void
현재 큐에 추가되었거나 로드된 동영상을 일시중지합니다.
player.stop():void
현재 큐에 추가되었거나 로드된 동영상을 중지합니다.
player.seekTo(seconds:Number):void
현재 신호를 주거나 로드된 동영상에서 지정된 시간을 탐색합니다.
player.getPlayerState():String
현재 큐에 추가된/로드된 동영상의 현재 상태를 반환합니다.
player.getBytesLoaded():Number
현재 큐에 추가된/로드된 동영상의 현재 로드된 바이트 값을 반환합니다.
player.getBytesTotal():Number
현재 큐에 추가된/로드된 동영상의 총 바이트 수를 반환합니다.
player.getCurrentTime():Number
현재 큐에 추가된/로드된 동영상의 현재 시간 위치를 반환합니다.
player.getDuration():Number
현재 큐에 추가된/로드된 동영상의 현재 길이를 반환합니다.
player.getStartBytes():Number
현재 큐에 추가되었거나 로드된 동영상의 시작 바이트입니다.
player.setVolume(newVolume:Number):void
현재 큐에 추가된/로드된 동영상의 볼륨을 설정합니다.
player.getVolume():Number
현재 신호를 주거나 로드된 동영상의 현재 볼륨을 반환합니다.
player.mute():void
현재 볼륨을 저장하고 현재 큐에 추가된/로드된 동영상의 볼륨을 0으로 변경합니다.
player.unmute():void
현재 큐에 추가된/로드된 동영상의 볼륨을 음소거된 경우 마지막으로 저장된 값으로 반환합니다.
player.getEmbedCode():String
현재 큐에 추가된/로드된 동영상의 현재 YouTube 삽입 코드를 반환합니다.
player.getVideoUrl():String
현재 큐에 추가되었거나 로드된 동영상의 현재 YouTube 동영상 URL을 반환합니다.

이벤트

YouTubeLoaderEvent.LOADED
Chromeless 플레이어가 성공적으로 로드를 완료하고 작업 호출을 수락할 준비가 되면 실행됩니다.
YouTubeLoaderEvent.STATE_CHANGE
플레이어의 상태가 변경될 때마다 실행됩니다. YouTubeLoader 클래스는 JavaScript API 번호를 관련 문자열 값으로 변환하며, YouTubeLoaderEvent 클래스는 현재 이벤트를 state라는 변수에 저장합니다. 가능한 값은 시작되지 않음, 종료됨, 재생 중, 일시중지됨, 버퍼링, 동영상 신호 있음입니다. SWF가 처음 로드되면 시작되지 않은 이벤트가 브로드캐스트됩니다. 동영상이 큐에 추가되고 재생 준비가 되면 동영상 큐 이벤트가 브로드캐스트됩니다.
YouTubeLoaderEvent.IO_ERROR
플레이어에서 오류가 발생하면 실행됩니다. 가능한 오류 코드는 두 가지입니다. 요청된 동영상을 찾을 수 없는 경우 100이 브로드캐스트됩니다. 동영상이 어떤 이유로든 삭제되었거나 비공개로 표시된 경우 이 문제가 발생합니다. 요청된 동영상이 삽입된 플레이어에서 재생되지 않을 때 101이 브로드캐스트됩니다.

데모 관련 메모

데모를 위해 XHTML 양식 필드, 버튼, 디스플레이 UI를 삽입된 ActionScript 3 래퍼 아래에 포함하고자 했습니다. swf 파일과 XHTML을 동시에 업데이트하려면 'deploy/_assets/js/'에 있는 'youTubeLoader.js' JavaScript 파일에 두 줄의 코드를 포함해야 했습니다(그림 3). 이 파일을 프로젝트에 통합할 때 다음 두 줄[69, 79] 을 삭제해야 합니다.

//------------------------------------
// SPECIAL YOUTUBE EVENT METHODS
//------------------------------------

function onYouTubePlayerReady(playerId) {

  if (checkObj()) {	
    obj.addEventListener("onStateChange", "onytplayerStateChange");
  };

  // PLEASE NOTE: For the purpose of this demo:
  // This calls a secondary method located in the index.html file allowing the html display to update.
  // You will most likely not need this, it's gross, remove this when you implement this code.
  secondaryOnYouTubePlayerReady(playerId);
}

function onytplayerStateChange(newState) {
    //alert("Player's new state: " + newState);
  obj.playerStateUpdateHandler(newState);

  // PLEASE NOTE: For the purpose of this demo:
  // This calls a secondary method located in the index.html file allowing the html display to update.
  // You will most likely not need this, it's gross, remove this when you implement this code.
  secondaryOnytplayerStateChange(newState)
}

데모 파일과 포함된 ActionScript 라이브러리는 무료 소프트웨어입니다. GNU Lesser General Public License의 조건에 따라 재배포 및 수정할 수 있습니다. 이 파일은 유용성을 기하기 위해 배포되지만 어떠한 보증도 하지 않습니다.

결론

이 도움말, 데모, 소스 파일을 통해 YouTube API와 삽입된 플레이어를 자체 프로젝트용으로 개발한 래퍼 라이브러리를 사용하여 ActionScript 3 환경에 통합하는 비교적 간단하고 안정적인 솔루션을 간단히 살펴볼 수 있습니다. 코드의 대부분에 주석을 달았으므로 라이브러리를 살펴보고 용도를 변경하는 것이 매우 간단합니다. 물론 제한사항이 있으며 항상 개선, 리팩터링, 향상의 여지가 있습니다. 이와 관련하여 의견이 있으시면 언제든지 문의해 주세요.

저자 약력


매튜 리치먼드

매튜 리치몬드는 14년간의 양방향 디자인, 개발, 아키텍처 경험을 보유하고 있습니다. 스튜디오에 있지 않을 때는 School of Visual Arts에서 디지털 일러스트레이션/사진 기술과 고급 ActionScript를 가르치고 있습니다. 매튜는 choppingblock.com의 창립 파트너 겸 디자이너입니다.