Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
vizint

Syncronizing Video, SWF's and Cuepoints with LoaderMax

Recommended Posts

I'm porting an existing flash framework for an online course that previously had all of the assets hard coded in AS3 over to LoaderMax.

 

I'm planning to externalize all references to the media assets (video, swf) along with course settings to a single XML and load with LoaderMax. The XML file also contains cuepoints for each node that trigger timeline labels using TimeLineMax when a videocuepoint is reached. I've done some testing using addASCuePoint with VideoLoader.

 

Looking for suggestions on the structure of the XML so that it best supports the LoaderMax platform. Is it better to add the SWF reference as an inline attribute with the video parameters or as a node - allowing it to have its own parameters?

 

Here is the XML I have so far:

 

<videoList>
<coursename>Course 1</coursename>
<introAnim>intro</introAnim>
<settingAutoPlay>1</settingAutoPlay>
<settingLMS>1</settingLMS>

<LoaderMax name="videoListLoader" maxConnections="1" prependURLs="assets/">

	<VideoLoader name="segment1" url="video1.mp4" height ="370" width="278" scaleMode="none" centerRegistration="true" alpha="0" autoPlay="false" volume=".5" swf="swf1"/>
		<swffile>swf1</swffile>
		<cuepoints>
			<cuepoint>
				<name>introduction</name>
				<time>0</time>
				<label>Introduction XX</label>
				<caption>intro caption</caption>
			</cuepoint>
			<cuepoint>
				<name>idea_1</name>
				<time>3.042</time>
				<label>Idea 1</label>
				<caption></caption>
			</cuepoint>
			<cuepoint>
				<name>closing</name>
				<time>12.601</time>
				<label>Closing</label>
				<caption>Closing caption</caption>
			</cuepoint>
		</cuepoints>
	<VideoLoader name="segment2" url="video2.mp4" height ="370" width="278" scaleMode="none" centerRegistration="true" alpha="0" autoPlay="false" swf="swf2"/>
	<swffile>swf2</swffile>
	<cuepoints>
	</cuepoints>

</LoaderMax>
</videoList>

 

How are the Video & SWF files then loaded simultaneously with LoaderMax?

Would it be better to load each video/swf/cuepoint node on demand (using getChildAt())?

There is roughly 50mb of combined video files and swf's in the course with each segment around 2-3mb.

 

I'm really excited about the elegant combination of LoaderMax & Tween/TimelineMax, but I'm having difficulty putting it all together.

Link to post
Share on other sites

My solution has 2 major changes

 

 

 

1: add your cuePoint data to the VideoLoader node. Right now your VideoLoader node is self-closing. You can do something like

 

<VideoLoader name="segment1" url="video1.mp4" height ="370" width="278" scaleMode="none" centerRegistration="true" alpha="0" autoPlay="false" volume=".5" swf="swf1">
	  //remove <swfFIle> node
	    <cuepoints>
		    <cuepoint>
			    <name>introduction</name>
			    <time>0</time>
			    <label>Introduction XX</label>
			    <caption>intro caption</caption>
		    </cuepoint>
		    <cuepoint>
			    <name>idea_1</name>
			    <time>3.042</time>
			    <label>Idea 1</label>
			    <caption></caption>
		    </cuepoint>
		    <cuepoint>
			    <name>closing</name>
			    <time>12.601</time>
			    <label>Closing</label>
			    <caption>Closing caption</caption>
		    </cuepoint>
	    </cuepoints>
//close VideoLoader node
</videoLoader>

 

all the cuePoint data is now part of the VideoLoader's rawXML property. You can read the 3rd code sample and description in the VideoLoader docs on how to target the rawXML:

http://www.greensock.com/as/docs/tween/com/greensock/loading/XMLLoader.html

 

2: Right now you only have <swfFile> nodes. LoaderMax isn't going to know what to do with those so you will have to parse them out of the xml and create your own SWFLoaders. I would suggest combining each set of VideoLoaders and SWFLoaders in their own LoaderMax so that they can be loaded together or atleast be grouped together logically. like:

 

<LoaderMax name="segment1Files" prependURLs="/assets" load="false">
<VideoLoader name="segment1" url="video1.mp4" height ="370" width="278" scaleMode="none" centerRegistration="true" alpha="0" autoPlay="false" volume=".5" swf="swf1">
	    <cuepoints>
		    <cuepoint>
			    <name>introduction</name>
			    <time>0</time>
			    <label>Introduction XX</label>
			    <caption>intro caption</caption>
		    </cuepoint>
	    </cuepoints>
</videoLoader>
<SWFLoader name="segment1swf" url="1.swf">
</LoaderMax>

 

You would have multiple LoaderMax nodes in your xml. Notice that I set the load attribute to false. I would recommend loading the xml up front and then loading each LoaderMax when requested by the user. You certainly can try loading everything at once, it could work fine.

Link to post
Share on other sites

Carl-

 

Thanks for your detailed response...

 

