I have a flvplayback component onto which I am loading a video.
To mimic next frame and previous frame actions I am adding cue points to the loaded for every second of its length.
The next frame /previous frame functions implement seekToNextNavCuePoint and seekToPrevNavCuePoint
on the video.
But its not working the way I expected it to.
Here is the actual class file. You can directly compile it with an fla file containing button instances in the library for play pause stop... Also you would need some sample flv file.
package
{
/*
The fla file contains buttons in the library;
*/
import flash.events.*;
import flash.display.*;
import fl.video.*;
public class testPlayer extends MovieClip
{
private var video1:FLVPlayback;
private var play_btn:PlayButton;
private var pause_btn:PauseButton;
private var stop_btn:StopButton;
private var nextFrame_btn:ForwardButton;
private var previousFrame_btn:ForwardButton;
public function testPlayer()
{
// constructor code
addEventListener(Event.ADDED_TO_STAGE,onAdded);
}
private function onAdded(event:Event)
{
setPlayer();
setPath();
setButtons();
}
private function setPlayer()
{
video1 = new FLVPlayback ;
this.addChild(video1);
video1.x = 50;
video1.y = 50;
}
private function setPath()
{
video1.addEventListener(VideoEvent.READY, flvPlayback_ready);
video1.addEventListener(MetadataEvent.CUE_POINT, flvPlayback_cuePoint);
// here you can give any flv you have and its total time
video1.load("test.flv",3600,false);
}
private function flvPlayback_ready(evt:VideoEvent):void
{
var num:Number = video1.totalTime;
for (var i:int=0; i<num; i++)
{
video1.addASCuePoint(i, "cuePoint"+String(i));
}
this.removeEventListener(VideoEvent.READY, flvPlayback_ready);
}
private function flvPlayback_cuePoint(evt:MetadataEvent):void
{
trace("CUE POINT!!!");
trace("\t", "name:", evt.info.name);// name: cuePoint1
trace("\t", "time:", evt.info.time);// time: 1
trace("\t", "type:", evt.info.type);// type: actionscript
}
private function setButtons()
{
play_btn=new PlayButton();
pause_btn=new PauseButton();
stop_btn=new StopButton();
nextFrame_btn=new ForwardButton();
previousFrame_btn=new ForwardButton();
play_btn.addEventListener(MouseEvent.CLICK,onPlay);
pause_btn.addEventListener(MouseEvent.CLICK,onPause);
stop_btn.addEventListener(MouseEvent.CLICK,onStop);
nextFrame_btn.addEventListener(MouseEvent.CLICK,onNextFrame);
previousFrame_btn.addEventListener(MouseEvent.CLICK,onPreviousFrame);
play_btn.x = 50;
play_btn.y = 350;
previousFrame_btn.x = 125;
previousFrame_btn.y = 350;
previousFrame_btn.scaleX *= -1;
nextFrame_btn.x = 150;
nextFrame_btn.y = 350;
pause_btn.x = 200;
pause_btn.y = 350;
stop_btn.x = 250;
stop_btn.y = 350;
addChild(play_btn);
addChild(pause_btn);
addChild(stop_btn);
addChild(previousFrame_btn);
addChild(nextFrame_btn);
}
private function onPlay(event:MouseEvent)
{
video1.play();
}
private function onPause(event:MouseEvent)
{
video1.pause();
}
private function onStop(event:MouseEvent)
{
video1.stop();
}
private function onNextFrame(event:Event)
{
if (video1.playing)
{
//video1.pause();
}
// this is not working the way i expected it to
video1.seekToNextNavCuePoint();
}
private function onPreviousFrame(event:Event)
{
if (video1.playing)
{
//video1.pause();
}
// this is not working the way i expected it to
video1.seekToPrevNavCuePoint();
}
}
}
What am I missing here? Just running it without invoking next/prev frame functions shows that the cue points being activated for every second as per the flvPlayback_cuePoint function.
update:
When I click the previousFrame button the frame shifts to cuepoint1 , irrespective of where the present cuepoint is. When I click the nextFrame button, the cue point and the display seemingly changes to next, but soon after a few clicks the cue point changes to 1 and the video starts from the beginning.
Question 1 : What is the Correct way to dynamically add Cue points in ActionScript 3.0 along the length of the loaded movie using addASCuePoint()
Question 2 : Can We add cue points with at intervals of 33ms, at which we can properly seek to?
Question 3: What is wrong in the above code?
update: Adding a bounty : To solve the problem and answers to The 3 questions
update:
After much unsuccessful trials with the above methods and trying out suggestions by Trevor. I got the functionality working through seek() method but with considerable lack of precision .
package
{
/*
The fla file contains buttons in the library;
*/
import flash.events.*;
import flash.display.*;
import fl.video.*;
public class testPlayer extends MovieClip
{
private var video1:FLVPlayback;
private var play_btn:PlayButton;
private var pause_btn:PauseButton;
private var stop_btn:StopButton;
private var nextFrame_btn:ForwardButton;
private var previousFrame_btn:ForwardButton;
private var playHeadTime:Number;
private var cue:Object;
public function testPlayer()
{
addEventListener(Event.ADDED_TO_STAGE,onAdded);
}
private function onAdded(event:Event)
{
setPlayer();
setPath();
setButtons();
playHeadTime = 0;
}
private function setPlayer()
{
video1 = new FLVPlayback ;
this.addChild(video1);
video1.x = 50;
video1.y = 50;
}
private function setPath()
{
video1.playheadUpdateInterval = 50;
video1.seekToPrevOffset = 0.01;
video1.addEventListener(VideoEvent.READY, flvPlayback_ready);
video1.addEventListener(MetadataEvent.CUE_POINT, flvPlayback_cuePoint);
video1.load("test.flv",3600,false);
}
private function flvPlayback_ready(evt:VideoEvent):void
{
// changing this loop to add more cue points causes the program to hang.
for (var i:int=0; i<video1.totalTime; i++)
{
cue= new Object();
cue.time = i;
cue.type = "navigation";// this does not seem to get set the type
cue.name = "cuePoint" + String(i);
video1.addASCuePoint(cue,cue.name);
}
video1.removeEventListener(VideoEvent.READY, flvPlayback_ready);
}
private function flvPlayback_cuePoint(evt:MetadataEvent):void
{
trace("CUE POINT!!!");
trace("\t", "name:", evt.info.name);// name: cuePoint1
trace("\t", "time:", evt.info.time ," playhead time :",String(Math.round(video1.playheadTime)));// time: 1
trace("\t", "====type:", evt.info.type);// traces actionscript instead of navigation
}
private function setButtons()
{
play_btn=new PlayButton();
pause_btn=new PauseButton();
stop_btn=new StopButton();
nextFrame_btn=new ForwardButton();
previousFrame_btn=new ForwardButton();
play_btn.addEventListener(MouseEvent.CLICK,onPlay);
pause_btn.addEventListener(MouseEvent.CLICK,onPause);
stop_btn.addEventListener(MouseEvent.CLICK,onStop);
nextFrame_btn.addEventListener(MouseEvent.CLICK,onNextFrame);
previousFrame_btn.addEventListener(MouseEvent.CLICK,onPreviousFrame);
play_btn.x = 50;
play_btn.y = 350;
previousFrame_btn.x = 125;
previousFrame_btn.y = 350;
previousFrame_btn.scaleX *= -1;
nextFrame_btn.x = 150;
nextFrame_btn.y = 350;
pause_btn.x = 200;
pause_btn.y = 350;
stop_btn.x = 250;
stop_btn.y = 350;
addChild(play_btn);
addChild(pause_btn);
addChild(stop_btn);
addChild(previousFrame_btn);
addChild(nextFrame_btn);
}
private function onPlay(event:MouseEvent)
{
video1.play();
}
private function onPause(event:MouseEvent)
{
video1.pause();
}
private function onStop(event:MouseEvent)
{
video1.stop();
}
private function onNextFrame(event:Event)
{
if (video1.playing)
{
video1.stop();
}
trace("Calling nextFrame :::",playHeadTime);
video1.seek(playHeadTime);
playHeadTime += 1;
}
private function onPreviousFrame(event:Event)
{
if (video1.playing)
{
video1.stop();
}
trace("Calling prevFrame ::::",playHeadTime);
video1.seek(playHeadTime);
playHeadTime -= 1;
}
}
}
The output for the following traces out like given below. The problem is the next and previous functions keep skipping cue points and don't seem to work at certain cue points. the trace below should give the clear picture.
Calling nextFrame ::: 0
CUE POINT!!!
name: cuePoint0
time: 0 playhead time : 0
====type: actionscript
Calling nextFrame ::: 1
CUE POINT!!!
name: cuePoint2
time: 2 playhead time : 2
====type: actionscript
Calling nextFrame ::: 2
Calling nextFrame ::: 3
CUE POINT!!!
name: cuePoint4
time: 4 playhead time : 4
====type: actionscript
Calling prevFrame :::: 4
Calling prevFrame :::: 3
Calling prevFrame :::: 2
CUE POINT!!!
name: cuePoint2
time: 2 playhead time : 2
====type: actionscript
Edit:
- Question 1 : How can we trigger the MetadataEvent.CUE_POINT on successive cue points i.e without it skipping a cue point.
- Question 2 : How cab we trigger the MetadataEvent.CUE_POINT event at each cue point when they are lets say at 100 ms intervals.