Youtube AS3 Wrapper – Documentation
The IYoutube Interface
This actually represents the playground for Youtube AS3 Wrapper: all the methods needed to handle youtube videos are methods of this interface.
So let’s go through each of the methods.
EventDispatcher related:
Use addEventListener to listen to the events dispatched by IYoutube:
YoutubeEvent.PLAYER_READY: dispatched when the player is loaded and ready to receive method calls
YoutubeEvent.PlAYER_ERROR: dispatched when the player receives an error
Possible error codes: 100 – video not found; 101, 150 – video not available in user area or cannot be played in chromeless player
YoutubeEvent.PlAYER_STATE_CHANGE: dispatched when the player has changed state
Always check if the player is ready to receive function call (after a YoutubeEvent.PLAYER_READY event the player is ready) before calling any function (exception functions are those described above and: destroy(), reload() and destroyAndReload() which will be discussed later).
Use isPlayerReady() to check if the player is ready:
* check to see if player is ready; always check if it's ready before calling any method
* @return Boolean true if player is ready, false otherwise
*/
function isPlayerReady():Boolean;
Loading videos methods:
* loads a video
* @param id String youtube id or youtube url
* @param startSeconds Number seconds from where to start the video
*/
function loadVideo(id:String, startSeconds:Number = 0):void;
/**
* cue a video
* @param id String youtube id or youtube url
* @param startSeconds Number seconds from where to start the video
*/
function cueVideo(id:String, startSeconds:Number = 0):void;
Use loadVideo when you want the playback to start as soon as the video is loaded. If loadVideo is used, there’s no need to call playVideo method, as playback starts automatically.
Use cueVideo when you don’t want the playback to start automatically. When this method is used, the player sends a Cue Video state (5) when the video is ready to play. Then playVideo method can be called.
On both methods, information about the video is available only after the playback has started ( a Playing state is entered (1)).
Video playback control:
* Play or resume a paused video
*/
function playVideo():void;
/**
* Pauses a playing video
*/
function pauseVideo():void;
/**
* Stops the current video; after this method is called, the clip cannot be played anymore; the video must be loaded again
*/
function stopVideo():void;
If stopVideo method is called, the clip that was playing cannot be played again. In order to do that, that video must be reloaded, using one of the loading methods described above.
To clear the remnant picture of a stopped video (stopped by using stopVideo()):
* Clears a remnant video after stopVideo() was called
*/
function clearVideo():void;
/**
* A merge between stopVideo() and clearVideo(); should be used instead of calling stopVideo() then clearVideo()
*/
function stopAndClearVideo() : void;
Use clearVideo to clear a video from display. However, instead of calling stopVideo() and then clearVideo(), call only stopAndClearVideo(). This is a better way because it uses only one LocalConnection call, instead of 2 (1 for stopVideo and 1 for clearVideo).
To resize the video:
Always use this method instead of setting width and height parameters on IYoutube object directly. By using this method, the youtube logo will keep it’s current size, otherwise scaling will occur both on the video picture and the logo (which is unwanted).
Methods to check if the player has any errors. However remember that when an error occurs, a YoutubeEvent.PLAYER_ERROR event is dispatched.
After an YoutubeEvent.PLAYER_ERROR event is dispatched, getPlayerError() returns the current error. Also playerHasError will return true.
The error is cleared when a new video is loaded or cued, or the current video is stopped or cleared.
Audio control functions:
* Mute the video
*/
function mute():void;
/**
* Unmute the video
*/
function unmute():void;
/**
* @return Boolean true if the video is muted false otherwise
*/
function isMute():Boolean;
/**
* Set the volume of the video
* @param volume Number the volume to be set [0-100]
*/
function setVolume(volume:Number):void;
/**
* Return the current volume of the video
* @return Number volume [0-100]
*/
function getVolume():Number;
The volume is a Number between 0 and 100.
Details about loading:
* Returns the current bytes loaded
* @return Number the current bytes loaded
*/
function getVideoBytesLoaded():Number;
/**
* Return the total bytes of the video, or a negative number until the total bytes of the video is known
* @return Number the total video bytes
*/
function getVideoBytesTotal():Number;
Notice that getVideoBytesTotal will return a negative Number until the details about the current video are loaded (which happens when a Playing (1) state is entered). So you should always check to see if the returned Number is greater than 0 before using it in calculations.
Also getVideoBytesLoaded returns 0 until any bytes are downloaded.
Details about playback and video length in seconds:
Both values are in seconds. Notice that getDuration will return a negative Number until the duration of the clip is found (after a Playing (1) state is entered). getCurrentTime will return 0 until the playback head changes. You should always check to see if getDuration returns a Number greater than 0 before using it.
Method to change the playhead:
Method to determine the current playing state the player is in. Should be used when a YoutubeEvent.PLAYER_STATE_CHANGE event occurs:
* Returns the players state
* @return int returns the current player stat
*/
function getPlayerState():int;
This method returns the current state that player has: -1=Video is Unstarted, 0=Video has Ended, 1=Video is Playing, 2=Video is Paused, 3=Buffering Video, 5=Video is Cued (received when cueVideo method is used to load a video; after this event is received, playVideo method can be used to start playback).
Use this method to know the current state of the player.
Link and embed code of current video:
Note that the url and the embed code are those related to Youtube site, and not related to the current player!
The next method, recently introduced by youtube api, returns the bytes where the video has started playing (if appropriate):
* Return the current bytes the video has started from
* @return uint video start bytes
*/
function getVideoStartBytes() : uint;
And saved the best for the last. This methods help destroying and reloading the player without the need to reload the entire wrapper.
* Destroy the player; no other action, other than reload() can occur on the player after this call
*/
function destroy() : void;
/**
* Reloads the player; YoutubeEvent.PLAYER_READY event will be dispatched when the player is loaded and ready to receive action
*/
function reload() : void;
/**
* A merge of destroy() and reload(); it should be used instead of calling destroy() and then reload()
*/
function destroyAndReload() : void;
As you can see there are these three methods: destroy, reload and destroyAndReload.
If you need to call destroy, then reload, use destroyAndReload instead.
You might be wondering why would you ever need to destroy and reload the player, and you’re right. In most of the cases you won’t need to destroy and reload it. However in Internet Explorer, after a few, or after every clip, has played, on another clip volume and mute will not work anymore. So when this happens, you can call destroyAndReload(), wait for Youtube.PLAYER_READY event, and then you’re good to play another clip, with volume and mute, and everything else supported. Note that this only happens in Internet Explorer, so before destroying and reloading the player check what browser is the embedding the player.
This method is used in the test harness player v1.0, so you can download the sources of the test harness player v1.0 (v1.1 uses the new Youtube AS3 Wrapper) and look through the code for more details on this is use.
The YoutubeEvent class
The only important here are these 3 constants:
Use these constants when you add event listeners to the IYoutube object.
Example:
....
ytPlayer.addEventListener(YoutubeEvent.PLAYER_READY, onYTPlayerReady);
function onYTPlayerReady(event : YoutubeEvent) : void {
// code here
}


