Пример #1
0
        private async Task FirstPacketWait()
        {
            logger.Info(
                $"{StreamType.Audio}: Waiting for {StreamType.Video} first data packet");

            try
            {
                await esStreams[(int)StreamType.Video].GetFirstDataPacketNotificationTask();

                logger.Info(
                    $"{StreamType.Audio}: {StreamType.Video} first data packet processed");

                if (!activeTaskCts.Token.IsCancellationRequested)
                {
                    esStreams[(int)StreamType.Audio].Start();
                    return;
                }
            }
            catch (OperationCanceledException)
            {
                logger.Info(
                    $"{StreamType.Audio}: Wait for {StreamType.Video} first data packet cancelled");
            }

            // Issue EOS if Player Async Operation (seek/prepare) is in progress
            if (IsAsyncOpRunning())
            {
                logger.Info("Terminating player async operation by A/V EOS");
                player.SubmitEosPacket(ESPlayer.StreamType.Video);
                player.SubmitEosPacket(ESPlayer.StreamType.Audio);
            }
        }
Пример #2
0
        /// <summary>
        /// Pushes EOS packet to ESPlayer
        /// </summary>
        /// <param name="dataPacket">Packet</param>
        /// <param name="token">CancellationToken</param>
        /// <exception cref="PacketSubmitException">
        /// Exception thrown on submit error
        /// </exception>
        private void PushEosPacket(CancellationToken token)
        {
            logger.Info("");

            bool doRetry;

            // Continue pushing packet till success or terminal failure
            do
            {
                var res = player.SubmitEosPacket(streamType.ESStreamType());
                doRetry = ShouldRetry(res, token);
            } while (doRetry && !token.IsCancellationRequested);
        }
Пример #3
0
        public async Task Seek(TimeSpan time)
        {
            logger.Info($"Seek to {time}");
            var token = activeTaskCts.Token;

            using (await asyncOpSerializer.LockAsync(token))
            {
                _pendingPosition = time;

                logger.Info($"Seeking to {_pendingPosition}");

                try
                {
                    // Don't cancel FlushStreams() or its internal operations. In case of cancellation
                    // stream controller will be in less then defined state.
                    await FlushStreams();

                    // DashDataProvider - does not care about cancellation token.
                    // HLSDataProvider - when cancelled, effectively terminates demuxer operation.
                    // - Playback termination - no issue.
                    // - Suspend - no way to resume demuxer other then restarting entire stream playback.
                    var seekToTime = await Client.Seek(time, CancellationToken.None);

                    _dataClock.Clock = seekToTime;

                    EnableInput();

                    var isCompleted = await ExecuteSeek(seekToTime, token);

                    _pendingPosition = null;

                    if (isCompleted)
                    {
                        // UI, when paused, does not issue Seeks till resumed. No need to
                        // handle seek while paused in player.
                        SubscribeBufferingEvent();
                        logger.Info("End");
                        return;
                    }
                }
                catch (SeekException e)
                {
                    var msg = $"Seeking to {time} Failed, reason \"{e.Message}\"";
                    logger.Error(msg);
                    playbackErrorSubject.OnNext(msg);

                    // Propagate subject content.
                    await Task.Yield();
                }
                catch (Exception e)
                    when(e is TaskCanceledException || e is OperationCanceledException)
                    {
                        logger.Info($"Seeking to {time} Cancelled");
                    }
                catch (Exception e)
                {
                    logger.Error(e);
                    playbackErrorSubject.OnNext($"Seeking to {time} Failed");
                    throw;
                }

                // SeekException or Cancellation occurred.
                player.SubmitEosPacket(ESPlayer.StreamType.Audio);
                player.SubmitEosPacket(ESPlayer.StreamType.Video);
                logger.Info("EOS Sent");
            }
        }