Example #1
0
        private async Task StreamSeek(TimeSpan time, bool resumeNeeded, CancellationToken token)
        {
            using (await asyncOpSerializer.LockAsync(token))
            {
                token.ThrowIfCancellationRequested();

                dataSynchronizer.Prepare();

                logger.Info($"Player.SeekAsync(): Resume needed: {resumeNeeded}");

                var asyncOp = player.SeekAsync(time, EnableTransfer);

                dataSynchronizer.SetAsyncOperation(asyncOp);
                await asyncOp.WithCancellation(token);

                logger.Info("Player.SeekAsync() Completed");

                token.ThrowIfCancellationRequested();

                if (resumeNeeded)
                {
                    player.Resume();
                }

                StartClockGenerator();
            }
        }
Example #2
0
        private async Task <bool> ExecuteSeek(TimeSpan time, CancellationToken token)
        {
            dataSynchronizer.Prepare();
            _dataClock.Start();

            var(needDataTcs, asyncHandler) = PrepareStreamStart(ESPlayer.StreamType.Audio, ESPlayer.StreamType.Video);

            using (token.Register(TerminateStreamStart, needDataTcs))
            {
                logger.Info($"Player.SeekAsync({time})");
                var seekTask = player.SeekAsync(time, (s, _) => asyncHandler(s));

                logger.Info($"Player.SeekAsync({time}) Waiting for ready to seek");
                await needDataTcs.Task;

                logger.Info($"Player.SeekAsync({time}) Starting transfer");
                if (false == await StartTransfer(token))
                {
                    _dataClock.Stop();
                    return(false);
                }

                logger.Info($"Player.SeekAsync({time}) Waiting for seek completion");
                await seekTask.WithCancellation(token);

                logger.Info($"Player.SeekAsync({time}) Done");

                StartClockGenerator();
            }

            return(true);
        }
Example #3
0
        private async Task StreamSeek(TimeSpan time, CancellationToken token)
        {
            logger.Info(time.ToString());

            // TODO: Propagate exceptions to upper layers
            try
            {
                using (await asyncOpSerializer.LockAsync(token))
                {
                    logger.Info("Seeking Streams");
                    var seekOperations = new List <Task <EsStream.SeekResult> >();

                    foreach (var esStream in dataStreams.Where(esStream => esStream != null))
                    {
                        seekOperations.Add(esStream.Stream.Seek(seekID, time, token));
                    }

                    await Task.WhenAll(seekOperations).WithCancellation(token);

                    // Check if any task encountered destructive config change
                    if (seekOperations.Any(seekTask => seekTask.Result == EsStream.SeekResult.RestartRequired))
                    {
                        // Restart needed
                        logger.Info("Configuration change during seek. Restarting Player");
                        await RestartPlayer(token);

                        return;
                    }

                    await Prebuffer(token);

                    logger.Info("Player.SeekAsync()");

                    await player.SeekAsync(time, OnReadyToSeekStream).WithCancellation(token);

                    logger.Info("Player.SeekAsync() Completed");
                    StartClockGenerator();
                }
            }
            catch (OperationCanceledException)
            {
                logger.Info("Operation Cancelled");
            }
            catch (Exception e)
            {
                logger.Error(e);
                playbackErrorSubject.OnNext("Seek Failed");
            }
            finally
            {
                // Always notify UI on seek end regardless of seek status
                // to unblock it for further seeks ops.
                // TODO: Remove SeekCompleted event. Return Task to PlayerController/PlayerService.
                if (!token.IsCancellationRequested)
                {
                    seekCompletedSubject.OnNext(Unit.Default);
                }
            }
        }
        private async Task StreamSeek(TimeSpan time, CancellationToken token)
        {
            logger.Info(time.ToString());
            using (await asyncOpSerializer.LockAsync(token))
            {
                logger.Info("Player.SeekAsync()");

                await player.SeekAsync(time, OnReadyToSeekStream).WithCancellation(token);

                logger.Info("Player.SeekAsync() Completed");
                StartClockGenerator();
            }
        }
Example #5
0
        private async Task StreamSeek(TimeSpan time, bool resumeNeeded, CancellationToken token)
        {
            dataSynchronizer.Prepare();

            logger.Info($"Player.SeekAsync(): Resume needed: {resumeNeeded} {player.GetState()}");

            var asyncOp = player.SeekAsync(time, async(s, t) => await StartTransfer(s, token));

            await asyncOp.WithCancellation(token);

            logger.Info($"Player.SeekAsync() Completed {player.GetState()}");

            token.ThrowIfCancellationRequested();

            if (resumeNeeded)
            {
                player.Resume();
            }

            StartClockGenerator();
        }