Jump to content
GreenSock

HyperNerd

VideoLoader & F4V Cue Points

Recommended Posts

Hello again,

 

I'm new to LoaderMax/VideoLoader, but I'm making decent headway and I LOVE using this over NetStream.

 

The next mountain I'm trying to pass is understanding how to properly use embedded cue points. I have an F4V with embedded cue points and what I would like to do is when the video is paused (onPause function), the actionscript would load a specific swf (addChild) based on the current cue point.

 

So far I only have the cue point listener succesfully tracing back, even if onPause isn't activated. Is that normal since it's just a trace? Furthermore, how would this properly be coded to load a swf based on current cue point ONLY when onPause is called?

 

I feel I am close, yet so far... Any help is graciously appriciated!

 

function onPause(e:MouseEvent):void
 {
TweenLite.to(mainVideo, .6, {volume:0, onComplete: soundFadeComplete});
  mainVideo.addEventListener(VideoLoader.VIDEO_CUE_POINT, cuePointHandler);
 }

 function cuePointHandler(event:LoaderEvent):void
 {
     trace("hit cue point " + event.data.name+"target:"+event.target);
//How do I load something here based on the current cue point?
    }

 function soundFadeComplete():void
 {
  mainVideo.pauseVideo();
 }

Link to comment
Share on other sites

The one thing I would change with your code is this:

assign event listener outside of the onPause() function. You want the cue points to be tracked while the video is playing. don't wait until it is paused to start listening like so:

mainVideo.addEventListener(VideoLoader.VIDEO_CUE_POINT, cuePointHandler);

function onPause(e:MouseEvent):void
 {
TweenLite.to(mainVideo, .6, {volume:0, onComplete: soundFadeComplete});
 }

 

 

 

Here is some sample code that will allow you to toggle the paused state of an f4v every time you click on it. Every time a cue point is encountered its name is stored in the previousCuePointFired variable. When the movie is paused it will trace out the name of the most recently encountered cue point.

 

 

import com.greensock.*;
import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import flash.events.VideoEvent;
import flash.events.MouseEvent;

//create a var to track the name of each cuePoint as it is fired
var previousCuePointFired:String;

var cuePoints:Array = [];

//change the name/url of the video that is loaded

var vid:VideoLoader = new VideoLoader("cuepoints.f4v",{container:this,onInit:getAllCuePoints});
vid.addEventListener(VideoLoader.VIDEO_CUE_POINT, onCue);

//add 'click to toggle pause' feature to video
vid.content.addEventListener(MouseEvent.CLICK, togglePaused);

function togglePaused(e:MouseEvent):void{
//switch the paused state of the video
vid.videoPaused = !vid.videoPaused;
if(vid.videoPaused){
trace("time to load a swf!");
trace("previousCuePointFired = " + previousCuePointFired);

//add swf loading code
}
}



function onCue(e:LoaderEvent):void {
trace("cuepoint fired: " + e.data.name);
//store your cue point name
previousCuePointFired = e.data.name;
}

function getAllCuePoints(e:LoaderEvent) {

trace(" *** Embedded CuePoint Data *** ");

//grab the array of cuePoint objects from the VideoLoader's metadata
if(vid.metaData.cuePoint){
cuePoints = vid.metaData.cuePoints;
trace("\n# of cuePoints = " + cuePoints.length);
for (var i:int = 0; i < cuePoints.length; i++) {
trace(cuePoints[i].name + " : " + cuePoints[i].time + " : " + vid.getCuePointTime(cuePoints[i].name));
}
trace("\n ***  *** \n");
}
}

vid.load();

 

You can use the value stored in previousCuePointFired to then load your swf.

To test just paste this code into a blank fla that has access to the greensock classes and your f4v.

Link to comment
Share on other sites

Thank you!

 

I'm running into a few issues:

 

If I try to import flash.events.VideoEvent;, I get error "Definition flash.events:VideoEvent could not be found". I am using this within the Gaia Framework, so not sure if that is causing a problem.

 

As for one button with the toggle pause states, I do need the two different buttons as you see it with pauseVideo/playVideo because there are other elements being shown/hidden based on these. I'm assuming I can still work with what your code within the onPause function?

 

In the end, I'm receiving a slew of errors:

Access of undefined property previousCuePointFired.

Access of undefined property vid.

Access of undefined property getAllCuePoints.

 

I see the potential here and I hope to keep understanding!

Link to comment
Share on other sites

it looks like you only copied a portion of the code.

attached is a working CS5 fla with f4v (use your own greensock classes)

 

And yes, you can certainly use independent buttons for play and pause. This file is provided just to illustrate the basic concepts of accessing a the most recent cuepoint when the video enters its paused state.

getRecentCuePoint.zip

Link to comment
Share on other sites

Thanks, Carl.

 

I have downloaded and opened getRecentCuePoint.fla. However, I'm still getting a compiler error for flash.event.Video.Event:

1172: Definition flash.events:VideoEvent could not be found

 

 

**UPDATE**

