JohnnyNL Posted July 24, 2014 Share Posted July 24, 2014 Hello everyone, I am new to Loadermax, and I recently started working on a new project that has multiple videos that need to be played on different pages, but at the same time keeping the videos in the background buffering so they can be played easily without waiting for them to buffer. For example, I have 3 pages, on page 1, page 2 and page 3, each individual page will have a different video coming from the same XML file. Right now I have all the videos playing in the same swf and they play as a playlist. here is the code. Any guidance on how to get this working would be greatly appreciated. This is also the link to the video player http://outermedia.ca/videoplayer/godaddy/ XML: <?xml version="1.0" encoding="iso-8859-1"?> <videoList> <LoaderMax name="videoListLoader" load="false" maxConnections="1" prependURLs="http://outermedia.ca/"> <VideoLoader name="videoID0" url="videoplayer/INTRO-1.flv" height ="406" width="720" scaleMode="proportionalInside" centerRegistration="true" alpha="0" autoPlay="false" /> <VideoLoader name="videoID1" url="videoplayer/DB02_C01_T01.flv" height ="406" width="720" scaleMode="proportionalInside" centerRegistration="true" alpha="0" autoPlay="false" /> <VideoLoader name="videoID2" url="videoplayer/DB03_C01_T02.flv" height ="406" width="720" scaleMode="proportionalInside" centerRegistration="true" alpha="0" autoPlay="false" /> <VideoLoader name="videoID3" url="videoplayer/DB_Animation_Ep 01_VBR2pass.flv" height ="406" width="720" scaleMode="proportionalInside" centerRegistration="true" alpha="0" autoPlay="false" /> </LoaderMax> </videoList> Main Class: 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; //Check if we are in PlayAll Mode (true) private var smoothing : Boolean = true; //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]); initUI(); var xmlLoader:XMLLoader = new XMLLoader("xml/videoList.xml", {name:"videoList", onComplete:xmlHandler}); xmlLoader.load(); } 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) queue.load(); //show the first video showVideo(_videos[1]); } //---- 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, preloader_mc], 0, {autoAlpha:1}); } private function activateUI():void { //add various listeners addListeners([controlUI_mc, videoContainer_mc], MouseEvent.ROLL_OVER, toggleControlUI); addListeners([controlUI_mc, videoContainer_mc], MouseEvent.ROLL_OUT, toggleControlUI); addListeners([controlUI_mc.playPauseButton_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, controlUI_mc.back_mc, controlUI_mc.next_mc, controlUI_mc.audio_mc, controlUI_mc.scrubber_mc]; var i:int = controls.length; while (i--) { controls.buttonMode = true; controls.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) { return; } //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) { togglePlayPause(); } //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. _currentVideo.prioritize(true); //play() the preloader and fade its alpha up. preloader_mc.play(); 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 videoContainer_mc.addChild(_currentVideo.content); //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 refreshTotalTime(); //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 updateDownloadProgress(); updatePlayProgress(); } private function bufferFullHandler(event:LoaderEvent):void { TweenMax.to(preloader_mc, 0.3, {autoAlpha:0, onComplete:preloader_mc.stop}); } private function rewindAndPause(video:VideoLoader):void { video.pauseVideo(); //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. video.gotoVideoTime(0); } 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; } showVideo(_videos[next]); } private function previousVideo(event:Event):void { var prev:int = _videos.indexOf(_currentVideo) - 1; if (prev < 0) { prev = _videos.length - 1; } showVideo(_videos[prev]); } //---- 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, {autoAlpha:1}); } else { TweenMax.to(controlUI_mc, 0, {autoAlpha:1}); } } private function togglePlayPause(event:MouseEvent=null):void { _currentVideo.videoPaused = ! _currentVideo.videoPaused; if (_currentVideo.videoPaused) { controlUI_mc.playPauseButton_mc.gotoAndStop("paused"); TweenMax.to(videoContainer_mc, 0, {blurFilter:{blurX:0, blurY:0}, colorMatrixFilter:{brightness:0}}); } else { controlUI_mc.playPauseButton_mc.gotoAndStop("playing"); TweenMax.to(videoContainer_mc, 0, {blurFilter:{blurX:0, blurY:0, remove:true}, colorMatrixFilter:{brightness:0, remove:true}}); } } private function toggleAudio(event:MouseEvent):void { _silentMode = !_silentMode; if (_silentMode) { _currentVideo.volume = 0; controlUI_mc.audio_mc.label.gotoAndStop("off"); } else { _currentVideo.volume = 1; controlUI_mc.audio_mc.label.gotoAndStop("on"); } } //---- 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); controlUI_mc.scrubber_mc.stopDrag(); _currentVideo.videoPaused = _preScrubPaused; } //---- UTILITY FUNCTIONS ------------------------------------------------------------------------------------- private function addListeners(objects:Array, type:String, func:Function):void { var i:int = objects.length; while (i--) { objects.addEventListener(type, func); } } private function force2Digits(value:Number):String { return (value < 10) ? "0" + String(value) : String(value); } } } Link to comment Share on other sites More sharing options...
Carl Posted July 24, 2014 Share Posted July 24, 2014 Hi and welcome to the GreenSock forums, Glad to hear you are having success with LoaderMax. I can't really read through 300 lines of code and understand how it all works well enough to make suggestions on how to add new features. From your explanation it seems like you just need helping referencing the proper VideoLoader when you need it. In your XML you already give each loader a name which you can then pass into LoaderMax.getLoader() method. for instance to get a reference to the first video use LoaderMax.getLoader("videoID0"); In your app, you probably want to keep track of an index representing which "page" you are on (again I didn't read your code carefully) so that you can dynamically target the VideoLoaders. var pageIndex = 4; LoaderMax.getLoader("videoID" + pageIndex); Hope this helps. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now