Пример #1
0
        private void DetectPlaybackEnded(MediaType main)
        {
            var playbackEndClock = MediaCore.Blocks[main].Count > 0
                ? MediaCore.Blocks[main].RangeEndTime
                : MediaCore.Timing.GetEndTime(main) ?? TimeSpan.MaxValue;

            // Check End of Media Scenarios
            if (!Commands.HasPendingCommands &&
                MediaCore.HasDecodingEnded &&
                !CanResumeClock(main))
            {
                // Rendered all and nothing else to render
                if (State.HasMediaEnded == false)
                {
                    if (Container.IsStreamSeekable)
                    {
                        var componentStartTime      = Container.Components[main].StartTime;
                        var actualComponentDuration = TimeSpan.FromTicks(playbackEndClock.Ticks - componentStartTime.Ticks);
                        Container.Components[main].Duration = actualComponentDuration;
                    }

                    MediaCore.PausePlayback();
                    MediaCore.ChangePlaybackPosition(playbackEndClock);
                }

                State.MediaState    = MediaPlaybackState.Stop;
                State.HasMediaEnded = true;
            }
            else
            {
                State.HasMediaEnded = false;
            }
        }
Пример #2
0
        private void DetectPlaybackEnded(MediaType main)
        {
            var playbackEndClock = MediaCore.Blocks[main].Count > 0
                ? MediaCore.Blocks[main].RangeEndTime
                : Container.Components.PlaybackEndTime ?? TimeSpan.MaxValue;

            var isAtEndOfPlayback = MediaCore.PlaybackPosition.Ticks >= playbackEndClock.Ticks ||
                                    MediaCore.Timing.HasDisconnectedClocks;

            // Check End of Media Scenarios
            if (!Commands.HasPendingCommands &&
                MediaCore.HasDecodingEnded &&
                isAtEndOfPlayback)
            {
                // Rendered all and nothing else to render
                if (State.HasMediaEnded == false)
                {
                    MediaCore.PausePlayback();
                    MediaCore.ChangePlaybackPosition(playbackEndClock);
                }

                State.MediaState    = MediaPlaybackState.Stop;
                State.HasMediaEnded = true;
            }
            else
            {
                State.HasMediaEnded = false;
            }
        }
Пример #3
0
        /// <summary>
        /// Provides the implementation for the Pause Media Command.
        /// </summary>
        /// <returns>True if the command was successful.</returns>
        private bool CommandPauseMedia()
        {
            if (State.CanPause == false)
            {
                return(false);
            }

            MediaCore.PausePlayback();

            foreach (var renderer in MediaCore.Renderers.Values)
            {
                renderer.OnPause();
            }

            MediaCore.ChangePlaybackPosition(SnapPositionToBlockPosition(MediaCore.PlaybackPosition));
            State.MediaState = MediaPlaybackState.Pause;
            return(true);
        }
