This is the final piece of actionscript, and the one I struggled the most on. It will take some explaining… but here goes!
Security.allowDomain(“www.youtube.com”,”http://s.ytimg.com”, “http://pipes.yahoo.com”);
I have already blogged about my security sandbox issues. This line of code was the fix. I had to add youtube, youtube’s favicon, and yahoo’s pipes site to a list of allowed domains. Flash is happy to communicate with online sites, only if you allow them using this Security.allowDomain code.
import flash.xml.*;
This import allows flash to communicate with the XML contained in the RSS feed generated by my Yahoo Pipe from BBC and YouTube. The feed lists YouTube links relating to the BBC top stories.
//variables and objects
var feed:String = “http://pipes.yahoo.com/pipes/pipe.run?_id=b586d73664d960245555fb6153c36275&_render=rss”;
var linkloader:URLLoader = new URLLoader();
var xml_data:XML;
This sets up my feed to interact with Flash, allowing it to be loaded with the URLLoader, and handled as xml data.
//var videos:Array;
This is an empty array, created to hold the videos I wish to display.
/*News Feed Loading*/
//listeners
linkloader.addEventListener(Event.COMPLETE, loadXML);
linkloader.load(new URLRequest(feed));
//functions
function loadXML(e:Event):void{
//copies loaded XML into XML Data
trace(“Loaded Feed”);
xml_data = new XML(e.target.data);
//trace(xml_data);
This copies my Yahoo Pipe RSS data, into the xml_data array.
var item_list:XMLList = xml_data.channel.item.link;
for (var x = 0; x < item_list.length(); x++){
trace(item_list[x]);
//videos[(x)] = item_list[x];
}
}
For each RSS item in the list, the YouTube link is extracted
// This will hold the API player instance once it is initialized.
var player:Object;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);
loader.load(new URLRequest(“http://www.youtube.com/v/g9f-6jygRJk?version=3″));
The video loader is set up, at the moment to explicitly display one video. It doesn’t yet use the URL’s held in my above link list.
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);
}
The video player is loaded, and is set to respond to a variety of errors with error description functions. These functions are explained individually below.
function onPlayerReady(event:Event):void {
// Event.data contains the event parameter, which is the Player API ID
trace(“player ready:”, Object(event).data);
If the player sets up correctly, this trace is sent.
// Once this event has been dispatched by the player, we can use
// cueVideoById, loadVideoById, cueVideoByUrl and loadVideoByUrl
// to load a particular YouTube video.
These comments explain that the player needs to be ready before it can load a video.
player = loader.content;
// Set appropriate player dimensions for your application
player.setSize(580, 360);
}
Once the player is ready, the content can be loaded, at the appropriate size.
function onPlayerError(event:Event):void {
// Event.data contains the event parameter, which is the error code
trace(“player error:”, Object(event).data);
}
This trace lists any errors which may have occured, and the object that generated them. This was helpful in the debugging process, as it allowed me to respond to each error individually, and also created a “get out” when trapped in an error loop.
function onPlayerStateChange(event:Event):void {
// Event.data contains the event parameter, which is the new player state
trace(“player state:”, Object(event).data);
}
The player always begins paused, clicking on it causes it to play. The state change between loading, playing, paused, and finished is recorded in numbers 0-3. When changing from each state, the trace is called.
function onVideoPlaybackQualityChange(event:Event):void {
// Event.data contains the event parameter, which is the new video quality
trace(“video quality:”, Object(event).data);
}
The video quality is controlled by YouTube, and accessed using their player. Changing the video quality mid-play doesn’t count as a statechange, but nonetheless did affect the playback achieved by my project. So this trace was introduced, allowing me to see if any errors were as a result of a change in video quality.