Как отменить состояние «поиска» класса Flex3 VideoDisplay - PullRequest
1 голос
/ 12 января 2011

У меня есть VideoDisplay экземпляр, воспроизводящий видео.Когда я нажимаю на видео слайдер (также мой компонент), устанавливается свойство videoDisplay.playheadTime, и videoDisplay.state переходит из состояния «воспроизведение» в состояние «поиска» на короткий момент (videoDisplay ищет новую позицию изатем воспроизводит видео снова).Намеренный bevaiour.

Но если я (или любой случайный пользователь) достаточно быстр, я могу снова установить playheadTime, пока игрок все еще находится в состоянии «поиска».При повторении несколько раз каждый клик ставится в очередь и videoDisplay прыгает на каждое место видео, на которое я нажал (это происходит с интервалом в 10-15 секунд после моего последнего клика).Когда я использую перетаскивание в реальном времени, videoDisplay, перегруженный поисками, переходит в состояние «ошибки».

Мой вопрос: есть ли способ отменить состояние поиска класса VideoDisplay?Например, игрок находится в состоянии «поиск», я установил playheadTime, а игрок забыл о последнем поиске и попытался найти новое место в видео.

Я опущу бессмысленные ответы, такие как «Использование Flex4».Класс VideoPlayer '!

1 Ответ

1 голос
/ 08 сентября 2011

Один из возможных способов - обернуть видео дисплей в компонент и немного лучше управлять поиском. Так что, если кто-то вызывает поиск, убедитесь, что видео в данный момент не ищет, если так, то дождитесь завершения текущей операции, прежде чем переходить к новой. Если пользователь попытается выполнить повторный поиск, откажитесь от всех ожидающих в данный момент операций и выполните последнюю из них при следующей операции. Работаем над этой точной проблемой прямо сейчас .... Вот код:

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. Но идея состоит в том, чтобы не вызывать поиск до тех пор, пока видео не будет приостановлено, и отслеживать, когда поиск завершен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...