AS3 YouTube Chromless API

SWEET!, YouTube released an ActionScript 3 API for their Chromeless Player. Previously, we had to rely on wrapper libraries to bridge the gap between the ActionScript 2 chromeless player and our very own AS 3 code, in short…it was painful. Now, its extremely easy to implement your very own YouTube Player. I scripted up a very simple example for you. Well, I should say it’s a bit more involved than the example you will find on the API reference page.

The following is an OOP based implementation. The video controls are all MovieClips and can be easily revised to your liking. The example below does not display the sound control, but its included in the .fla and can be added to the code, in either a slider or bar form.

Get Adobe Flash player

Lets break down the code:

The document class Main.as, is a simple view which builds all the flash components including the instantiation of the YouTube Player and VideoPlayerControls. The class also handles all the events dispatched from the YouTubePlayer and VideoPlayerControls.

Main.as
/****************************
* Manuel Gonzalez           *
* design@stheory.com        *
* www.stheory.com           *
* www.codingcolor.com       *
*****************************/

package {

  import flash.display.MovieClip;
  import flash.display.Sprite;
  import flash.display.Shape;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import fl.controls.TextInput;
  import fl.controls.RadioButton;
  import fl.controls.Button;
  import com.YouTube.*;
  import com.video.*;

  public class Main extends Sprite {
    private var youTubePlayer:YouTubePlayer;
    private var videoPlayerContainer:MovieClip;
    private var videoPlayerControls:VideoPlayerControls;
    private var videoPlayerWidth:Number=320;
    private var videoPlayerHeight:Number=240;
    private var defaultVideoByID:String ="0UjsXo9l6I8";
    private var defaultVideoByURL:String ="http://www.youtube.com/watch?v=0UjsXo9l6I8";
    private var b1:Button;
    private var ti1:TextInput;
    private var ti2:TextInput;
    private var rb1:RadioButton;
    private var rb2:RadioButton;


    public function Main() {
      createVideoBkg();
      setupInputFields();
      createRadioButton();
      setupLoadButton();
      videoPlayerContainer = new MovieClip();
      videoPlayerContainer.x = 40;
      videoPlayerContainer.y = 25;
      addChild(videoPlayerContainer);
      createYouTubePlayer();
      createVideoPlayerControls();
    }
    /*
    Method: destroy
    Parameters:
    Returns:
    */

    private function destroy():void
    {
      videoPlayerControls.destroy();
      youTubePlayer.destroy();
      removeChild(videoPlayerContainer);
      removeChild(videoPlayerControls);
    }
    /*
    Method: createVideoBkg
    Parameters:
    Returns:
    */

    private function createVideoBkg():void {
      var bkg = new Sprite();
      bkg.x = 40;
      bkg.y = 25;
      createRectangle(bkg,0x000000,videoPlayerWidth,videoPlayerHeight);
      addChild(bkg);
    }
    /*
    Method: createVideoPlayerControls
    Parameters:
    Returns:
    */

    private function createVideoPlayerControls():void {
      videoPlayerControls = new VideoPlayerControls();
      videoPlayerControls.visible=false;
      videoPlayerControls.videoWidth = videoPlayerWidth;
      videoPlayerControls.videoHeight = videoPlayerHeight;
      videoPlayerControls.addEventListener(VideoPlayerControls.ON_PLAYBACK_STATE_CHANGE,playerControlsOnChange);
      videoPlayerControls.addEventListener(VideoPlayerControls.ON_SOUND_CHANGE,playerControlsSoundOnChange);
      videoPlayerControls.x = videoPlayerContainer.x;
      videoPlayerControls.y = videoPlayerContainer.y + (videoPlayerHeight + 8);
      videoPlayerControls.init();
      addChild(videoPlayerControls);

    }
    /*
    Method: createYouTubePlayer
    Parameters:
    Returns:
    */

    private function createYouTubePlayer():void {
      youTubePlayer = new YouTubePlayer();
      youTubePlayer.addEventListener(YouTubeEvent.ON_READY, playerReady);
      youTubePlayer.addEventListener(YouTubeEvent.ON_CHANGE, onPlayerStateChange);
      youTubePlayer.createPlayer(videoPlayerContainer);
    }
    /*
    Method:playerControlsOnChange
    Parameters:
    event:VideoControlsEvent
    Returns:
    */

    private function playerControlsOnChange(event:VideoControlsEvent):void {

      var buttonState:String = event.data.state;
      switch (buttonState) {
        case "play" :
          youTubePlayer.playVideo();
          break;
        case "pause" :
          youTubePlayer.pauseVideo();
          break;
        case "seek" :
          youTubePlayer.seekTo(event.data.val,true);
          break;
      }
    }
    /*
    Method:playerControlsSoundOnChange
    Parameters:
    event:VideoControlsEvent
    Returns:
    */

    private function playerControlsSoundOnChange(event:VideoControlsEvent):void {

      var buttonState:String = event.data.state;
      switch (buttonState) {
        case "mute" :
          youTubePlayer.mute();
          break;
        case "unmute" :
          youTubePlayer.unMute();
          break;
        case "adjust_volume" :
          youTubePlayer.setVolume(event.data.val);
          removeEventListener(Event.ENTER_FRAME,trackProgress);
          break;
      }
    }
    /*
    Method: playerReady
    Parameters:
    event:YouTubeEvent
    Returns:
    */

    private function playerReady(event:YouTubeEvent):void {
      youTubePlayer.setSize(videoPlayerWidth,videoPlayerHeight);
      youTubePlayer.cueVideoById(defaultVideoByID);
    }
    /*
    Method: onPlayerStateChange
    Parameters:
    event:Event
    Returns:
    */

    private function onPlayerStateChange(event:Event):void {
      var _state = event.data;
      switch (_state) {
        case -1 :
          //trace("unstarted");
          break;
        case 0 :
          //trace("ended");
          videoPlayerControls.setPlayPauseControls(youTubePlayer.PlayerState);
          removeEventListener(Event.ENTER_FRAME,trackProgress);
          break;
        case 1 :
          //trace("playing" + youTubePlayer.volume);
          youTubePlayer.setVolume(20);
          videoPlayerControls.setPlayPauseControls(youTubePlayer.PlayerState);
          videoPlayerControls.setMuteControl(youTubePlayer.isMuted());
          videoPlayerControls.setSeekDuration(youTubePlayer.duration);
          addEventListener(Event.ENTER_FRAME,trackProgress);
          break;
        case 2 :
          //trace("paused");
          break;
        case 3 :
          //trace("buffering");

          break;
        case 5 :
          //trace("video cued");
          videoPlayerControls.visible=true;
          break;
      }
    }
    /*
    Method:trackProgress
    Parameters:
    event:Event
    Returns:
    */

    private function trackProgress(event:Event):void {
      var _bytesLoaded = youTubePlayer.VideoBytesLoaded;
      var _bytesTotal = youTubePlayer.VideoBytesTotal;

      videoPlayerControls.setLoadingProgress({bytes:_bytesLoaded,total:_bytesTotal});
      videoPlayerControls.setSeekCurrentTime(youTubePlayer.CurrentTime);

    }
    /*
    Method: setupLoadButton
    Parameters:
    Returns:
    */

    private function setupLoadButton():void {
      b1 = new Button();
      b1.x = 25;
      b1.y = 445;
      b1.label = "Load Video";
      b1.addEventListener(MouseEvent.CLICK, loadVideo);
      addChild(b1);

    }
    /*
    Method:loadVideo
    Parameters:
    event:MouseEvent
    Returns:
    */

    private function loadVideo(event:MouseEvent):void {
      if (rb1.selected) {
        youTubePlayer.loadVideoById(defaultVideoByID);
      } else if (rb2.selected) {

        //youTubePlayer.loadVideoByUrl(defaultVideoByURL);Google has not implemented yet
        youTubePlayer.loadVideoById(extractVideoId(defaultVideoByURL));
      }
    }
    /*
    Method:extractVideoId
    Parameters:
    inUrl:String
    Returns: String
    */

    private function extractVideoId(inUrl:String):String {
      var vIndex:Number = inUrl.lastIndexOf("=");
      if (vIndex == -1) {
        // awh snap there is no Id
        return "";
      } else {
        return inUrl.substr(vIndex + 1,inUrl.length);
      }
    }
    /*
    Method: setupInputFields
    Parameters:
    Returns:
    */

    private function setupInputFields():void {
      ti1 = new TextInput();
      ti1.move(100,375);
      ti1.width = 150;
      ti1.text = defaultVideoByID;
      ti1.addEventListener(Event.CHANGE,updateDefaultVideoById);
      ti2 = new TextInput();
      ti2.move(100,400);
      ti2.width = 250;
      ti2.text = defaultVideoByURL;
      ti2.addEventListener(Event.CHANGE,updateDefaultVideoByURL);
      addChild(ti1);
      addChild(ti2);
    }
    /*
    Method:updateDefaultVideoById
    Parameters:
    event:Event
    Returns:
    */

    private function updateDefaultVideoById(event:Event):void {
      defaultVideoByID = ti1.text;
    }
    /*
    Method:updateDefaultVideoByURL
    Parameters:
    event:Event
    Returns:
    */

    private function updateDefaultVideoByURL(event:Event):void {
      defaultVideoByURL = ti2.text;
    }
    /*
    Method: createRadioButton()
    Parameters:
    Returns:
    */

    private function createRadioButton():void {
      rb1= new RadioButton();
      rb1.label="by ID :";
      rb1.selected = true;
      rb1.move(20, 375);

      rb2= new RadioButton();
      rb2.label="by URL:";
      rb2.selected = false;
      rb2.move(20, 400);
      addChild(rb1);
      addChild(rb2);
    }
    /*
    Method:createRectangle
    Parameters:
    inSrc:*
    inColor:Number
    inW:Number;
    inH:Number;
    Return:
    */

    private function createRectangle(inSrc:*,inColor:Number=0x999999,inW:Number=80,inH:Number=50):void {
      var rect:Shape=new Shape();
      rect.graphics.clear();
      rect.graphics.beginFill(inColor);
      rect.graphics.drawRect(0,0,inW,inH);
      rect.graphics.endFill();
      inSrc.addChild(rect);
    }
  }
}