I've updated the xml and set up an XML loader and handler - it seems to be loading properly.

 

<videoList>
   <coursename>Course 1</coursename>
   <introAnim>intro</introAnim>
   <settingAutoPlay>1</settingAutoPlay>
   <settingLMS>1</settingLMS>

   <LoaderMax name="segment1Files" maxConnections="1" prependURLs="assets/" load="false">

       <VideoLoader name="segment1" url="segment1.mp4" height ="370" width="278" scaleMode="none" centerRegistration="true" alpha="1" autoPlay="false" volume=".1">

           <cuepoints>
               <cuepoint>
                   <name>introduction</name>
                   <time>0</time>
                   <label>Introduction 1</label>
                   <caption>intro caption</caption>
               </cuepoint>
               <cuepoint>
                   <name>closing</name>
                   <time>12.601</time>
                   <label>Closing</label>
                   <caption>Closing caption</caption>
               </cuepoint>
           </cuepoints>

       </VideoLoader>

           <SWFLoader name="segment1swf" url="segment1.swf"/>

   </LoaderMax>     

       <LoaderMax name="segment2Files" maxConnections="1" prependURLs="assets/" load="false">

       <VideoLoader name="segment2" url="segment2.mp4" height ="370" width="278" scaleMode="none" centerRegistration="true" alpha="0" autoPlay="false" volume=".5">

           <cuepoints>
               <cuepoint>
                   <name>introduction2</name>
                   <time>0</time>
                   <label>Introduction 2</label>
                   <caption>intro caption</caption>
               </cuepoint>
               <cuepoint>
                   <name>closing2</name>
                   <time>12.601</time>
                   <label>Closing</label>
                   <caption>Closing caption</caption>
               </cuepoint>
           </cuepoints>

       </VideoLoader>

           <SWFLoader name="segment2swf" url="segment2.swf"/>

   </LoaderMax>

</videoList>

 

I've been able to target the VideoLoader and SWFLoader using attribute names.

 

_xml = event.target.content;        
trace("loaderMax0 name is: " +_xml.LoaderMax[0].@name);
trace("loaderMax1 name is: " +_xml.LoaderMax[1].@name);
trace("loaderMax0 Video name is: " +_xml.LoaderMax[0].VideoLoader.@name);
trace("loaderMax0 SWF name is: " +_xml.LoaderMax[0].SWFLoader.@name);

 

 

How do I call the VideoLoader and SWF loaders on demand? Should I create a VideoLoader/SWFLoader for each segment (node) or do I just replace the reference to the content and parameters?

 

is there a cleaner way to reference each VideoLoader/SWF loader?

 

var videoloader:VideoLoader = new VideoLoader("assets/"+_xml.LoaderMax[currentSegment].VideoLoader.@url, {name:"video", volume: .8, container:this, x:50, y:50, alpha:1});
videoloader.load();

var swfloader:SWFLoader = new SWFLoader("assets/"+_xml.LoaderMax[currentSegment].SWFLoader.@url, {name:"swf", container:this, x:750, y:20, onInit:initHandler, estimatedBytes:9500});
swfloader.load();

 

Should I unload the current loader pair before loading the next/previous node?

 

Thanks again for all your help!

Link to post
Share on other sites

Great progress you have made.

 

Once the XML is loaded all of the sub loaders should have been automatically created. Its just a matter of telling them when to load. you should be able to do

 

//load segment2 video
LoaderMax.getLoader("segment2").load();
addChild(LoaderMax.getContent("segment2"))

Link to post
Share on other sites

Carl-

 

I've made some more progress, VideoLoader & SWFLoader are loading simultaneously from a series of Loader Max nodes:

 

//VideoLoader
LoaderMax.getLoader(_xml.LoaderMax[currentSegment].VideoLoader.@name).load();
addChild(LoaderMax.getContent(_xml.LoaderMax[currentSegment].VideoLoader.@name));
//SWFLoader
LoaderMax.getLoader(_xml.LoaderMax[currentSegment].SWFLoader.@name).load();
addChild(LoaderMax.getContent(_xml.LoaderMax[currentSegment].SWFLoader.@name));

Using this approach, how do I assign the parameters to the loader? It picks up values, like position x= "400" y = "240" just fine from the XML file, but since the video and swf's always have the same position, it would be nice to set this once.

 

I've set up Next/Previous buttons which walk through the nodes of the course. This leads to multiple video/swf files playing at the same time. Clearly I need to unload the "last" content before displaying the "current" content.

 

//in xmlHandler
numSegments = _xml.LoaderMax.length();