How does the destroyAndReload() Work
I have the following
public function unloadPlayer(){
//loader.unload();
videoID = ”;
var t:TextField = youtubeText as TextField;
t.text = ‘Player removing ‘ + this.player.getPlayerState();
this.player.destroy();
}
public function removePlayer(end:Boolean) {
videoID = ”;
this.player.stopAndClearVideo();
if(end){
this.player.destroy();
}
}
I get the player readystate as 0
then I have
public function loadYouTubeVideo(ID) {
var t:TextField = youtubeText as TextField;
/*if (videoID != ”) {
t.text = ‘Player is on ‘+ this.player.getPlayerState();
this.player.stopAndClearVideo();
} */
videoID = ID;
if(this.player.isPlayerReady()){
this.player.loadVideo(ID);
t.text = ‘Player is now ‘+ this.player.getPlayerState();
}else{
this.player.destroyAndReload();
t.text = ‘Player is loading at ‘+ this.player.getPlayerState();
}
t.text = ‘Player is at ‘+ this.player.getPlayerState();
}
Nothing is happening
now on executing the player is removed…but in trying to reload It i dont get back the player….
I get a player ready state of -1
Sorry for not answering earlier.
There are no changes yet since v0.7.2
You could download the sources for a Test Harness Player in the downloads area, and look through the code to see how it’s done there.
I recommend using the latest wrapper and the latest sources for the player.
Regards
Ok so i did a destroyAndReload() and i get a playerchangestate = 0. So now I try for a loadVideo() but when i do this.player.isPlayerReady() is not true… Sooo what does this mean? i need to loader.load() again? do i attempt a this.player.reload()?
I dont get any errors though…
did I mention that this is a flash website and has nothing to do with FLEX?
can i also mention that I found no CS3 FLA files in the test harness player? are you destroying anything in the test player? it would be good to illustrate how this destroy/ destroyAndReload() works
ok i have been working on this for 2 weeks. I tried everything. this is what I have so far
package {
import flash.display.MovieClip;
import pinosh.youtube.IYoutube;
import pinosh.youtube.YoutubeEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.IOErrorEvent;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.text.*;
public class YoutubeVideoPlayer extends MovieClip {
private var player : IYoutube;
var API:String = ‘key=AI39si6KVHOdqCapPaeUoAo6y2YyoDW35NM3XKpGcfD_GN2U3C_oML7LonPjOk55L1R0fVC5dzL2x-SPY9Fq6YVotNnFTdBX0w&client=ytapi-KendallArneaud-BrotherResistanc-ag7m3q3u-0′;
var videoID = ”;
var loader:Loader;
public function YoutubeVideoPlayer(vidID) {
super();
videoID = vidID
loadPlayer();
}
public function playerStopPlaying(e) {
this.player.stopAndClearVideo();
videoID = ”;
//this.player.destroyAndReload();
//this.visible = false;
}
public function unloadPlayer(){
loader.unload();
videoID = ”;
player = null;
}
public function removePlayer(){
/*var t:TextField = youtubeText as TextField;
videoID = ”;
if(this.player.getPlayerState() == 5 || this.player.getPlayerState() == 1){
stopPlayer(true);
}else{
t.text = ‘Player removing ‘ + this.player.destroyAndReload();
}*/
this.player.stopAndClearVideo();
}
public function stopPlayer(end:Boolean){
this.player.stopAndClearVideo();
if(end && this.player.isPlayerReady()){
removePlayer();
var t:TextField = youtubeText as TextField;
t.text = ‘Player removing ‘ + this.player.getPlayerState();
}
}
public function loadPlayer(){
if(player == undefined){
var t:TextField = youtubeText as TextField;
t.text = ‘Player is loading’;
loader = new Loader();
// listen for the right events
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.playerLoaded);
//loader.contentLoaderInfo.addEventListener(Event.UNLOAD, this.removePlayer);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.playerCannotBeLoaded);
loader.load(new URLRequest(”ytPlayer.swf?apiKey=”+API));// to pass the youtube api key use
}else if(this.player.isPlayerReady()){
var t:TextField = youtubeText as TextField;
t.text = ‘Player is loading at ‘+ this.player.getPlayerState();
this.player.reload();
}else if(this.player.playerHasError()){
var t:TextField = youtubeText as TextField;
t.text = ‘Player error is ‘+ this.player.getPlayerError();
}else if(this.player){
this.player.loadVideo(videoID);
var t:TextField = youtubeText as TextField;
t.text = ‘Player is restarting ‘;
//loadPlayer();
}else{
var t:TextField = youtubeText as TextField;
t.text = ‘Player is reloading ‘
unloadPlayer();
loadPlayer();
}
}
private function playerLoaded(event : Event):void {
// grab the loader object
var loader : Loader = event.target["loader"] as Loader;
// add it to the display list of TestPlayer
this.addChild(loader);
// grab the IYoutube object; it’s the content property of the loader object
this.player = loader.content as IYoutube;
// start listening for the events dispatched by player
this.player.addEventListener(YoutubeEvent.PLAYER_READY, this.onYTPlayerReady);
this.player.addEventListener(YoutubeEvent.PLAYER_STATE_CHANGE, this.onYTPlayerStateChange);
this.player.addEventListener(YoutubeEvent.PLAYER_ERROR, this.onYTPlayerError);
}
private function playerCannotBeLoaded(event : IOErrorEvent):void {
// trace the for this test, bu should be handled more carrefully
var t:TextField = youtubeText as TextField;
t.text = ‘Player not found ‘ + event;
}
private function onYTPlayerReady(event : YoutubeEvent):void {
// now our player is ready to rumble; let’s play a clip
var t:TextField = youtubeText as TextField;
if (videoID != ”) {
this.player.loadVideo(videoID);
t.text = ‘Player Getting Video : ‘+ this.player.getPlayerState();
}
t.text = ‘Player Ready : ‘+ this.player.getPlayerState();
}
private function onYTPlayerStateChange(event : YoutubeEvent):void {
var t:TextField = youtubeText as TextField;
t.text = “TestPlayer::onYTPlayerStateChange ==> “+this.player.getPlayerState();
}
private function onYTPlayerError(event : YoutubeEvent):void {
var t:TextField = youtubeText as TextField;
t.text = “TestPlayer::onYTPlayerError ==> “+this.player.getPlayerError();
}
public function loadYouTubeVideo(ID) {
var t:TextField = youtubeText as TextField;
/*if (videoID != ”) {
t.text = ‘Player is on ‘+ this.player.getPlayerState();
this.player.stopAndClearVideo();
} */
videoID = ID;
if(this.player.isPlayerReady()){
this.player.loadVideo(ID);
t.text = ‘Player is now ‘+ this.player.getPlayerState();
}else{
loadPlayer();
}
//t.text = ‘Player is at ‘+ this.player.getPlayerState();
}
}
}
the following is not working in being able to re-instantiate the wrapper
this.player.destory();
this.player.destoryAndReload();
this.player.stopAndClearVideo();
i even tried to unload.
I believe what could be causing this is not being able to close the bridge or destory function in AS2…I’m not sure though
has anyone ver been success full in destroying and reloading ?
No you won’t find any fla files inside the packages, but if you look through the mxml ones you will see the actionscript3 code that you need.
The code is almost the same, except for the line where it says “…rawChildren.addChild”.
If you look at that you should be ok.
I did look at the mxml would you believe…You seem to be doing some basic stuff so I cant understand why what I have is not working. What i am paying attention to is the fact that we both try to stop and clear the video first just to make sure we get rid of any thing and then try to destory and reload it…. I get this and it seems to work as on the destroy and reload i get the play state change to 0…this is good…but its when I try to load a new clip…I dont get anything loading. What I want to note is that even on the destroy and reload I note the browsers status bar indicating that i might still be loading/ streaming the video as the url is a google url.
Thank you for this wrapper. However getStartBytes() and getLoadedBytes() seem to have issues.
Just load a YouTube video, then seek to any unbuffered (yet) pointinto the video.
You’ll see that the getStartBytes() continually returns 0, while getLoadedBytes() continues to increase from its pre-seek value when it should have been resetted to 0.
The concerned YouTube API methods work fine so either it’s a problem with your wrapper, or with my code. I’m inclined towards the former since I didn’t have this problem with other wrappers.
Oops. I failed to notice that the allowSeekAhead parameter was set to false by default. Instead of seeking to an unbuffered point, I was seeking to the last buffered point – that’s why startBytes was always 0 and loadedBytes wasn’t resetted.
Sorry for the fake alert. Definitely the best YouTube wrapper around here.
@Mat
My second comment isn’t appearing for some reason I was just saying that I failed to notice that allowSeekAhead was set to false by default and that was the cause of my problems. Your wrapper works perfectly fine.
Hi.
I’m glad you figured it out.
I tried my best to make it work best, however there’s always room for improvement.
Thanks for the kind words.
Ovidiu
Hello!
First of all thank you for your great work. When I compile and run your test case, the video loads as excepted, but theese security errors are thrown:
*** Security Sandbox Violation ***
SecurityDomain ‘http://localhost/MySwf.swf’ tried to access incompatible context ‘http://www.youtube.com/apiplayer?uniq=2341159274′
3
*** Security Sandbox Violation ***
SecurityDomain ‘http://localhost/MySwf.swf’ tried to access incompatible context ‘http://www.youtube.com/apiplayer?uniq=2341159274′
1
I tried to use Security.allowDoman(”www.youtube.com”); and I also tried to load a security policy xml to allow the youtube.com domain, but it does not work. It seems to me, that the wrapper class breaks the security policy. Is that the case?
If possible could you please fix this issue fast, since I would just love to use your mulitiple instance wrapper in the RIA I am developing at the moment.
Thank you!
Hi Thanks for your interest in this wrapper.
I will take a look and work on this, I will let you know when a new version that takes care of this is available.
Hi Ovidiu. Very useful component. Thanks so much for the good work!
I noticed that when a video is paused and you call seekTo with allowSeekAhead parameter set to true the video will start buffering & playing. This is not the desired behavior I think. I mean it should not start playing automatically. When it’s paused it should stay paused even after seeking forward/backward. When it’s playing it should keep playing.
Can you help me out please?
Hi Mario,
The wrapper mimics the exact behavior of the youtube chromeless player. Actually it uses that one. This means, the wrapper works just as the youtube player does. If you try to seek a paused video on the Youtube site past the downloaded bits the playback will start even though you paused the video first.
If you want to change that, you’ll have to manage that yourself.
The DOPly player does exactly what you’re looking for.
Regards,
Ovidiu
Hi Ovidiu,
thanks very much for the quick response!
Yes, you’re right! The Youtube chromeless player behaves in the same way.
I’m facing another problem. In my application the player/wrapper doesn’t initialize any more (the Youtube logo appears but the YoutubeEvent.PLAYER_READY never fires) when the website is reloaded while a video is played. It happens after 3 to 10 reloads in both Firefox and Safari on Mac OS. The only way out is then to restart the browser.
Any idea? Would it help to fire the destroy method when the website is reloaded? Shouldn’t this happen sort of automatically?
Thanks in advance,
Mario
I just tried destroy(). Calling it on webpage unload doesn’t help to avoid the described problem. No idea what to try next.
Is there a way to get one player on top and vice versa?
Yes of course.
Please refer to the changelog Changelog
You need to know the player’s id and use that in swapDepth function, or use the bringToFront, sendToBack… set of functions.
An example can be seen in the FlashTest player’s source code.