The YouTubePlayer class simply wraps up all the current API calls. It also loads the chromeless player into a provided displayObject and dispatches events using a custom events class.

YouTubePlayer.as

/****************************
* Manuel Gonzalez           *
* design@stheory.com        *
* www.stheory.com           *
* www.codingcolor.com       *
*****************************/

package com.YouTube{
  import flash.events.Event;
  import flash.events.EventDispatcher;
  import flash.events.IEventDispatcher;
  import flash.system.Security;
  import flash.events.IOErrorEvent;
  import flash.display.Loader;
  import flash.net.URLRequest;

  public class YouTubePlayer extends EventDispatcher {
   
    private var _youTubePlayer:Object;
    private var _loader:Loader;
    private var _container:*
    protected var _playerPath:String = "http://www.youtube.com/apiplayer?version=3";

    public function YouTubePlayer(target:IEventDispatcher=null) {
      super(target);
    }
    /*
    Method:createPlayer
    */

    public function createPlayer(inContainer:*):void
    {
      _container = inContainer;
      Security.allowInsecureDomain("*");
      Security.allowDomain("*");
      var _loader = new Loader();
      _loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);
      _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
      _loader.load(new URLRequest(_playerPath));
    }
   
    /*
    Method: duration
     Returns the duration in seconds of the currently playing video.
     Note that getDuration() will return 0 until the video's metadata is loaded,
     which normally happens just after the video starts playing.
    */

    public function get duration():Number
    {
      return _youTubePlayer.getDuration();
    }
    /*
    Method:videoUrl
     Returns the YouTube.com URL for the currently loaded/playing video.
    */

    public function get videoUrl():String
    {
      return _youTubePlayer.getVideoUrl();
    }
      /*
    Method:embedCode
     Returns the embed code for the currently loaded/playing video.
    */

    public function get embedCode():String
    {
      return _youTubePlayer.getVideoEmbedCode();
    }
     
    /*
    Method: volume()
    Returns the player's current volume, an integer between 0 and 100.
    Note that getVolume() will return the volume even if the player is muted.
    */

    public function get volume():Number
    {
     return _youTubePlayer.getVolume();
    }
   
    /*
    Method: VideoBytesLoaded
    Returns the number of bytes loaded for the current video.
    */

    public function get VideoBytesLoaded():Number
    {
      return _youTubePlayer.getVideoBytesLoaded();
    }
   
    /*
    Method: VideoBytesTotal
    Returns the size in bytes of the currently loaded/playing video.
    */

    public function get VideoBytesTotal():Number
    {
      return _youTubePlayer.getVideoBytesTotal();
    }
     
    /*
    Method: VideoStartBytes
    Returns the number of bytes the video file started loading from.
    Example scenario: the user seeks ahead to a point that hasn't loaded yet,
    and the player makes a new request to play a segment of the video that hasn't loaded yet.
    */

    public function get VideoStartBytes():Number
    {
      return _youTubePlayer.getVideoStartBytes();
    }
      /*
    Method:PlayerState
    Returns the state of the player. Possible values are unstarted (-1), ended (0), playing (1),
    paused (2), buffering (3), video cued (5).
    */

    public function get PlayerState():Number
    {
      return _youTubePlayer.getPlayerState();
    }
      /*
    Method: CurrentTime
    Returns the elapsed time in seconds since the video started playing.
    */

    public function get CurrentTime():Number
    {
      return _youTubePlayer.getCurrentTime()
    }
      /*
    Method: PlaybackQuality
    This function retrieves the actual video quality of the current video.
    It returns undefined if there is no current video. Possible return values are:
    hd720, large, medium and small.
    */

    public function get PlaybackQuality():String
    {
      return _youTubePlayer.getPlaybackQuality();
    }
    /*
    Method: PlaybackQuality
    This function sets the suggested video quality for the current video.
    The function causes the video to reload at its current position in the new quality.
    If the playback quality does change, it will only change for the video being played.
    */

    public function set PlaybackQuality(suggestedQuality:String):void
    {
        _youTubePlayer.setPlaybackQuality(suggestedQuality);
    }
     
    //////////////////////////////////////////////////////////////////////////////////////////////
   
    /*
    Method: cueVideoById
    Loads the specified video's thumbnail and prepares the player to play the video.
    The player does not request the FLV until playVideo() or seekTo() is called.
    */

    public function cueVideoById(videoId:String, startSeconds:Number=0, suggestedQuality:String="default"):void
    {
      _youTubePlayer.cueVideoById(videoId, startSeconds, suggestedQuality);
    }
    /*
    Method:loadVideoById
    Loads and plays the specified video.
    */

    public function loadVideoById(videoId:String, startSeconds:Number=0, suggestedQuality:String="default"):void
    {
      _youTubePlayer.loadVideoById(videoId, startSeconds, suggestedQuality);
    }
    /*
    Method:cueVideoByUrl
    Loads the specified video's thumbnail and prepares the player to play the video.
    The player does not request the FLV until playVideo() or seekTo() is called.
    */

    public function cueVideoByUrl(mediaContentUrl:String, startSeconds:Number=0):void
    {
      _youTubePlayer.cueVideoByUrl(mediaContentUrl, startSeconds);
    }
    /*
    Method:playVideo
     Plays the currently cued/loaded video.
    */

    public function playVideo():void
    {
      _youTubePlayer.playVideo();
    }
      /*
    Method:pauseVideo
    Pauses the currently playing video.
    */

    public function pauseVideo():void
    {
      _youTubePlayer.pauseVideo();
    }
      /*
    Method: stopVideo
    Stops the current video. This function also cancels the loading of the video.
    */

    public function stopVideo():void
    {
      _youTubePlayer.stopVideo();
    }
      /*
    Method: seekTo
    Seeks to the specified time of the video in seconds.
    The seekTo() function will look for the closest keyframe before the seconds specified.
    This means that sometimes the play head may seek to just before the requested time,
    usually no more than ~2 seconds.
    */

   
    public function seekTo(seconds:Number, allowSeekAhead:Boolean):void
    {
      _youTubePlayer.seekTo(seconds, allowSeekAhead);
    }
   
    /*
    Method:
     Mutes the player.
    */

    public function mute():void
    {
      _youTubePlayer.mute();
    }
   
    /*
    Method: unMute
    Unmutes the player.
    */

    public function unMute():void
    {
      _youTubePlayer.unMute();
    }
   
    /*
    Method: isMuted
    Returns true if the player is muted, false if not.
    */

    public function isMuted():Boolean
    {
      _youTubePlayer.isMuted();
    }
   
    /*
    Method: setVolume
     Sets the volume. Accepts an integer between 0 and 100.
    */

    public function setVolume(inVolume:Number):void
    {
      _youTubePlayer.setVolume(inVolume);
    }
 
   
      /*
    Method:setSize
    Sets the size in pixels of the player.
    This method should be used instead of setting the width and height properties
    of the MovieClip. Note that this method does not constrain the proportions of
    the video player, so you will need to maintain a 4:3 aspect ratio.
    The default size of the chromeless SWF when loaded into another SWF is 320px by 240px
    and the default size of the embedded player SWF is 480px by 385px.
    */

    public function setSize(inWidth:Number, inHeight:Number):void
    {
      _youTubePlayer.setSize(inWidth, inHeight);
    }
   
      /*
    Method: loadVideoByUrl
    This function, which loads and plays the specified video,
    has not yet been implemented for the ActionScript 3.0 Player API.
    */

    public function loadVideoByUrl(mediaContentUrl:String, startSeconds:Number=0):void
    {
   
      _youTubePlayer.loadVideoByUrl(mediaContentUrl, startSeconds);
    }
    /*
    Method: destroy
    This function, which has not yet been implemented for the AS3 Player API,
    destroys the player instance. This method should be called before unloading
    the player SWF from your parent SWF.
    */

    public function destroy():void
    {
      _youTubePlayer.destroy();
    }
    private function onLoaderInit(event:Event):void {
     
      var player:Loader = Loader(event.target.loader);
      _youTubePlayer = player.content;
      _youTubePlayer.addEventListener("onReady", onPlayerReady);
      _youTubePlayer.addEventListener("onError", onPlayerError);
      _youTubePlayer.addEventListener("onStateChange", onPlayerStateChange);
      _youTubePlayer.addEventListener("onPlaybackQualityChange", onVideoPlaybackQualityChange);
      _container.addChild(_youTubePlayer);
      _loader = null;
      }
    private function ioErrorHandler(event:IOErrorEvent):void {
            //trace("ioErrorHandler: " + event);
      dispatchEvent(new YouTubeEvent(YouTubeEvent.ON_IOERROR,event));
        }
    private function onPlayerReady(event:Event):void {
      //trace("player ready:", Object(event).data)
      dispatchEvent(new YouTubeEvent(YouTubeEvent.ON_READY,event.data));
    }

    private function onPlayerError(event:Event):void {
      //trace("player error:", Object(event).data);
      dispatchEvent(new YouTubeEvent(YouTubeEvent.ON_ERROR,event.data));
    }

    private function onPlayerStateChange(event:Event):void {
      //trace("player state:", Object(event).data);
      dispatchEvent(new YouTubeEvent(YouTubeEvent.ON_CHANGE,event.data));
    }

    private function onVideoPlaybackQualityChange(event:Event):void {
      //trace("video quality:", Object(event).data);
      dispatchEvent(new YouTubeEvent(YouTubeEvent.ON_QUALITY_CHANGED,event.data));
    }

  }
}

