1

Hello everyone and anyone!

Ok... I have been banging my head against the wall with this issue for literally weeks, but I still cannot find an answer that has successfully resolved the issue.

I created an FLA and placed a FLV component with the instance name of videoPlay on the stage.

videoPlay is pathed to a streaming FLV with embedded event cue points. The cue points are numbered sequentially from narration1 to narration16.

I established a listener object:

     var videoPlayCuePointListener:Object = new Object();

The event listener for the cue points:

   videoPlayCuePointListener.cuePoint = function(eventObject:Object):Void{
   if(eventObject.info.name == "narration1"){_root.cc_box.cc_txt.htmlText = cueTxt1);}
   else if(eventObject.info.name == "narration2"){_root.cc_box.cc_txt.htmlText = cueTxt2);}
   etc, through narration16 }

and so on through narration16.

Then I attached the event listener to the FLV component on stage:

   videoPlay.addEventListener("cuePoint", videoPlayCuePointListener);

All of this works very well. As the FLV plays, each event cue point fires off the correct text to the cc_txt dynamic text box.

The issue I am having is that I cannot find the nearest cue point to the FLV playhead so that I can fire events when the user scrubs the timeline.

I have researched this as thoroughly as I possibly could before finally deciding to post the issue, but although the documentation and various postings regarding findNearestCuePoint discovered throughout the web have provided numerous examples, not a single one has been successful.

I have attempted to add a listener to videoPlay that creates an object (nearestCue) and gives nearestCue the value of videoPlay.findNearestCuePoint(videoPlay.playheadTime), then read out nearestCue's name, label, etc. No dice.

Nothing suggested in any posts I have reviewed (many, many posts) has provided an answer.

This seems like it would be the easiest thing to accomplish but I have not been successful a single time.

Any suggestions or assistance would be much appreciated.

Thank you for your time!

Rod
  • 11
  • 2

2 Answers2

1

Haven't touched AS2 in a long time. I've done a basic test and findNearestCuePoint worked. You're using the FLVPlayback component, right ? Here's what I've tried:

videoPlayer.autoPlay = false;
onEnterFrame = function():Void{
    videoPlayer.seekPercent(_xmouse/Stage.width * 100);
    videoPlayer.play();
    trace(videoPlayer.findNearestCuePoint(videoPlayer.playheadTime).name);
}

The recommended way would be to find the nearest cue point in an playheadUpdate handler which is triggered after the playhead changes it's value. (e.g. 1. tell the playhead to move, 2. the playhead actually changes the value, 3. the playheadUpdate gets called)

Here's a more basic approach:

onEnterFrame = function():Void{
    if(videoPlayer.metadata) trace(videoPlayer.findNearestCuePoint(_xmouse/Stage.width * videoPlayer.metadata.duration).name);
}

In my test I've added 4 cue points. Tried them all: actionscript/event/navigation. The strange thing was when I tried to access the cuePoints property through videoPlayer or through videoPlayer.metadata I got an array of 8 undefined objects, and the length of the array was 4 when I traced it. Don't know what the issue is, maybe encoding/codec and as2 compatibility, not sure.

Anyway...as long as you've got your cuePoints array, you can manually find the closest one by looping though all of them and getting the smallest absolute difference between each cue point time and the current time:

function getClosestCuePoint(cuePoints:Array,time:Number):Object{
    var numCuePoints:Number = cuePoints.length;
    var minDist:Number = 100000000,result:Object;
    for(var i:Number = 0 ; i < numCuePoints ; i++){
        if(Math.abs(cuePoints[i].time - time) < minDist){
            minDist = Math.abs(cuePoints[i].time - time);
            result = cuePoints[i];
        }
    }
    return result;
}

Here's a mockup example: let's pretend some boxes on the screen are the cue points and the _xmouse position would be the playhead time. Try this in a new document:

//fake cue points
var numCuePoints:Number = 5;
var cuePoints = [];
for(var i:Number = 0 ; i < numCuePoints ; i++) cuePoints[i] = {name:'narration ' + (i+1),time: 10 + (80 + Math.random() * 20) * i}
//visual hint - separated from the cue points
for(var i:Number = 0 ; i < numCuePoints ; i++) drawBox(this,0x009900,10,15,cuePoints[i].time,Stage.width * .5);
var playhead:TextField = drawText(this,'playhead');

//playhead update
onEnterFrame = function():Void{
    playhead._x = _xmouse;
    playhead.setTextFormat(new TextFormat('Verdana',11));
    playhead.text = 'time: ' + _xmouse+' / cue ' + getClosestCuePoint(cuePoints,_xmouse).name;
}
//find the shortest marker within the shortest distance from the current value
function getClosestCuePoint(cuePoints:Array,time:Number):Object{
    var numCuePoints:Number = cuePoints.length;
    var minDist:Number = 100000000,result:Object;
    for(var i:Number = 0 ; i < numCuePoints ; i++){
        if(Math.abs(cuePoints[i].time - time) < minDist){
            minDist = Math.abs(cuePoints[i].time - time);
            result = cuePoints[i];
        }
    }
    return result;
}
//utils
function drawBox(target:MovieClip,color:Number,width:Number,height:Number,x:Number,y:Number):Void{
    target.lineStyle(3,color);
    target.moveTo(x,y);
    target.lineTo(x+width,y);
    target.lineTo(x+width,y+height);
    target.lineTo(x,y+height);
    target.lineTo(x,y);
}
function drawText(target:MovieClip,name:String):TextField{
    var result:TextField = target.createTextField(name,target.getNextHighestDepth(),0,Stage.width * .5-20,100,20);
    result.autoSize = 'left';
    result.border = true;
    result.selectable = false;
    return result;
}

HTH

George Profenza
  • 50,687
  • 19
  • 144
  • 218
  • Thank you very much for your reply... I really appreciate it. Unfortunately, none of the code you posted here has resulted in a trace of the existing cue points. In addition, the _xmouse portion of the first two onEnterFrame functions just makes the video bounce back and forth. I did try using a playheadUpdate event listener, and while it reported effectively, all of the results were null or undefined. Still not sure what I am doing wrong, because by all examples I have used so far, it should be functioning. – Rod Aug 15 '11 at 15:37
  • I'm sorry to hear the code doesn't work for you. I will upload/post my test files later today (which do work), maybe they can be of some use. Are you 100% sure your cue points are encoded and accessible from actionscript ? What gets printed in the Output Panel if you trace the cue points array ? – George Profenza Aug 15 '11 at 15:52
  • @Rob I've uploaded a test file [here](http://lifesine.eu/so/AS2CuePointTest.zip). Check if it works for you. Could you upload a very basic version of your setup for a check ? Not sure if something in as2 not working or the way the video is encoded – George Profenza Aug 15 '11 at 21:43
0

George,

I believe I discovered the issue, and I think it was something that you covered in your previous post, but I glossed over it by accident.

The F4V I was working with had the cue points embedded using Adobe Media Encoder... and that was the entire issue.

I went back and exported the cue points out to XML, then stripped them out of the F4V and re-encoded it without them. Then I edited the XML to change all of the event cue point to actionscript and imported them into the FLA file using the FLV component properties dialogue.

Presto, amazingly enough, I had no issues finding the cue points, tracing them, and using them for any purpose.

So in the future, I just need to remember to set up the cue points in the Properties dialogue and set them to actionscript and I should be golden. So far, it has worked flawlessly with all of the F4V files since making the change.

Thank you very much for your detailed response and your follow up!