Flash AS3向flv动态添加提示点并寻找下一个提示点的问题

Flash AS3向flv动态添加提示点并寻找下一个提示点的问题,flash,actionscript-3,video-streaming,frame,flvplayback,Flash,Actionscript 3,Video Streaming,Frame,Flvplayback,我有一个flvplayback组件,正在加载视频 为了模仿下一帧和上一帧的动作,我在加载的视频中每隔一秒添加一个提示点 下一帧/上一帧函数在视频上实现seekToNextNavCuePoint和seekToPrevNavCuePoint 但它没有按我预期的方式工作 这是实际的类文件。您可以直接编译一个fla文件,其中包含播放暂停停止库中的按钮实例。。。此外,您还需要一些示例flv文件 package { /* The fla file contains buttons in

我有一个flvplayback组件,正在加载视频

为了模仿下一帧和上一帧的动作,我在加载的视频中每隔一秒添加一个提示点

下一帧/上一帧函数在视频上实现seekToNextNavCuePoint和
seekToPrevNavCuePoint

但它没有按我预期的方式工作

这是实际的类文件。您可以直接编译一个fla文件,其中包含播放暂停停止库中的按钮实例。。。此外,您还需要一些示例flv文件

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();
        }
    }

}
当我单击previousFrame按钮时,无论当前cuepoint在何处,帧都会移动到cuepoint1。当我单击nextFrame按钮时,提示点和显示似乎更改为next,但几次单击后,提示点更改为1,视频从头开始

  • 问题1:在ActionScript 3.0中,使用addASCuePoint()

  • 问题2:我们能否以33毫秒的间隔添加提示点 能不能好好找找

  • 问题3:上述代码中有什么错误

    更新: 添加悬赏:解决问题并回答3个问题

更新:


在用上述方法进行了多次失败的试验并尝试了特雷弗的建议之后。 我通过seek()方法获得了功能,但精度相当低

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;
        }
    }
}
编辑:

  • 问题1:我们如何在连续的提示点上触发MetadataEvent.CUE_点,即不跳过提示点
  • 问题2:我们如何在每个提示点触发MetadataEvent.CUE_POINT事件,比如每隔100毫秒触发一次

尝试在每秒导出flv时将关键帧添加到flv,因为如果它是渐进式的,则只能在视频中查找关键帧。在播放流媒体时,您可以精确到时间

问题1<代码>视频1.添加提示点(i,“提示点”+字符串(i))可以正常工作,我唯一关心的是i的初始值为0,我不确定该值是否会被存储或触发。。。但可能是这样

问题2。是,如果视频是流式的,或者是渐进式的,并且有一个关键帧,并且帧速率为30fps或更高。为了每33毫秒有一个提示点,你的视频需要30帧/秒。如果你可以每40毫秒使用一次提示点,那么每分钟25帧就可以了。帧速率在编码时设置,通常与源相同

第三季度。有几件事可以尝试:

尝试将
seekToPrevOffset()
设置为较低的值,例如0.1(如果您计划在帧上放置提示点,则设置为较小的值),默认设置为1,这意味着它可能跳过提示点

还可以尝试将playheadUpdateInterval从250降低到50,这可能有助于搜索。如果你经常每隔30毫秒寻找一次,你就必须把它放得更低

如果视频是渐进式的,请不要搜索已加载的内容以外的内容,否则播放头将跳回起始位置

由于
seekToNextNavCuePoint()
基于当前播放头时间,因此在上一个seek命令完成之前,不允许用户单击“下一步”。或者,您可以将一个值传递到
seekToNextNavCuePoint(myCheckForwardFromHereVar)
中,这样用户就可以在不等待seek命令完成的情况下多次按下next

如果您想拥有更大的控制权,可以跟踪视频中的位置,然后使用
seekToNavCuePoint()
创建自己的
seekToNextNavCuePoint
seekToNextPrevCuePoint
函数。例如

seekToNavCuePoint(“cuePoint”+字符串(数学地板(播放头时));

参见视频点播(“提示点”+字符串(数学楼层(播放头时)+1))

问题1:使用addASCuePoint()在ActionScript 3.0中动态添加提示点的正确方法是什么


问题2:我们是否可以以33毫秒的间隔添加提示点,以便我们能够正确地寻找提示点?
参见问题1的答案,确保不要超过flv的长度
如果在33毫秒时更改视觉项目,会让人眼睛流血

问题3:上述代码中有什么错误?
您从未定义提示点的位置和作用。你能举个例子说明你在每个提示点会做什么吗?

当你提供更多信息时,我将对此进行编辑

第三组问题 *我们如何在连续的提示点上触发MetadataEvent.CUE_点,即不跳过提示点*

*我们如何在每个提示点触发MetadataEvent.CUE_POINT事件,比如每隔100毫秒触发一次*

这可能看起来很奇怪,但你不能保证你会收到一个特定的提示点事件。提示点事件未编组或排队。由于FLV容器和swf之间的帧速率不同,一些事件将被抛出。如果包含的swf文件处于“帧间”,则几乎肯定会错过flv上的提示点。如果两个提示点相距100毫秒,且swf使用标准的24fps。我估计每5个线索点中至少会有1个失去控制。这类似于flash处理许多事情(如垃圾收集)的方式,它尽可能做到最好,但如果“框架”需要继续,它将停止底层进程的执行。即使同步帧速率和提示点间隔,您仍会偶尔错过事件

现在。。。说了这么多。你可以通过不使用提示点来完成你想要的。只需监视playheadUpdate事件并发送howe即可
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;
        }
    }
}
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
var cue:Object = new Object();
cue.time = 4;
cue.type = "actionscript";
cue.name = "myCue";
video1.addASCuePoint(cuePoints_array[i]);