The VideoPlayerControls class builds all the independent assets to control the chromeless player.

VideoPlayerControls.as

/****************************
* Manuel Gonzalez           *
* design@stheory.com        *
* www.stheory.com           *
* www.codingcolor.com       *
*****************************/


package com.video{
  import flash.display.*;
  import flash.events.MouseEvent;
  import flash.events.Event;
 
 
  public class VideoPlayerControls extends Sprite{
   
   
    public static  const ON_PLAYBACK_STATE_CHANGE:String = "ON_PLAYBACK_STATE_CHANGE";
    public static  const ON_SOUND_CHANGE:String = "ON_SOUND_CHANGE";
    public static  const ON_SEEK_CHANGE:String = "ON_SEEK_CHANGE";
   
    private var playbackControl:MovieClip;
    private var loadProgessBar:MovieClip;
    private var scrubControl:MovieClip;
    private var volumeControl:MovieClip;
    private var muteControl:MovieClip;
    private var vidWidth:Number;
    private var vidHeight:Number;
   
    public function set videoWidth(inNum:Number):void
    {
       vidWidth=inNum;
    }
    public function get videoWidth():Number
    {
       return vidWidth;
    }
    public function set videoHeight(inNum:Number):void
    {
      vidHeight =inNum;
    }
    public function get videoHeight():Number
    {
      return vidHeight;
    }
    public function VideoPlayerControls(){}
    /*
    Method: init
    Parameters:
    Returns:
    */

    public function init():void
    {
      createPlayPauseButton();
      createMuteButton();
      createVideoLoadBar();
      createScrubControl();
      adjustLayout( vidWidth,vidHeight)
    }
    /*
    Method: setLoadingProgress
    Parameters:
    inObj:Object
    Returns:
    */

    public function setLoadingProgress(inObj:Object):void
    {
      loadProgessBar.byteLoaded = inObj.bytes;
      loadProgessBar.byteTotal = inObj.total;
    }
    /*
    Method:setVolumeControl
    Parameters:
    inNum:Number
    Returns:
    */

    public function setVolumeControl(inNum:Number):void
    {
       volumeControl.curVolume = inNum;
    }
    /*
    Method: setMuteControl
    Parameters:
    inBool:Boolean
    Returns:
    */

    public function setMuteControl(inBool:Boolean):void{
      muteControl.isMuted = inBool;
    }
    /*
    Method: setPlayPauseControls
    Parameters:
    inNum:Number
    Returns:
    */

    public function setPlayPauseControls(inNum:Number):void
    {
      if(inNum == 0){
        playbackControl.buttonState="play";
      }else if(inNum == 1){
        playbackControl.buttonState="pause";
      }
    }
    /*
    Method: setSeekDuration
    Parameters:
    inNum:Number
    Returns:
    */

    public function setSeekDuration(inNum:Number):void
    {
      scrubControl.durr = inNum;
    }
    /*
    Method: setSeekCurrentTime
    Parameters:
    inNum:Number
    Returns:
    */

    public function setSeekCurrentTime(inNum:Number):void
    {
      scrubControl.currTime = inNum;
    }
    /*
    Method: adjustLayout
    Parameters:
    inW:Number
    inH:Number
    Returns:
    */

    public function adjustLayout(inW:Number,inH:Number):void
    {
      playbackControl.x=0;
      loadProgessBar.x = (playbackControl.x + playbackControl.width)+10;
      loadProgessBar.y = playbackControl.height/2 - loadProgessBar.height/2;
      scrubControl.x = loadProgessBar.x;
      scrubControl.y = loadProgessBar.y;
      muteControl.x = inW - muteControl.width
     
    }
    /*
    Method: destroy
    Parameters:
    Returns:
    */

    public function destroy():void
    {
      playbackControl.removeEventListener(Event.CHANGE,setPlaybackState);
      muteControl.removeEventListener(Event.CHANGE,setMuteState);
      scrubControl.removeEventListener(Event.CHANGE,onSeek);
      removeChild(playbackControl);
      removeChild(loadProgessBar);
      removeChild(muteControl);
      removeChild(scrubControl);
    }
    /*
    Method: createScrubControl
    Parameters:
    Returns:
    */

    private function createScrubControl():void
    {
      scrubControl = new VideoScrubber();
      scrubControl.addEventListener(Event.CHANGE,onSeek);
      addChild(scrubControl);
    }
    /*
    Method:createMuteButton
    Parameters:
    Returns:
    */

    private function createMuteButton():void
    {
      muteControl = new MuteControlButton();
      muteControl.addEventListener(Event.CHANGE,setMuteState);
      addChild(muteControl);
    }
    /*
    Method: createVideoLoadBar
    Parameters:
    Returns:
    */

    private function createVideoLoadBar():void
    {
      loadProgessBar = new VideoProgressBar();
      addChild(loadProgessBar);
    }
    /*
    Method: createPlayPauseButton
    Parameters:
    Returns:
    */

    private function createPlayPauseButton():void
    {
      playbackControl = new PlayPauseButton();
      playbackControl.addEventListener(Event.CHANGE,setPlaybackState);
      addChild(playbackControl);
    }
    /*
    Method:createVolumeSliderControl
    Parameters:
    Returns:
    */

    private function createVolumeSliderControl():void
    {
      volumeControl = new VolumeSliderControl();
      volumeControl.addEventListener(Event.CHANGE,adjustPlayerVolume);
      addChild(volumeControl)
     
    }
   
    /*
    Method:createVolumeBarControl
    Parameters:
    Returns:
    */

    private function createVolumeBarControl():void
    {
      volumeControl = new VolumeBarControl();
      volumeControl.addEventListener(Event.CHANGE,adjustPlayerVolume);
      addChild(volumeControl)
     
    }
    /*
    Method:adjustPlayerVolume
    Parameters:
    event:Event
    Returns:
    */

    private function adjustPlayerVolume(event:Event):void
    {
      var evtObj:Object = {state:"adjust_volume", val:volumeControl.curVolume}
      dispatchEvent(new VideoControlsEvent(evtObj,ON_SOUND_CHANGE));
    }
    /*
    Method:setPlaybackState
    Parameters:
    event:Event
    Returns:
    */

    private function setPlaybackState(event:Event):void
    {
      var evtObj:Object = {state:playbackControl.buttonState}
      dispatchEvent(new VideoControlsEvent(evtObj,ON_PLAYBACK_STATE_CHANGE));
    }
    /*
    Method:setMuteState
    Parameters:
    event:Event
    Returns:
    */

    private function setMuteState(event:Event):void
    {
      var type:String;
      if(muteControl.isMuted){
        type = "mute";
      }else{
        type = "unmute";
      }
      var evtObj:Object = {state:type};
      dispatchEvent(new VideoControlsEvent(evtObj,ON_SOUND_CHANGE));
    }
    /*
    Method: onSeek
    Parameters:
    event:Event
    Returns:
    */

    private function onSeek(event:Event):void
    {
      var evtObj:Object = {state:"seek",val:scrubControl.sec}
      dispatchEvent(new VideoControlsEvent(evtObj,ON_PLAYBACK_STATE_CHANGE));
    }
   
   
  }
 
 
 
 
 
}

