如何取消Flex3 VideoDisplay类的“搜索”状态

时间:2011-01-12 14:13:47

标签: flex video flex3

我有VideoDisplay个实例播放视频。当我点击视频滑块(也是我的组件)时,属性videoDisplay.playheadTime已设置,videoDisplay.state从“播放”变为“搜索”状态一小段时间(videoDisplay寻找新的位置,然后再次播放视频)。预期的bevaiour。

但是,如果我(或任何随机用户)足够快,我可以在玩家仍然处于“寻找”状态时再次设置playheadTime。重复几次后,每次点击都会排队,videoDisplay跳转到我点击的视频的每个地方(这是在我最后一次点击后大约10-15秒的时间间隔内发生的)。当我使用实时拖动时videoDisplay被搜索所淹没,进入“错误”状态。

我的问题是 - 有没有办法取消寻找VideoDisplay课程的状态?例如,玩家处于“寻找”状态,我设置了playheadTime,并且玩家忘记了上次搜索并尝试找到视频的新位置。

我会像'使用Flex4 VideoPlayer类'那样毫无意义的答案!

1 个答案:

答案 0 :(得分:1)

一种可能的方法是将视频显示包装在组件中,并自行管理搜索。因此,如果有人打电话寻求,请确保视频当前没有寻求,如果是,请等到当前操作完成后再继续操作。如果用户尝试再次搜索,则丢弃所有当前待处理的操作,并使最新的操作成为下一个操作。立即处理这个确切的问题....这是代码:

public function Seek(nSeconds:Number, bPlayAfter:Boolean):void
{ 
    trace("Player Seek: "+ nSeconds);
    var objSeekComand:VideoPlayerSeekCommand = new VideoPlayerSeekCommand(ucPlayer, nSeconds, bPlayAfter);
    ProcessCommand(objSeekComand);
}

protected function ProcessCommand(objCommand:ICommand):void
{
    if(_objCurrentCommand != null)
    {
        _objCurrentCommand.Abort();
    }

    _objCurrentCommand = objCommand
    objCommand.SignalCommandComplete.add(OnCommandComplete);
    objCommand.Execute();
}

这是命令

public class VideoPlayerSeekCommand extends CommandBase
    {
        private var _ucVideoDisplay:VideoDisplay;
        private var _nSeekPoint:Number;
        private var _bPlayAfterSeek:Boolean;
        private var _bIsExecuting:Boolean;

        public function VideoPlayerSeekCommand(ucVideoDisplay:VideoDisplay, nSeekPointInSeconds:Number, bPlayAfterSeek:Boolean,  fAutoAttachSignalHandler:Function = null)
        {
            _ucVideoDisplay = ucVideoDisplay;
            _nSeekPoint = nSeekPointInSeconds;
            _bPlayAfterSeek = bPlayAfterSeek;

            super(fAutoAttachSignalHandler);
        }

        override public function Execute():void
        {
            //First check if we are playing, and puase if needed
            _bIsExecuting = true;
            if(_ucVideoDisplay.playing == true)
            {
                _ucVideoDisplay.addEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, OnPlayerStateChangedFromPlay, false, 0, true);
                _ucVideoDisplay.pause();
            }
            else
            {
                DoSeek();
            }

        }

        protected function OnPlayerStateChangedFromPlay(event:MediaPlayerStateChangeEvent):void
        {
            _ucVideoDisplay.removeEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, OnPlayerStateChangedFromPlay);
            if(_bIsExecuting == true)
            {
                if(_ucVideoDisplay.playing == false)
                {
                    DoSeek();
                }
                else
                {
                    throw new Error("VideoPlayerSeekAndPlayCommand - OnPlayerStateChangedFromPlay error");
                }
            }
        }

        private function DoSeek():void
        {
            if(_bIsExecuting == true)
            {
                _ucVideoDisplay.seek(_nSeekPoint);
                CheckSeekComplete();
            }
        }

        private function CheckSeekComplete():void
        {
            if(_bIsExecuting == true)
            {
                if (Math.abs( _ucVideoDisplay.currentTime - _nSeekPoint) < 2)
                {
                    if(_bPlayAfterSeek == true)
                    {
                        _ucVideoDisplay.play();
                    }
                    DispatchAndDestroy();
                }
                else
                {
                    CoreUtils.CallLater(CheckSeekComplete, .07);
                }
            }
        }

        override public function Abort():void
        {
            _bIsExecuting = false;
            SignalCommandComplete.removeAll();
        }
    }

我在这里使用AS3信号而不是事件,而CoreUtils.Call稍后你可以使用setInterval或Timer。但这个想法是在视频暂停之前不要调用搜索,并跟踪搜索完成的时间。

相关问题