I just commented out import flash.event.Video.Event and it's working... I can see cue point traces and stored cues! Very cool. Now to figure out how to merge this with my project. Hopefully I don't have too many questions over the weekend :)

 

Thank you!

Link to comment
Share on other sites

Cool. Glad to hear you have it working. Just so you know I'll be out of town for Sat and Sun so don't worry if I don't get back to you til Monday.

Link to comment
Share on other sites

Hi Carl (and anyone who can help),

 

I've spent a good chunk of the weekend understanding this code and attempting to implement it. After trying various combinations of code, I can't seem to understand how to call an IF statement that loads a SWF based on last cuepoint name. Please see my code below - I've left it mostly intact with a new LoaderEvent:

 

function initCue(e:LoaderEvent):void {
if (event.target.metaData=="river") {
trace("LOAD RIVER SWF");
}
if (event.target.metaData=="vegas") {
trace("LOAD VEGAS SWF");
}
}

 

I see how the cuepoints are being traced back as they are reached, but how do I code: "when paused, check previous cuepoint - IF it is named this, load this SWF - IF it is named this other, load this instead, etc...

 

It seems that you can't call a LoaderEvent from a function as I am trying to do from TogglePause event ( initCUE(); )? I keep getting error: 1136: Incorrect number of arguments. Expected 1 No matter how I try to code it. Feels so close, but can't figure out this piece..

 

import com.greensock.*;
import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import flash.events.MouseEvent;

//create a var to track the name of each cuePoint as it is fired
var previousCuePointFired:String;
var cuePoints:Array = [];
var vid:VideoLoader = new VideoLoader("cuepoints.f4v",{container:this,onInit:getAllCuePoints});
vid.addEventListener(VideoLoader.VIDEO_CUE_POINT, onCue);

//add 'click to toggle pause' feature to video
vid.content.addEventListener(MouseEvent.CLICK, togglePaused);

function togglePaused(e:MouseEvent):void{
//switch the paused state of the video
vid.videoPaused = !vid.videoPaused;
if(vid.videoPaused){
trace("time to load a swf!");
trace("previousCuePointFired = " + previousCuePointFired);
initCue(); //can't call to LoaderEvent like this???
}
}
function initCue(e:LoaderEvent):void {
if (e.data.name=="river") {
trace("LOAD RIVER SWF");
}
if (e.data.name=="vegas") {
trace("LOAD VEGAS SWF");
}
}
function onCue(e:LoaderEvent):void {
trace("cuepoint fired: " + e.data.name);
//store your cue point name
previousCuePointFired = e.data.name;
}

function getAllCuePoints(e:LoaderEvent) {

trace(" *** Embedded CuePoint Data *** ");
//grab the array of cuePoint objects from the VideoLoader's metadata
if(vid.metaData.cuePoint){
cuePoints = vid.metaData.cuePoints;
trace("\n# of cuePoints = " + cuePoints.length);
for (var i:int = 0; i < cuePoints.length; i++) {
trace(cuePoints[i].name + " : " + cuePoints[i].time + " : " + vid.getCuePointTime(cuePoints[i].name));
}
trace("\n ***  *** \n");
}
}

vid.load();

Link to comment
Share on other sites

Hi,

 

Assuming you are able to trace out the previousCuePointFired value when you pause the video, you shouldn't need to do anything with LoaderEvent.

 

If I am understanding you correctly your code can be revised as follows:

 

 

function togglePaused(e:MouseEvent):void{
//switch the paused state of the video
vid.videoPaused = !vid.videoPaused;
if(vid.videoPaused){
trace("time to load a swf!");
trace("previousCuePointFired = " + previousCuePointFired);
initCue(); //can't call to LoaderEvent like this???
}
}
function initCue():void {
if (previousCuePointFired=="river") {
trace("LOAD RIVER SWF");
}
if (previousCuePointFired=="vegas") {
trace("LOAD VEGAS SWF");
}
}

Link to comment
Share on other sites

Amazing, this is it! I was trying to use e.data.name again, but that was already set to previousCuePointFired = e.data.name; , if I am understanding correctly?

 

I also noticed that I can bypass setting up a new function initCue(); by simply nesting my IF/THEN swf load statements within the IF vid.videoPaused statement:

 

function togglePaused(e:MouseEvent):void{
//switch the paused state of the video
vid.videoPaused = !vid.videoPaused;
if(vid.videoPaused){
trace("time to load a swf!");
trace("previousCuePointFired = " + previousCuePointFired);

 if (previousCuePointFired=="river")
 {
    trace("LOAD RIVER SWF");
 }
 }
}

 

Is it best to avoid nesting them like this, or does that make sense to keep things concise?

 

Thank you again SO much! This has all been very helpful :mrgreen:

Link to comment
Share on other sites

Glad to hear you are making progress. Sure, you can nest the code like that. Some folks prefer though to have their functions focused on a singular task.

 

Right now the swf loading logic is locked into a mouse event. Suppose for whatever reason you want to load a swf once a Timer reaches 60 seconds? Well you would have to right that logic out again somewhere else. Right now you are most likely not going to have any problems.

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.
×