And thats pretty much the meat of the application. The rest of the classes are each video control asset (play/pause, mute, ect.).
The next release I will introduce the ability to search YouTube and display the results in a custom scroller.
Enjoy!

Download Source:
AS3 YouTube Chromeless Player (929)

22 thoughts on “AS3 YouTube Chromless API

  • January 21, 2010 at 12:54 pm
    Permalink

    Your code is great, but i cant understand why you have to do classes, object oriented, build objects at run time, labels, buttons, etc. To show something so simple, your readers at some time will get lost.

    But this is only my way of think.

    If you want make a post where you show “best practices”, “object oriented programming in as3”, “classes”, etc that will be great, but to show this i think the target is “show clearly”

    — i didt only with this lines

    import flash.system.Security;

    Security.allowInsecureDomain(“*”);
    Security.allowDomain(“*”);

    // This will hold the API player instance once it is initialized.
    var player:Object;

    //Codigo del video a cargar

    var loader:Loader = new Loader();
    loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);
    loader.load(new URLRequest(“http://www.youtube.com/apiplayer?version=3”));

    function onLoaderInit(event:Event):void {
    addChild(loader);
    loader.content.addEventListener(“onReady”, onPlayerReady);
    loader.content.addEventListener(“onError”, onPlayerError);
    loader.content.addEventListener(“onStateChange”, onPlayerStateChange);
    loader.content.addEventListener(“onPlaybackQualityChange”, onVideoPlaybackQualityChange);
    }

    function onPlayerReady(event:Event):void {
    // Event.data contains the event parameter, which is the Player API ID
    trace(“player ready:”, Object(event).data);

    // Once this event has been dispatched by the player, we can use
    // cueVideoById, loadVideoById, cueVideoByUrl and loadVideoByUrl
    // to load a particular YouTube video.
    player=loader.content;
    var laUrl = “http://www.youtube.com/watch?v=cZ5zn1Vvd2I”;
    var elId = “”;
    var vIndex:Number=laUrl.lastIndexOf(“=”);
    if (vIndex==-1) {
    // awh snap there is no Id
    elId = “”;
    } else {
    elId = laUrl.substr(vIndex + 1,laUrl.length);
    }
    trace(elId);
    player.loadVideoById(elId);
    player.setSize(320, 240);
    player.x=15;
    player.y=15;
    }

    function onPlayerError(event:Event):void {
    // Event.data contains the event parameter, which is the error code
    trace(“player error:”, Object(event).data);
    }

    function onPlayerStateChange(event:Event):void {
    // Event.data contains the event parameter, which is the new player state
    trace(“player state:”, Object(event).data);

    if (Object(event).data==3) {

    intervalo.start();
    }

    if (Object(event).data==0) {

    intervalo.stop();
    }

    }

    Reply
    • January 21, 2010 at 1:32 pm
      Permalink

      Hi Ben,
      Thanks for the comment and additional code. I did state, “it’s a bit more involved than the example you will find on the API reference page. The following is an OOP based implementation”. My posts vary from simplified to OOP based implementations based on my mood. I hope the post helped you and others in some way or another , its all a learning experience.

      Reply
  • January 21, 2010 at 12:56 pm
    Permalink

    function onVideoPlaybackQualityChange(event:Event):void {
    // Event.data contains the event parameter, which is the new video quality
    trace(“video quality:”, Object(event).data);
    }

    /* the lines intervalo.stop() and intervalo.start() doesnt matter erase them*/

    Reply
  • January 29, 2010 at 4:52 pm
    Permalink

    For me it mutes but doesn’t un-mute. Tried it in IE and Chrome. I have this problem with my project too. Is it just my machine or is this a problem for others too.

    Reply
  • January 30, 2010 at 2:04 pm
    Permalink

    nice tutorial. thanks for sharing!

    Reply
  • June 7, 2010 at 8:33 pm
    Permalink

    how can i call the embed code into main as and display it plz help me

    Reply
    • June 7, 2010 at 10:27 pm
      Permalink

      @bijoy.
      Look into the getVideoEmbedCode() method in the youtube API. It will return a string of the embed code for the currently loaded/playing video.
      M

      Reply
  • August 24, 2010 at 5:11 pm
    Permalink

    Hello!

    Congratulations! Your player is very nice!

    Do u have an example with a quality selector and fullscreen? I try to modify your code to use this functions without success… fullscreen not work fine on FireFox, and the quality selector I don´t know how to populate the combobox… can u help me?

    Thanks a lot!

    Reply
    • August 25, 2010 at 10:16 pm
      Permalink

      Hi Pedro,
      I haven’t tested either of the functionality you speak of. When I get some free time, i’ll revisit the post and include the source.

      Reply
  • January 6, 2011 at 9:42 am
    Permalink

    Hi there,

    A big thank you for your example above. Has been a great learning resource for me.

    May I ask a question: When mute is activated and the volume slider is used, how do I tell the mute button to deactivate?

    Peace and blessings.

    Reply
    • January 6, 2011 at 10:50 am
      Permalink

      Hi Jorgen,
      You can skin a cat in many ways. Here is one way of doing it.
      Add a new method to the MuteControlButton.as class:
      public function resetMuteControl():void
      {
      setToggle();
      }
      All that does is reset the visual state of the mute button.

      Now in the Main.as class navigate to the playerControlsSoundOnChange() method and revise it a bit.

      private function playerControlsSoundOnChange(event:VideoControlsEvent):void {

      var buttonState:String = event.data.state;
      switch (buttonState) {
      case “mute” :
      youTubePlayer.mute();
      break;
      case “unmute” :
      youTubePlayer.unMute();
      break;
      case “adjust_volume” :
      //new code
      if( youTubePlayer.isMuted() )//check to see if the youtube player is actually muted
      {
      //if its is, reset the mute button to reflect a state of unmute
      //path to your slider instance .resetMuteControl();
      // unmute the youtube player
      youTubePlayer.unMute();
      }
      //
      youTubePlayer.setVolume(event.data.val);
      removeEventListener(Event.ENTER_FRAME,trackProgress);
      break;
      }
      }

      Give it a try.
      Enjoy!

      Reply
  • January 6, 2011 at 11:43 am
    Permalink

    Thank you so very much.

    However, it never enters this bit of code:

    if( youTubePlayer.isMuted() )/

    even with the mute button activated.

    Please bear with me I’m a bit new to all this and I’m learning so much from this project.

    The sound slider is activated in the VideoPlayerControls.as init() function utilising the function createVolumeSliderControl() and I have no idea what instance this is?

    Thank you again.
    Peace

    Reply
  • January 12, 2011 at 10:50 pm
    Permalink

    Brilliant! Thank you very much! This was beyond helpful!

    -joeshock

    Reply
  • March 3, 2011 at 3:26 am
    Permalink

    Hi there, just wanted to say thank you very much for this Tut, i was struggling with the seekbar function so this is a really great help for me! very very helpful!

    Reply
  • May 18, 2011 at 4:02 am
    Permalink

    Hi…this is a great tutorial…one of the few out there that they actually work!!

    I tried out Bens version of code because it seemed to fit more easily in my project…but i do need to add some controls like a playhead and time etc etc…

    is there a way to do this?

    Reply
    • May 18, 2011 at 9:19 pm
      Permalink

      I can’t speak to Ben’s version since it’s not MY recommended way to implement Actionscript, especially in AS3. The code I provide implements some of the basic controls you desire. If you would like to use my code with Ben’s version simply copy the Video Controls Folder from my .fla into yours and make sure you keep the code source folder structure the same. You would have to add the following method(s) createVideoPlayerControls(), playerControlsOnChange(), playerControlsSoundOnChange() and trackProgress() to your existing code.

      Good luck.

      Reply
  • August 5, 2011 at 3:10 pm
    Permalink

    Hi,

    I wonder if you can check your coding, there seems to be an memory leakage issue. Every time you reload the video file the commit and memory size increases. Im looking to load and play back a playlist of video files. Id be greatful if you can let me know once you have located and fixed this. Thanks Shiraz

    Reply
  • February 17, 2012 at 6:56 am
    Permalink

    how i play the video in perticular second

    Reply
  • April 28, 2012 at 1:34 am
    Permalink

    nice work……great…really helpful… 😀

    Reply
  • July 12, 2012 at 4:05 pm
    Permalink

    Is the VolumeSliderControl available, if it is not how do I get it to appear?

    Guy

    Reply
    • August 15, 2012 at 4:09 pm
      Permalink

      Hi,
      It’s been so long since I posted the article, I don’t remember if I included audio controls in the package. But you can easily implement a sliding volume control on your own. There are tons of them online Kieth Peters has some minimal ones. All you would have to do is pass the sliders value like so :
      youTubePlayer.setVolume(50)

      Good Luck!

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: