我有VideoDisplay
个实例播放视频。当我点击视频滑块(也是我的组件)时,属性videoDisplay.playheadTime
已设置,videoDisplay.state
从“播放”变为“搜索”状态一小段时间(videoDisplay
寻找新的位置,然后再次播放视频)。预期的bevaiour。
但是,如果我(或任何随机用户)足够快,我可以在玩家仍然处于“寻找”状态时再次设置playheadTime
。重复几次后,每次点击都会排队,videoDisplay
跳转到我点击的视频的每个地方(这是在我最后一次点击后大约10-15秒的时间间隔内发生的)。当我使用实时拖动时videoDisplay
被搜索所淹没,进入“错误”状态。
我的问题是 - 有没有办法取消寻找VideoDisplay
课程的状态?例如,玩家处于“寻找”状态,我设置了playheadTime
,并且玩家忘记了上次搜索并尝试找到视频的新位置。
我会像'使用Flex4 VideoPlayer类'那样毫无意义的答案!
答案 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。但这个想法是在视频暂停之前不要调用搜索,并跟踪搜索完成的时间。