我有一个播放视频的VideoDisplay实例。当我单击视频滑块(也是我的组件)时,属性videoDisplay.playheadTime被设置,videoDisplay.state从“播放”进入“寻找”状态一段时间( videoDisplay寻找新位置,然后再次播放视频)。预期的行为。
但如果我(或任何随机用户)足够快,我可以在播放器仍处于“寻找”状态时再次设置playheadTime。当重复几次时,每次点击都会进入队列,videoDisplay会跳到我点击过的视频的每个地方(这是在我最后一次点击后大约10-15秒的间隔内发生的)。当我使用实时拖动时,被seekings淹没的videoDisplay会进入“错误”状态。
我的问题是--有什么方法可以取消VideoDisplay类的寻道状态吗?例如,播放器处于“查找”状态,我设置了playheadTime,而播放器忘记了上次查找,并试图找到视频的新位置。
我将否决像“使用Flex4 VideoPlayer类”这样毫无意义的答案!
发布于 2011-09-09 03:36:53
一种可能的方法是将视频显示包装在一个组件中,并自己更好地管理seek。因此,如果有人调用了seek,请确保视频当前未在查找,如果是,则等待当前操作完成后再继续执行新的操作。如果用户再次尝试查找,则丢弃所有当前挂起的操作,并使最新的操作成为下一个操作。现在正在努力解决这个问题……代码如下:
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信号,而不是事件,稍后您可以使用setInterval或计时器来执行CoreUtils.Call。但这个想法是在视频暂停之前不调用seek,并跟踪seek何时完成。
https://stackoverflow.com/questions/4669737
复制相似问题