Jump to content


Smart Action Script 3 Loader for SWF movies

Recommended Posts

HI Guys

First of all, thanks for your cool topics, LoaderMax is really Cool.

I was wondering, if GreenSock, has any smart AS3 "SWF" Loading and Play Back Player, just as the same version for its Video Player? (Play, pause, Next, Back, mute, progress / seek bar  and etc...)




Link to comment
Share on other sites

Hi Saaed, Welcome to the GreenSock forums.


The LoaderMax loaders only focus on loading assets and providing some handy playback-control methods where necessary. There aren't any VideoPlayer or SWFPlayer graphical user interfaces associated with the tools.  Perhaps for VideoLoader you are referring to some assets provided in one of the tutorials. 


For controlling a SWFLoader's swf, you can control it just like a MovieClip with play(), gotoAndPlay(), gotoAndStop(), stop() etc. 


To access the actual swf that is loaded just use the rawContent property of the SWFLoader

var mySwf:SWFLoader = new SWFLoader("animation.swf", {container:this})

//after loaded
var swf:MovieClip = mySwf.rawContent as MovieClip;

//control and get currentFrame

let us know if you need more help

Link to comment
Share on other sites

Dear Carl, here is the Class that manages to load multiple FLV movies:

package {
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;

	import com.greensock.TweenMax;
	import com.greensock.events.LoaderEvent;
	import com.greensock.loading.LoaderMax;
	import com.greensock.loading.XMLLoader;
	import com.greensock.loading.VideoLoader;
	import flash.geom.Rectangle;

	public class Main extends MovieClip {
		//an array containing the VideoLoaders in the order they should be played
		private var _videos:Array;
		//keeps track of the VideoLoader that is currently playing
		private var _currentVideo:VideoLoader;
		//If true, the audio has been muted
		private var _silentMode:Boolean;
		//tracks whether or not the video was paused when the user moused-down on the scrubber. We must pause for scrubbing, but this tells us whether or not to playVideo() when the user releases the mouse. 
		private var _preScrubPaused:Boolean;

		public function Main() {
			LoaderMax.activate([XMLLoader, VideoLoader]);
			var xmlLoader:XMLLoader = new XMLLoader("xml/videoList.xml", {name:"videoList", onComplete:xmlHandler});
		private function xmlHandler(event:LoaderEvent):void {
			//get the LoaderMax named "videoListLoaded" which was inside our XML
			var queue:LoaderMax = LoaderMax.getLoader("videoListLoader");
			//store the nested VideoLoaders in an array
			_videos = queue.getChildren();
			//start loading the queue of VideoLoaders (they will load in sequence)
			//show the first video
//---- UI (User Interface) FUNCTIONS ---------------------------------------------------------------------------

		private function initUI():void {
			//ignore mouse interaction with progressBar_mc so that clicks pass through to the loadingBar_mc whose listener handles skipping the video to that spot.
			controlUI_mc.progressBar_mc.mouseEnabled = false;
			//ignore mouse interaction with preloader_mc
			preloader_mc.mouseEnabled = false;
			//the "layer" blendMode makes the alpha fades cleaner (overlapping objects don't add alpha levels)
			controlUI_mc.blendMode = "layer";
			//set the progress and loading bars and the scrubber to the very beginning
			controlUI_mc.progressBar_mc.width = controlUI_mc.loadingBar_mc.width = 0;
			controlUI_mc.scrubber_mc.x = controlUI_mc.progressBar_mc.x;
			//initially hide the user interface - autoAlpha:0 sets alpha to 0 and visible to false.
			TweenMax.allTo([controlUI_mc, playPauseBigButton_mc, preloader_mc], 0, {autoAlpha:0});
		private function activateUI():void {
			//add various listeners
			addListeners([controlUI_mc, videoContainer_mc, playPauseBigButton_mc], MouseEvent.ROLL_OVER, toggleControlUI);
			addListeners([controlUI_mc, videoContainer_mc, playPauseBigButton_mc], MouseEvent.ROLL_OUT, toggleControlUI);
			addListeners([controlUI_mc.playPauseButton_mc, playPauseBigButton_mc, videoContainer_mc], MouseEvent.CLICK, togglePlayPause);
			addListeners([controlUI_mc.back_mc, controlUI_mc.audio_mc, controlUI_mc.next_mc], MouseEvent.ROLL_OVER, blackRollOverHandler);
			addListeners([controlUI_mc.back_mc, controlUI_mc.audio_mc, controlUI_mc.next_mc], MouseEvent.ROLL_OUT, blackRollOutHandler);
			controlUI_mc.audio_mc.addEventListener(MouseEvent.CLICK, toggleAudio);
			controlUI_mc.next_mc.addEventListener(MouseEvent.CLICK, nextVideo);
			controlUI_mc.back_mc.addEventListener(MouseEvent.CLICK, previousVideo);
			controlUI_mc.playPauseButton_mc.addEventListener(MouseEvent.ROLL_OVER, growPlayPause);
			controlUI_mc.playPauseButton_mc.addEventListener(MouseEvent.ROLL_OUT, shrinkPlayPause);
			controlUI_mc.scrubber_mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownScrubber);
			controlUI_mc.loadingBar_mc.addEventListener(MouseEvent.CLICK, scrubToMouse);
			//loop through various UI elements and set buttonMode to true and mouseChildren to false so that rollovers/outs work smoothly
			var controls:Array = [controlUI_mc.playPauseButton_mc, playPauseBigButton_mc, controlUI_mc.back_mc, controlUI_mc.next_mc, controlUI_mc.audio_mc, controlUI_mc.scrubber_mc];
			var i:int = controls.length;
			while (i--) {
				controls[i].buttonMode = true;
				controls[i].mouseChildren = false;
//---- NAVIGATION FUNCTIONS ---------------------------------------------------------------------------------
		private function showVideo(video:VideoLoader):void {
			//if the new video is the one that's currently showing, do nothing.
			if (video == _currentVideo) {
			//The first time through, the _currentVideo will be null. That's when we need to activate the user interface
			if (_currentVideo == null) {
				activateUI(); //don't activate the UI until the first video is ready. This avoids errors when _currentVideo is null.
			} else {
				//remove the event listeners from the _currentVideo (which is now the old one that will be replaced)
				_currentVideo.removeEventListener(LoaderEvent.PROGRESS, updateDownloadProgress);
				_currentVideo.removeEventListener(VideoLoader.VIDEO_COMPLETE, nextVideo);
				_currentVideo.removeEventListener(VideoLoader.PLAY_PROGRESS, updatePlayProgress);
				_currentVideo.removeEventListener(VideoLoader.VIDEO_BUFFER_FULL, bufferFullHandler);
				_currentVideo.removeEventListener(LoaderEvent.INIT, refreshTotalTime);
				//If the video is paused, we should togglePlayPause() so that the new video plays and the interface matches.
				if (_currentVideo.videoPaused) {
				//fade out the preloader and then stop() it. If the new video needs to display the preloader, that's okay because the fade-in tween we create later will overwrite this one.
				TweenMax.to(preloader_mc, 0.3, {autoAlpha:0, onComplete:preloader_mc.stop});
				//fade the current (old) video's alpha out. Remember the VideoLoader's "content" refers to the ContentDisplay Sprite we see on the screen.
				TweenMax.to(_currentVideo.content, 0.8, {autoAlpha:0});
				//fade the current (old) video's volume down to zero and then pause and rewind the video (it will be invisible by that time).
				TweenMax.to(_currentVideo, 0.8, {volume:0, onComplete:rewindAndPause, onCompleteParams:[_currentVideo]});

			//now swap the _currentLoader variable so it refers to the new video.
			_currentVideo = video;

			//listen for PROGRESS events so that we can update the loadingBar_mc's scaleX accordingly
			_currentVideo.addEventListener(LoaderEvent.PROGRESS, updateDownloadProgress);
			//listen for a VIDEO_COMPLETE event so that we can automatically advance to the next video.
			_currentVideo.addEventListener(VideoLoader.VIDEO_COMPLETE, nextVideo);
			//listen for PLAY_PROGRESS events so that we can update the progressBar_mc's scaleX accordingly
			_currentVideo.addEventListener(VideoLoader.PLAY_PROGRESS, updatePlayProgress);
			//if the video hasn't fully loaded yet and is still buffering, show the preloader
			if (_currentVideo.progress < 1 && _currentVideo.bufferProgress < 1) {
				//when the buffer fills, we'll fade out the preloader
				_currentVideo.addEventListener(VideoLoader.VIDEO_BUFFER_FULL, bufferFullHandler);
				//prioritizing the video ensures that it moves to the top of the LoaderMax gueue and any other loaders that were loading are canceled to maximize bandwidth available for the new video.
				//play() the preloader and fade its alpha up.
				TweenMax.to(preloader_mc, 0.3, {autoAlpha:1});
			//start playing the video from its beginning
			_currentVideo.gotoVideoTime(0, true);
			//always start with the volume at 0, and fade it up to 1 if necessary.
			_currentVideo.volume = 0;
			if (!_silentMode) {
				TweenMax.to(_currentVideo, 0.8, {volume:1});
			//when we addChild() the VideoLoader's content, it makes it rise to the top of the stacking order
			//fade the VideoLoader's content alpha in. Remember, the "content" refers to the ContentDisplay Sprite that we see on the stage.
			TweenMax.to(_currentVideo.content, 0.8, {autoAlpha:1});
			//update the total time display
			//if the VideoLoader hasn't received its metaData yet (which contains duration information), we should set up a listener so that the total time gets updated when the metaData is received.
			if (_currentVideo.metaData == null) {
				_currentVideo.addEventListener(LoaderEvent.INIT, refreshTotalTime);
			//update the progressBar_mc and loadingBar_mc
		private function bufferFullHandler(event:LoaderEvent):void {
			TweenMax.to(preloader_mc, 0.3, {autoAlpha:0, onComplete:preloader_mc.stop});
		private function rewindAndPause(video:VideoLoader):void {
			//rewind the video so that when we fade it in again later, it's already displaying the first frame and there's no delay skipping to it. 
		private function refreshTotalTime(event:LoaderEvent=null):void {
			var minutes:String = force2Digits(int(_currentVideo.duration / 60));
			var seconds:String = force2Digits(int(_currentVideo.duration % 60));
			controlUI_mc.totalTime_tf.text = minutes + ":" + seconds;
		private function nextVideo(event:Event):void {
			var next:int = _videos.indexOf(_currentVideo) + 1;
			if (next >= _videos.length) {
				next = 0;
		private function previousVideo(event:Event):void {
			var prev:int = _videos.indexOf(_currentVideo) - 1;
			if (prev < 0) {
				prev = _videos.length - 1;
//---- PROGRESS AND LOADING BAR FUNCTIONS -------------------------------------------------------------
		private function updateDownloadProgress(event:LoaderEvent=null):void {
			controlUI_mc.loadingBar_mc.scaleX = _currentVideo.progress;
		private function updatePlayProgress(event:LoaderEvent=null):void {
			var time:Number = _currentVideo.videoTime;
			var minutes:String = force2Digits(int(time / 60));
			var seconds:String = force2Digits(int(time % 60));
			controlUI_mc.currentTime_tf.text = minutes + ":" + seconds;
			controlUI_mc.progressBar_mc.scaleX = _currentVideo.playProgress;
			controlUI_mc.scrubber_mc.x = controlUI_mc.progressBar_mc.x + controlUI_mc.progressBar_mc.width;
//---- TOGGLE FUNCTIONS -------------------------------------------------------------------------------
		private function toggleControlUI(event:MouseEvent):void {
			if (videoContainer_mc.hitTestPoint(mouseX, mouseY)) {
				TweenMax.to(controlUI_mc, 0.3, {autoAlpha:1});
			} else {
				TweenMax.to(controlUI_mc, 0.3, {autoAlpha:0});
		private function togglePlayPause(event:MouseEvent=null):void {
			_currentVideo.videoPaused = ! _currentVideo.videoPaused;
			if (_currentVideo.videoPaused) {
				TweenMax.to(playPauseBigButton_mc, 0.3, {autoAlpha:1});
				TweenMax.to(videoContainer_mc, 0.3, {blurFilter:{blurX:6, blurY:6}, colorMatrixFilter:{brightness:0.5}});
			} else {
				TweenMax.to(playPauseBigButton_mc, 0.3, {autoAlpha:0});
				TweenMax.to(videoContainer_mc, 0.3, {blurFilter:{blurX:0, blurY:0, remove:true}, colorMatrixFilter:{brightness:1, remove:true}});
		private function toggleAudio(event:MouseEvent):void {
			_silentMode = !_silentMode;
			if (_silentMode) {
				_currentVideo.volume = 0;
			} else {
				_currentVideo.volume = 1;
//---- ROLLOVER/OUT HANDLERS ---------------------------------------------------------------------------------
		private function blackRollOverHandler(event:MouseEvent):void {
			TweenMax.to(event.target.label, 0.3, {tint:0xFFFFFF});
		private function blackRollOutHandler(event:MouseEvent):void {
			TweenMax.to(event.target.label, 0.3, {tint:null});
		private function growPlayPause(event:MouseEvent):void {
			TweenMax.to(event.target, 0.2, {scaleX:1.3, scaleY:1.3});
		private function shrinkPlayPause(event:MouseEvent):void {
			TweenMax.to(event.target, 0.2, {scaleX:1, scaleY:1});

//---- SCRUBBER FUNCTIONS ------------------------------------------------------------------------------------
		private function mouseDownScrubber(event:MouseEvent):void {
			_preScrubPaused = _currentVideo.videoPaused;
			_currentVideo.videoPaused = true;
			controlUI_mc.scrubber_mc.startDrag(false, new Rectangle(controlUI_mc.loadingBar_mc.x, controlUI_mc.loadingBar_mc.y, controlUI_mc.loadingBar_mc.width, 0));
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpScrubber);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, scrubToMouse);
		private function scrubToMouse(event:MouseEvent):void {
			controlUI_mc.progressBar_mc.width = controlUI_mc.mouseX - controlUI_mc.progressBar_mc.x;
			_currentVideo.playProgress = controlUI_mc.progressBar_mc.scaleX;
		private function mouseUpScrubber(event:MouseEvent):void {
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpScrubber);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, scrubToMouse);
			_currentVideo.videoPaused = _preScrubPaused;
//---- UTILITY FUNCTIONS -------------------------------------------------------------------------------------
		private function addListeners(objects:Array, type:String, func:Function):void {
			var i:int = objects.length;
			while (i--) {
				objects[i].addEventListener(type, func);
		private function force2Digits(value:Number):String {
			return (value < 10) ? "0" + String(value) : String(value);

And the Xml file, storing the information is as Below: 

<?xml version="1.0" encoding="iso-8859-1"?> 

	<LoaderMax name="videoListLoader" maxConnections="1" prependURLs="assets/">
		<VideoLoader name="videoID0" url="videoClip01.flv" height ="406" width="720" scaleMode="proportionalInside" centerRegistration="true" alpha="0" autoPlay="false" />
		<VideoLoader name="videoID1" url="videoClip02.mp4" height ="406" width="720" scaleMode="proportionalInside" centerRegistration="true" alpha="0" autoPlay="false" />
		<VideoLoader name="videoID2" url="videoClip03.flv" height ="406" width="720" scaleMode="proportionalInside" centerRegistration="true" alpha="0" autoPlay="false" />

So, what is the neccesarry changes, to change this loader to a swf Loader?

thanks in advance for your care Carl.


Link to comment
Share on other sites

Thank you for providing the code from the active tuts tutorial.

That tutorial is a wonderful resource for understanding many of the intricacies of LoaderMax, XMLLoader and VideoLoader.


I would recommend stepping back from a full-featured multi-video player and start by loading a single swf and controlling it with a UI. 


Once that is done you will be familiar with the various SWFLoader events, methods and properties and have an idea of how those methods, properties and events can be applied to a _currentSwf object.


Although SWFLoader and VideoLoader are similar (as they both extend LoaderItem) there is far too much code in that VideoLoader example that would have to be edited or removed for a multi-SWFLoader Player.  I would use that example as a general guide for loading and controlling multiple assets through a common interface, but I wouldn't attempt to edit it directly.


Unfortunately, the amount of code that needs to be changed is far too great to list  :|

For instance, none of the code relating to VIDEO_COMPLETE , PLAY_PROGRESS, VIDEO_BUFFER_FULL, bufferProgress, volume, gotoVideoTime(), videoTime, pauseVideo etc would apply to a SWFLoader.


Also, you will have to come up with totally new code to handle associating the swfs _currentFrame to a visualization in a progress bar, showing the time (minutes seconds) based on _currentFrame, and controlling sound to name a few. 


In short, its quite an undertaking but certainly possible. 

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

Hi Carl, I appreciate your Consern, and thanks for directing me to start my SWF navigator from very beginning. As a matter of fact, I want to LoaderMaize the script, and make it cool with its tips and tricks, therefore I will go step by step with you.

Actually,I have tried to write the code for my purpose, and i have used LoaderMax XML Loader for loading my assets information. on the other hand SWFLoader, for loading my swf movies.

I've added an event Listener to the next button, which increments a variable named "CurrentId" (Keeping the number of the swf file that is loaded and is playing now) and one other listener for Previous Button which does vice versa.

I have a public function named playSWF, which has to load the new file.

The problem is that, when PlaySWF is done, the previous SWF file which was loaded, is still palying,and the new file is played together wth the previous one.

The function is as below:

public function playSWF():void
            var url:String = _videos[CurrentID].url;
            var currentLoader = new SWFLoader(url,{container:videoContainer_mc,width:720,height:406,centerRegistration:true,autoPlay:true});


_Videos is defined as below:



// that is an array
private var _videos:Array;

//which is generated from the queue children:

private function xmlHandler(event:LoaderEvent):void
            var queue:LoaderMax = LoaderMax.getLoader("SwfListLoader");
            _videos = queue.getChildren();

How can I stop, unload and remove the listeners from the current swf file, and then load the new file in playSWF function?

This will be the 1st stage.


Link to comment
Share on other sites

you would need a global reference to currentLoader. Currently you are using

var currentLoader = new SWFLoader(url,{container:videoContainer_mc,width:720,height:406,centerRegistration:true,autoPlay:true});

inside a function. no other functions can access currentLoader.


I would declare the currentLoader var outside any functions so that all functions in your class can access it.

var currentLoader:SWFLoader;

public function playSWF():void
var url:String = _videos[CurrentID].url;

//get rid of previous loaded swf


currentLoader = new SWFLoader(url,{container:videoContainer_mc,width:720,height:406,centerRegistration:true,autoPlay:true});
Link to comment
Share on other sites

Thanks Carl.

It works fine now, and navigating well among the External SWF Movies.

Could you please give em a guide how to access the properties of the loaded SWF, like 1)totalFrames, 2)currnetFrame, 3)mute and unmute the Sound, 4) Pause it at a certain frame, and resume it from the same frame?

I tried these few lines of the code, but I receive the Error of the null Object (Error #1009).

public function playSWF():void
			var url:String = _videos[CurrentID].url;

			//get rid of previous loaded swf

			if (currentLoader)
				TweenMax.to(preloader_mc, 0.2, {autoAlpha:1});

			currentLoader = new SWFLoader(url,{container:videoContainer_mc,width:720,height:406,centerRegistration:true,autoPlay:true,onProgress:progressHandler,onComplete:completeHandler});
			TweenMax.to(preloader_mc, 0.3, {autoAlpha:0, onComplete:preloader_mc.stop});
			var CurrentSWF:MovieClip = currentLoader.rawContent as MovieClip;
			var minutes:String = force2Digits(int(CurrentSWF.totalFrames / 60));
			var seconds:String = force2Digits(int(CurrentSWF.totalFrames % 60));
			controlUI_mc.totalTime_tf.text = minutes + ":" + seconds;

private function force2Digits(value:Number):String
			return (value < 10) ? "0" + String(value) : String(value);

I will be looking forward, for your really useful guides.

This is the 2nd stag.

My very best Regards.

Link to comment
Share on other sites

Hi Saaed,


It appears the problem is that you are trying to get totalFrames BEFORE the swf is loaded.


I would use the completeHandler method for that. 

Once the file is loaded you should be able to use


currentLoader.rawContent.play(), .stop(), gotoAndStop() etc.


I see you are using a CurrentSWF variable which is good, but be careful about declaring it inside a function. Just like currentLoader, you want that to be accessible from other functions.



Link to comment
Share on other sites

Hi Carl, I cant really say, how much useful your comments are, I Just came to appreciate your Help.

My problem is totally solved and I now , have a External SWFLoader, with the features of, pausing, Playing, Next , Previous, Loading, PreLoading,Sound Controller and whatever you see on a videoLoader.

Anyone, needs such a loader, just let me know.

Carl, I want to add a multilevel menu to this loader, so that i can have a TOC (Table Of Contents) for My loader. Is there any tutorial for making a XML menu with GreenSock?

I will be looking forward for your Response.

Your Fan: Saeed :)


Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.