Пример #4
0
        private void AlignClocksToPlayback(MediaType main, MediaType[] all)
        {
            // we don't want to disturb the clock or align it if we are not ready
            if (Commands.HasPendingCommands)
            {
                return;
            }

            if (HasDisconnectedClocks)
            {
                foreach (var t in all)
                {
                    if (t == MediaType.Subtitle)
                    {
                        continue;
                    }

                    var compBlocks   = MediaCore.Blocks[t];
                    var compPosition = MediaCore.Timing.GetPosition(t);

                    if (compBlocks.Count <= 0)
                    {
                        MediaCore.PausePlayback(t, false);

                        if (MediaCore.Timing.GetIsRunning(t))
                        {
                            this.LogDebug(Aspects.Timing,
                                          $"CLOCK PAUSED: {t} clock was paused at {compPosition.Format()} because no decoded {t} content was found");
                        }

                        continue;
                    }

                    // Don't let the RTC lag behind the blocks or move beyond them
                    if (compPosition.Ticks < compBlocks.RangeStartTime.Ticks)
                    {
                        MediaCore.ChangePlaybackPosition(compBlocks.RangeStartTime, t, false);
                        this.LogDebug(Aspects.Timing,
                                      $"CLOCK BEHIND: {t} clock was {compPosition.Format()}. It was updated to {compBlocks.RangeStartTime.Format()}");
                    }
                    else if (compPosition.Ticks > compBlocks.RangeEndTime.Ticks)
                    {
                        if (t != MediaType.Audio)
                        {
                            MediaCore.PausePlayback(t, false);
                        }

                        MediaCore.ChangePlaybackPosition(compBlocks.RangeEndTime, t, false);

                        this.LogDebug(Aspects.Timing,
                                      $"CLOCK AHEAD : {t} clock was {compPosition.Format()}. It was updated to {compBlocks.RangeEndTime.Format()}");
                    }
                }

                return;
            }

            // Get a reference to the main blocks.
            // The range will be 0 if there are no blocks.
            var blocks   = MediaCore.Blocks[main];
            var position = MediaCore.PlaybackPosition;

            if (blocks.Count == 0)
            {
                // We have no main blocks in range. All we can do is pause the clock
                if (MediaCore.Timing.IsRunning)
                {
                    this.LogDebug(Aspects.Timing,
                                  $"CLOCK PAUSED: playback clock was paused at {position.Format()} because no decoded {main} content was found");
                }

                MediaCore.PausePlayback();
                return;
            }

            if (position.Ticks < blocks.RangeStartTime.Ticks)
            {
                // Don't let the RTC lag behind what is available on the main component
                MediaCore.ChangePlaybackPosition(blocks.RangeStartTime);
                this.LogTrace(Aspects.Timing,
                              $"CLOCK BEHIND: playback clock was {position.Format()}. It was updated to {blocks.RangeStartTime.Format()}");
            }
            else if (position.Ticks > blocks.RangeEndTime.Ticks)
            {
                // Don't let the RTC move beyond what is available on the main component
                MediaCore.PausePlayback();
                MediaCore.ChangePlaybackPosition(blocks.RangeEndTime);
                this.LogTrace(Aspects.Timing,
                              $"CLOCK AHEAD : playback clock was {position.Format()}. It was updated to {blocks.RangeEndTime.Format()}");
            }
        }
Пример #5
0
        private void AlignClocksToPlayback(MediaType main, MediaType[] all)
        {
            // we don't want to disturb the clock or align it if we are not ready
            if (Commands.HasPendingCommands)
            {
                return;
            }

            MediaBlockBuffer blocks   = null;
            TimeSpan         position = MediaCore.PlaybackPosition;

            if (HasDisconnectedClocks)
            {
                foreach (var t in all)
                {
                    if (t == MediaType.Subtitle)
                    {
                        continue;
                    }

                    blocks   = MediaCore.Blocks[t];
                    position = MediaCore.Timing.Position(t);

                    // Don't let the RTC lag behind the blocks or move beyond them
                    if (position.Ticks < blocks.RangeStartTime.Ticks)
                    {
                        MediaCore.ChangePlaybackPosition(blocks.RangeStartTime, t);
                        this.LogTrace(Aspects.Timing, $"CLOCK BEHIND: {t} clock was {position.Format()}. It was updated to {blocks.RangeStartTime.Format()}");
                    }
                    else if (position.Ticks > blocks.RangeEndTime.Ticks)
                    {
                        // we don't use the pause playback method to prevent
                        // reporting the current playback position
                        MediaCore.Timing.Pause(t);
                        MediaCore.ChangePlaybackPosition(blocks.RangeEndTime, t);
                        this.LogTrace(Aspects.Timing, $"CLOCK AHEAD : {t} clock was {position.Format()}. It was updated to {blocks.RangeEndTime.Format()}");
                    }
                }

                return;
            }

            // Get a reference to the main blocks.
            // The range will be 0 if there are no blocks.
            blocks = MediaCore.Blocks[main];
            var range = blocks.GetRangePercent(position);

            if (range < 0)
            {
                // Don't let the RTC lag behind what is available on the main component
                MediaCore.ChangePlaybackPosition(blocks.RangeStartTime);
                this.LogTrace(Aspects.Timing, $"CLOCK BEHIND: playback clock was {position.Format()}. It was updated to {blocks.RangeStartTime.Format()}");
            }
            else if (range > 1d)
            {
                // Don't let the RTC move beyond what is available on the main component
                MediaCore.PausePlayback();
                MediaCore.ChangePlaybackPosition(blocks.RangeEndTime);
                this.LogTrace(Aspects.Timing, $"CLOCK AHEAD : playback clock was {position.Format()}. It was updated to {blocks.RangeEndTime.Format()}");
            }
            else if (range == 0 && blocks.Count == 0 && MediaCore.Timing.IsRunning)
            {
                // We have no main blocks in range. All we can do is pause the clock
                this.LogTrace(Aspects.Timing, $"CLOCK PAUSED: playback clock was {position.Format()} but no {main} content was found");
                MediaCore.PausePlayback();
            }
        }