What started it was the need to add captioned video. The original version had the ability to show transcripts, but it was limited to a long string of text. Since the original was built two wonder events happened; the updated release of Captionate, and Flash’s FLVPlaybackCaptioned component. This new version of Captionate allows for the easy creation of the timed XML file that FLVPlaybackCapioned needs to work properly. Voilà! Easy caption creation.
This is not say that the player itself needed updating. The code was staring to show its age. Originally written in ActionScript 2.0, using older components, and with all of the code in one frame on the timeline, it was screaming for a rewrite! The biggest issue what that there where five different versions that used basically the same code, but a few different parameters. This was done because somebody wanted a smaller audio only version, or wanted to play larger videos. They just copied the old code, changed what they wanted to change, and published that.
This new version incorporates the new captioning abilities, while addressing the issues of the old player. First step was to update the code to ActionScript 3.0, along with the components, and then break it apart into classes. I then added feedback of the player’s status during loading. This biggest thing was the ability for the player to change into the different types, while using the same code for all the different ‘types’. This has already proved invaluable in updating and debugging. Then end product is a smooth running player that can incorporate all of the different variations that is the same file size of just one of the old players. Mission accomplished.
The backend also received a major rewrite. When creating a player, you use to have to create the HTML for the player on some types also. Now all you have to do is copy three lines into a new index file. This code references a dynamic back end written in PHP that will dynamically create the required HTML for the player. This allows me to update the player and the backend without having to worry about changing hundreds of html files to make it all work again. Another benefit has been the ability to add an HTML 5 component to the player.
Here is some code from the player’s main class:
// Public Functions *********************************************************** // start the player building process public function RenderPlayer(gotParams:Boolean):void { // lets start by showing the loading status this.loadStatus = new LoaderStatus(); // crate our loader this.loadStatus.rootParent = this.rootObject; // send it the root this.loadStatus.SetupLoadingTextbox(this.loaderTextX, this.loaderTextY); // create the text box for the loading text this.loadStatus.loadingIndicator = rootObject.loadingMarker; // send it the loading marker movie this.loadStatus.SkinColor(this.skinColor, this.skinAlpha); // send it the skin color and alpha (may change) this.loadStatus.ShowLoadingStatus('Starting Initialization', this.formatInfo.GetFormat()); // send it our initial message plus any formatting if(!gotParams) { this.loadStatus.RemoveLoader('Unable to load player parameters!'); return; } this.transcriptFromCaptionURL = this.baseURL + "transcript.php"; // this script will create a transcript from the captions this.baseURL = this.baseURL + this.playerFolder; // create the whole URL this.streamURL = this.streamURL + this.playerFolder; // create the whole streaming URL // create the urls for what to load this.xmlURL = this.baseURL + "courses/" + this.courseNumber.toUpperCase() + "/" + this.mediaDirName + "/mediaInfo.xml"; // Locates "mediaInfo.xml" this.transcriptURL = this.baseURL + "courses/" + this.courseNumber.toUpperCase() + "/" + this.mediaDirName + "/transcript.htm"; // Locates the transcript this.cssURL = this.baseURL + "courses/" + this.courseNumber.toUpperCase() + "/styles.css"; // Locates the CSS this.captionURL = this.baseURL + "courses/" + this.courseNumber.toUpperCase() + "/" + this.mediaDirName + "/captions.xml"; // XML for captions trace(this.xmlURL); trace(this.cssURL); trace(this.captionURL); // Start XML Load this.xmlObject = new XmlLoader(); // get the loader this.xmlObject.GetXML(xmlURL); this.xmlObject.loader.addEventListener(Event.COMPLETE, XmlComplete); this.xmlObject.loader.addEventListener(Event.OPEN, XmlStarted); this.xmlObject.loader.addEventListener(IOErrorEvent.IO_ERROR, XmlLoadError); //this.xmlObject.loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, XmlLoadError); } // Private Functions ****************************************************** // Load background image, if any private function LoadBackground():void { if(this.showBack) { // Start Background Loading Process this.bgURL = this.baseURL + "courses/" + this.courseNumber.toUpperCase() + "/" + this.bgImageN + "." + this.xmlData.bgFormat.toLowerCase(); // Locates the background image or animation this.bgObject = new BgLoader(); this.bgObject.GetBG(this.bgURL); this.bgObject.loader.contentLoaderInfo.addEventListener(Event.OPEN, BgStarted); this.bgObject.loader.contentLoaderInfo.addEventListener(Event.COMPLETE, BgLoaded); this.bgObject.loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, BgError); } else { this.LoadCSS(); } } // get the CSS for the player, if any private function LoadCSS():void { if(this.showCSS) { // Loading CSS this.cssObject = new CssLoader(); this.cssObject.GetCSS(cssURL); this.cssObject.loader.addEventListener(Event.OPEN, CssStarted); this.cssObject.loader.addEventListener(IOErrorEvent.IO_ERROR, CssError); this.cssObject.loader.addEventListener(Event.COMPLETE, CssLoaded); this.cssObject.loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, CssSecError); } else { // set the text areas if(this.setTextArea) { this.SetTextAreas(); } // start the loading the actual media this.LoadMedia(); } }