private function controlNextPrev():void
{

if (currentSegment == 0){
   trace("first Segment");
   //video
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment-1].VideoLoader.@name).unload();
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment].VideoLoader.@name).load();
   addChild(LoaderMax.getContent(_xml.LoaderMax[currentSegment].VideoLoader.@name))
   //swf
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment].SWFLoader.@name).load();
   addChild(LoaderMax.getContent(_xml.LoaderMax[currentSegment].SWFLoader.@name))


}
else if (currentSegment < (numSegments-1)){            
   trace("mid segments");
   //video
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment-1].VideoLoader.@name).unload();
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment].VideoLoader.@name).load();
   addChild(LoaderMax.getContent(_xml.LoaderMax[currentSegment].VideoLoader.@name))
   //swf
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment].SWFLoader.@name).load();
   addChild(LoaderMax.getContent(_xml.LoaderMax[currentSegment].SWFLoader.@name))

}

else if (currentSegment == (numSegments-1)){

   trace("Last Segment");

   //video                
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment-1].VideoLoader.@name).unload();
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment].VideoLoader.@name).load();
   addChild(LoaderMax.getContent(_xml.LoaderMax[currentSegment].VideoLoader.@name))
   //swf                
   LoaderMax.getLoader(_xml.LoaderMax[currentSegment].SWFLoader.@name).load();
   addChild(LoaderMax.getContent(_xml.LoaderMax[currentSegment].SWFLoader.@name))

}

 

How do I refer to the current VideoLoader as a variable that can be exchanged and unloaded?

 

private var _currentVid:VideoLoader;

_currentVid = LoaderMax.getLoader(_xml.LoaderMax[currentSegment].VideoLoader.@name).load();
_currentVid.playVideo();

 

plays audio and throws an error

TypeError: Error #1009: Cannot access a property or method of a null object reference.

 

As always - thanks for your kind and detailed feedback.

Link to post
Share on other sites

as for using a var to reference the loader you are on the right track. when you assign the var a value, leave the load() part off:

 

private var _currentVid:VideoLoader;
_currentVid = LoaderMax.getLoader(_xml.LoaderMax[currentSegment].VideoLoader.@name);
_currentVid.load();
_currentVid.playVideo();

 

you can then do _currentVid.unload() before you load the next one.

 

as for assigning the same x and y values. you could also do:

 

_currentVid.content. x= 400
_currentVid.content.y = 240

Link to post
Share on other sites
  • 2 weeks later...

I've made good progress on this project - now working to build a menu with the button labels coming from each loadermax segment in the XML.

 

I'd like to derive the segment names from each loaderMax node:

 

trace("Segment Name is: "+LoaderMax.getLoader(_xml.LoaderMax[currentSegment].@ name));

 

but this returns "LoaderMax 'Segment Name 1'"

 

Here is the XML:

<courseList>
   <courseName>Name of Course</courseName>
   <LoaderMax name="Segment Name 1" maxConnections="2" prependURLs="assets/" load="false">

       <VideoLoader name="segment1" url="segment_1.mp4"  scaleMode="none"  autoPlay="true" volume=".9" autoAdvance = "false">

           <cuepoints>
               <cuepoint>
                   <name>introduction</name>
                   <time>0.01</time>
               </cuepoint>
           </cuepoints>

       </VideoLoader>

           <SWFLoader name="segment1" url="segment1.swf" type="timeline" nextAction = "next"/>

   </LoaderMax>
   <LoaderMax name="Segment Name 2" maxConnections="2" prependURLs="assets/" load="false">

       <VideoLoader name="segment2" url="segment2.mp4"  scaleMode="none"  autoPlay="true" volume=".9" autoAdvance = "false">

           <cuepoints>
               <cuepoint>
                   <name>introduction</name>
                   <time>0.01</time>
               </cuepoint>
           </cuepoints>

       </VideoLoader>

           <SWFLoader name="segment2" url="segment2.swf" type="code" nextAction = "auto"/>

   </LoaderMax>

</courseList>

 

How can I derive the name (or other attributes) from the LoaderMax loader?

 

Thanks again for all your help!

Link to post
Share on other sites

all of the xml attributes for each loader are stored in a "vars" object for each loader.

 

it appear's you can already dynamically generate the name atribute of each LoaderMax node with:

 


_xml.LoaderMax[currentSegment].@name

 

So you should be able to do:


var currentName:String = _xml.LoaderMax[currentSegment].@name
trace(LoaderMax.getLoader( currentName ).vars.name);

that is really redundant though as that means you are using the name of a loader to find its name.

 

but once you have found the Loader via it's name, you can get all the other attributes like:

 

trace(LoaderMax.getLoader( currentName ).vars.maxConnections);

 

 

Again, this is described in the docs (3rd code example)

http://www.greensock.../XMLLoader.html

 

-- also it appears you are using the same name for multiple assets which may become confusing. you have a VideoLoader and SWFLoader both with name="segment2"

 

also, since all of your LoaderMax nodes are named the same way you could also just do

 

var currentLoaderMax:LoaderMax = LoaderMax.getLoader("Segment Name " + currentSegment)

trace(currentLoader.vars.someAttribute);

perhaps I'm misunderstanding your question. hope some of this helps

Link to post
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.

×