We use Akamai (formerly ninesystems) for all of our video streaming (media page, online education, grad stories, etc.) and we tend to use the FLVPlayback component for our various video players. When we hit an Akamai stream URL (http://dts.edgeboss.net/xxxxx.flv), it is an XML file with information on servers based on the user's location. This XML must be parsed in order to construct a stream URL to play. Ninesystems provided a sample player, but it used Flash 7 style coding which is very hard to manage. I've developed a little AS3 class that encapsulates all the functionality.
Here is the usage (assuming an FLVPlayback component called: flvPlayback);
using edu.dts.video.AkamaiPlayer;
var akamaiPlayer:AkamaiPlayer = new AkamaiPlayer(flvPlayback);
akamaiPlayer.playStream("http://edgeboss.net/xxxxx.flv");
That's it. The full source code is below:
package edu.dts.video
{
import flash.display.MovieClip;
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.Timer;
import fl.video.FLVPlayback;
import fl.video.VideoEvent;
public class AkamaiPlayer extends EventDispatcher
{
private var _player:FLVPlayback;
private var _protocols_array:Array = [
{protocol:"rtmp", port:1935},
{protocol:"rtmp", port:80}
];
private var _connections_array:Array = new Array();
private var _duration:Number = 0;
private var _connectionIndex:Number = 0;
private var _connectTimeout = null;
private var _akamaiUrl:String = "";
private var _akamaiConn:String = "";
private var _connTimeout = 10000;
private var _streamXml:XML;
private var _timer:Timer;
public var connectionFailure:Function;
public function AkamaiPlayer(player:FLVPlayback)
{
_player = player;
_player.addEventListener(VideoEvent.READY, playerReady);
}
public function playStatic(flvUrl:String) {
trace("AkaimiPlayer playing " + flvUrl);
_player.play(flvUrl);
}
public function playStream(akamaiUrl:String) {
trace("AkaimiPlayer playing " + akamaiUrl);
// check for XML version (xmlvers)
if (akamaiUrl.indexOf("?") == -1) {
akamaiUrl += "&xmlvers=2";
}
else
{
if (akamaiUrl.indexOf("xmlvers=2") == -1) {
akamaiUrl += "&xmlvers=2";
}
}
_akamaiUrl = akamaiUrl;
_akamaiConn = "";
if (_player.playing)
_player.stop();
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, loadComplete);
xmlLoader.load(new URLRequest(_akamaiUrl));
}
private function loadComplete(event:Event):void {
trace("FLV XML is Loaded");
// get XML data
_streamXml = new XML(event.currentTarget.data);
// clear out existing data
_connectionIndex = 0;
_connections_array = new Array();
// find //
var entries:XMLList = _streamXml.stream.entry;
var item_xml:XML;
// loop through the array of matching XMLNodes and remap the child nodes into an tempObject
for each (item_xml in entries) {
var tempObj:Object = new Object();
var node:XML;
for each (node in item_xml.children()) {
tempObj[node.localName()] = node.text();
}
// create connection string array entries
for ( var i = 0; i < _protocols_array.length; i++ ) {
var connString:String =
_protocols_array[i].protocol + "://" +
tempObj["serverName"] + ":" + _protocols_array[i].port + "/" +
tempObj["appName"]+ "/" + tempObj["streamName"];
_connections_array.push( connString );
trace("added: " + connString);
}
}
_timer = new Timer(_connTimeout);
_timer.addEventListener("timer", timerHandler);
_timer.start();
tryNextConnection();
}
private function tryNextConnection():void {
var connString:String = _connections_array[_connectionIndex];
if (_connectionIndex == _connections_array.length ) {
// make sure to reset to last connection
connString = _connections_array[_connectionIndex-1];
_timer.stop();
if (connectionFailure != null)
connectionFailure();
trace("tried all protocols with no luck");
return;
}
// just in case it happens to start playing from another source
if (_player.playing)
return;
trace("connecting to " + (_connectionIndex+1).toString() + " of " + (_connections_array.length).toString() + ": " + connString + " ; count: " + _timer.currentCount.toString());
_player.autoPlay = true;
_player.play(connString);
// iterate the connection so that if it fails, we go to the next one
_connectionIndex++;
}
private function timerHandler(event:TimerEvent):void {
tryNextConnection();
}
private function stopConnectionAttempts():void {
_timer.stop();
}
private function playerReady(event:VideoEvent):void {
// successful play
stopConnectionAttempts();
}
}
}