void seekFunc(double positionSeconds, VideoLib.VideoPlayer.SeekKeyframeMode mode) { if (VideoState == VideoPlayerControl.VideoState.CLOSED) { return; } // wait for video and audio decoding to block // To make sure no packets are in limbo // before flushing any ffmpeg internal or external queues. videoDecoder.FrameQueue.setState(FrameQueue.FrameQueueState.BLOCK, FrameQueue.FrameQueueState.BLOCK, FrameQueue.FrameQueueState.BLOCK); if (videoDecoder.seek(positionSeconds, mode) == true) { // flush the framequeue and audioplayer buffer videoDecoder.FrameQueue.flush(); audioPlayer.flush(); audioFrameTimer = videoFrameTimer = HRTimer.getTimestamp(); } if (VideoState == VideoPlayerControl.VideoState.PLAYING) { videoDecoder.FrameQueue.setState(FrameQueue.FrameQueueState.PLAY, FrameQueue.FrameQueueState.PLAY, FrameQueue.FrameQueueState.PLAY); } else if (VideoState == VideoPlayerControl.VideoState.PAUSED) { // display the first new frame in paused mode videoDecoder.FrameQueue.startSingleFrame(); } }
public async Task seek(double positionSeconds, VideoLib.VideoPlayer.SeekKeyframeMode mode = VideoLib.VideoPlayer.SeekKeyframeMode.SEEK_BACKWARDS) { if (videoDecoder.FrameQueue.IsBuffering) { return; } if (SeekTask != null) { try { await SeekTask; } catch (TaskCanceledException) { } } SeekTask = Task.Factory.StartNew(() => seekFunc(positionSeconds, mode), CancelTokenSource.Token); }