Beispiel #1
0
        /// <summary>
        /// Gets a <see cref="IResumeState"/> from the player.
        /// </summary>
        /// <param name="state">Outputs resume state.</param>
        /// <returns><c>true</c> if successful, otherwise <c>false</c>.</returns>
        public virtual bool GetResumeState(out IResumeState state)
        {
            TimeSpan currentTime = CurrentTime;

            // Workaround for TsReader handling on playback end: it reports a negative position, so we treat it to "stream end"
            if (currentTime.TotalSeconds < 0)
            {
                currentTime = Duration;
            }
            TimeSpan duration = Duration;

            // If we already played back more then 99%, we don't want to ask user to resume playback.
            if (currentTime.TotalSeconds / duration.TotalSeconds > 0.99)
            {
                state = null;
            }
            else
            {
                state = new PositionResumeState
                {
                    ResumePosition             = CurrentTime,
                    ActiveResourceLocatorIndex = _mediaItem?.ActiveResourceLocatorIndex ?? 0,
                    ActiveEditionIndex         = _mediaItem?.ActiveEditionIndex ?? 0
                }
            };
            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// Sets a <see cref="IResumeState"/> to the player. The player is responsible to make the required initializations.
        /// </summary>
        /// <param name="state">Resume state.</param>
        /// <returns><c>true</c> if successful, otherwise <c>false</c>.</returns>
        public virtual bool SetResumeState(IResumeState state)
        {
            PositionResumeState pos = state as PositionResumeState;

            if (pos == null)
            {
                return(false);
            }

            if (_mediaItem != null)
            {
                // Check for multi-resource media items, first set the matching part, then the position
                if (pos.ActiveResourceLocatorIndex != _mediaItem.ActiveResourceLocatorIndex && pos.ActiveResourceLocatorIndex <= _mediaItem.MaximumResourceLocatorIndex ||
                    pos.ActiveEditionIndex != _mediaItem.ActiveEditionIndex && pos.ActiveEditionIndex <= _mediaItem.MaximumEditionIndex)
                {
                    _mediaItem.ActiveResourceLocatorIndex = pos.ActiveResourceLocatorIndex;
                    _mediaItem.ActiveEditionIndex         = pos.ActiveEditionIndex;
                    if (!NextItem(_mediaItem, StartTime.AtOnce))
                    {
                        return(false);
                    }
                }
            }
            CurrentTime = pos.ResumePosition;
            return(true);
        }
        protected void CheckResumeMenuInternal(MediaItem item)
        {
            IResumeState    resumeState = null;
            IUserManagement userProfileDataManagement = ServiceRegistration.Get <IUserManagement>();

            if (userProfileDataManagement.IsValidUser)
            {
                string resumeStateString;
                if (userProfileDataManagement.UserProfileDataManagement.GetUserMediaItemData(userProfileDataManagement.CurrentUser.ProfileId, item.MediaItemId, PlayerContext.KEY_RESUME_STATE, out resumeStateString))
                {
                    resumeState = ResumeStateBase.Deserialize(resumeStateString);
                }
            }

            if (resumeState == null)
            {
                // Asynchronously leave the current workflow state because we're called from a workflow model method
                IThreadPool threadPool = ServiceRegistration.Get <IThreadPool>();
                threadPool.Add(() =>
                {
                    LeaveCheckResumePlaybackSingleItemState();
                    PlayItem(item);
                });
                return;
            }
            _playMenuItems = new ItemsList();
            ListItem resumeItem = new ListItem
            {
                Command = new MethodDelegateCommand(() =>
                {
                    LeaveCheckResumePlaybackSingleItemState();
                    PlayItem(item, resumeState);
                })
            };
            PositionResumeState positionResume = resumeState as PositionResumeState;

            if (positionResume != null)
            {
                string playbackResume = LocalizationHelper.Translate(Consts.RES_PLAYBACK_RESUME_TIME, positionResume.ResumePosition.ToString(@"hh\:mm\:ss"));
                resumeItem.SetLabel(Consts.KEY_NAME, playbackResume);
            }
            else
            {
                resumeItem.SetLabel(Consts.KEY_NAME, Consts.RES_PLAYBACK_RESUME);
            }
            _playMenuItems.Add(resumeItem);
            ListItem playItem = new ListItem(Consts.KEY_NAME, Consts.RES_PLAYBACK_FROMSTART)
            {
                Command = new MethodDelegateCommand(() =>
                {
                    LeaveCheckResumePlaybackSingleItemState();
                    PlayItem(item);
                })
            };

            _playMenuItems.Add(playItem);
            IScreenManager screenManager = ServiceRegistration.Get <IScreenManager>();

            screenManager.ShowDialog(Consts.DIALOG_PLAY_MENU, (dialogName, dialogInstanceId) => LeaveCheckResumePlaybackSingleItemState());
        }
        void OnMessageReceived(AsynchronousMessageQueue queue, SystemMessage message)
        {
            if (message.ChannelName == PlayerManagerMessaging.CHANNEL)
            {
                // React to player changes
                PlayerManagerMessaging.MessageType messageType = (PlayerManagerMessaging.MessageType)message.MessageType;
                switch (messageType)
                {
                case PlayerManagerMessaging.MessageType.PlayerResumeState:
                    IResumeState        resumeState    = (IResumeState)message.MessageData[PlayerManagerMessaging.KEY_RESUME_STATE];
                    PositionResumeState positionResume = resumeState as PositionResumeState;
                    if (positionResume != null)
                    {
                        TimeSpan resumePosition = positionResume.ResumePosition;
                        _progress = Math.Min((int)(resumePosition.TotalSeconds * 100 / _duration.TotalSeconds), 100);
                    }
                    break;

                case PlayerManagerMessaging.MessageType.PlayerError:
                case PlayerManagerMessaging.MessageType.PlayerEnded:
                case PlayerManagerMessaging.MessageType.PlayerStopped:
                    StopScrobble();
                    break;

                case PlayerManagerMessaging.MessageType.PlayerStarted:
                    var psc = (IPlayerSlotController)message.MessageData[PlayerManagerMessaging.PLAYER_SLOT_CONTROLLER];
                    CreateScrobbleData(psc);
                    StartScrobble();
                    break;
                }
            }
        }
Beispiel #5
0
        protected static bool TryGetPlayDuration(MediaItem mediaItem, IResumeState resumeState, out int playPercentage, out double playDuration)
        {
            playPercentage = 100;
            playDuration   = 0;
            PositionResumeState positionResume = resumeState as PositionResumeState;

            if (positionResume != null)
            {
                TimeSpan resumePosition = positionResume.ResumePosition;
                TimeSpan duration       = TimeSpan.FromSeconds(0);
                IList <MediaItemAspect> aspects;
                if (mediaItem.Aspects.TryGetValue(VideoStreamAspect.ASPECT_ID, out aspects))
                {
                    var  aspect  = aspects.First();
                    int? part    = (int?)aspect[VideoStreamAspect.ATTR_VIDEO_PART];
                    int? partSet = (int?)aspect[VideoStreamAspect.ATTR_VIDEO_PART_SET];
                    long?dur     = null;
                    if (!part.HasValue || part < 0)
                    {
                        dur = (long?)aspect[VideoStreamAspect.ATTR_DURATION];
                    }
                    else if (partSet.HasValue)
                    {
                        dur = aspects.Where(a => (int?)a[VideoStreamAspect.ATTR_VIDEO_PART_SET] == partSet &&
                                            aspect[VideoStreamAspect.ATTR_DURATION] != null).Sum(a => (long)a[VideoStreamAspect.ATTR_DURATION]);
                    }
                    if (dur.HasValue)
                    {
                        duration = TimeSpan.FromSeconds(dur.Value);
                    }
                }
                else if (mediaItem.Aspects.TryGetValue(AudioAspect.ASPECT_ID, out aspects))
                {
                    var  aspect = aspects.First();
                    long?dur    = aspect == null ? null : (long?)aspect[AudioAspect.ATTR_DURATION];
                    if (dur.HasValue)
                    {
                        duration = TimeSpan.FromSeconds(dur.Value);
                    }
                }

                if (duration.TotalSeconds > 0)
                {
                    playPercentage = (int)(resumePosition.TotalSeconds * 100 / duration.TotalSeconds);
                    playDuration   = resumePosition.TotalSeconds;
                }
                else
                {
                    playPercentage = 0;
                    playDuration   = 0;
                }
            }
            if (playPercentage > 100)
            {
                playPercentage = 100;
            }
            return(true);
        }
        private void HandleResumeInfo(IPlayerSlotController psc, Guid mediaItemId, IResumeState resumeState)
        {
            PositionResumeState pos = resumeState as PositionResumeState;

            lock (_syncObj)
                if (_progressUpdateWorks.ContainsKey(psc))
                {
                    _progressUpdateWorks[psc].ResumePosition = pos != null ? pos.ResumePosition : _progressUpdateWorks[psc].Duration;
                }
        }
Beispiel #7
0
        private void SaveResumePosition(SystemMessage message)
        {
            IResumeState        resumeState    = (IResumeState)message.MessageData[PlayerManagerMessaging.KEY_RESUME_STATE];
            PositionResumeState positionResume = resumeState as PositionResumeState;

            if (positionResume != null)
            {
                _resumePosition = positionResume.ResumePosition;
            }
        }
Beispiel #8
0
        /// <summary>
        /// Sets a <see cref="IResumeState"/> to the player. The player is responsible to make the required initializations.
        /// </summary>
        /// <param name="state">Resume state.</param>
        /// <returns><c>true</c> if successful, otherwise <c>false</c>.</returns>
        public virtual bool SetResumeState(IResumeState state)
        {
            PositionResumeState pos = state as PositionResumeState;

            if (pos == null)
            {
                return(false);
            }
            CurrentTime = pos.ResumePosition;
            return(true);
        }
Beispiel #9
0
        /// <summary>
        /// Gets a <see cref="IResumeState"/> from the player.
        /// </summary>
        /// <param name="state">Outputs resume state.</param>
        /// <returns><c>true</c> if successful, otherwise <c>false</c>.</returns>
        public virtual bool GetResumeState(out IResumeState state)
        {
            TimeSpan currentTime = CurrentTime;
            TimeSpan duration    = Duration;

            // If we already played back more then 99%, we don't want to ask user to resume playback.
            if (currentTime.TotalSeconds / duration.TotalSeconds > 0.99)
            {
                state = null;
            }
            else
            {
                state = new PositionResumeState {
                    ResumePosition = CurrentTime
                }
            };
            return(true);
        }
Beispiel #10
0
        /// <summary>
        /// Gets a <see cref="IResumeState"/> from the player.
        /// </summary>
        /// <param name="state">Outputs resume state.</param>
        /// <returns><c>true</c> if successful, otherwise <c>false</c>.</returns>
        public virtual bool GetResumeState(out IResumeState state)
        {
            TimeSpan currentTime = CurrentTime;
            TimeSpan duration    = Duration;

            // If we already played back more then 99%, we don't want to ask user to resume playback.
            if (currentTime.TotalSeconds / duration.TotalSeconds > 0.99)
            {
                state = null;
            }
            else
            {
                state = new PositionResumeState
                {
                    ResumePosition             = CurrentTime,
                    ActiveResourceLocatorIndex = _mediaItem?.ActiveResourceLocatorIndex ?? 0,
                    ActiveEditionIndex         = _mediaItem?.ActiveEditionIndex ?? 0
                }
            };
            return(true);
        }
        protected async Task CheckResumeMenuInternal(MediaItem item, int edition)
        {
            // First make sure the correct edition is selected
            if (edition <= item.MaximumEditionIndex)
            {
                item.ActiveEditionIndex = edition;
            }

            IResumeState    resumeState = null;
            IUserManagement userProfileDataManagement = ServiceRegistration.Get <IUserManagement>();

            if (userProfileDataManagement.IsValidUser)
            {
                var userResult = await userProfileDataManagement.UserProfileDataManagement.GetUserMediaItemDataAsync(userProfileDataManagement.CurrentUser.ProfileId, item.MediaItemId, PlayerContext.KEY_RESUME_STATE);

                if (userResult.Success)
                {
                    resumeState = ResumeStateBase.Deserialize(userResult.Result);
                }
            }

            // Check if resume state matches the current edition, if not start from beginning
            IResumeStateEdition rse = resumeState as IResumeStateEdition;

            if (rse != null && rse.ActiveEditionIndex != edition)
            {
                resumeState = null;
            }

            if (resumeState == null)
            {
                // Asynchronously leave the current workflow state because we're called from a workflow model method
                //await Task.Yield();
                await Task.Run(async() =>
                {
                    LeaveCheckResumePlaybackSingleItemState();
                    await PlayItem(item);
                });

                return;
            }
            _playMenuItems = new ItemsList();
            ListItem resumeItem = new ListItem
            {
                Command = new AsyncMethodDelegateCommand(() =>
                {
                    LeaveCheckResumePlaybackSingleItemState();
                    return(PlayItem(item, resumeState));
                })
            };
            PositionResumeState positionResume = resumeState as PositionResumeState;

            if (positionResume != null)
            {
                string playbackResume = LocalizationHelper.Translate(Consts.RES_PLAYBACK_RESUME_TIME, positionResume.ResumePosition.ToString(@"hh\:mm\:ss"));
                resumeItem.SetLabel(Consts.KEY_NAME, playbackResume);
            }
            else
            {
                resumeItem.SetLabel(Consts.KEY_NAME, Consts.RES_PLAYBACK_RESUME);
            }
            _playMenuItems.Add(resumeItem);
            ListItem playItem = new ListItem(Consts.KEY_NAME, Consts.RES_PLAYBACK_FROMSTART)
            {
                Command = new AsyncMethodDelegateCommand(() =>
                {
                    LeaveCheckResumePlaybackSingleItemState();
                    return(PlayItem(item));
                })
            };

            _playMenuItems.Add(playItem);
            IScreenManager screenManager = ServiceRegistration.Get <IScreenManager>();

            screenManager.ShowDialog(Consts.DIALOG_PLAY_MENU, (dialogName, dialogInstanceId) => LeaveCheckResumePlaybackSingleItemState());
        }
Beispiel #12
0
        public void Init(MediaItem mediaItem)
        {
            if (mediaItem == null)
            {
                SetEmpty();
                return;
            }

            int currentPlayCount;

            MediaItemAspect.TryGetAttribute(mediaItem.Aspects, MediaAspect.ATTR_PLAYCOUNT, 0, out currentPlayCount);

            if (mediaItem.UserData.ContainsKey(UserDataKeysKnown.KEY_PLAY_PERCENTAGE))
            {
                PlayPercentage = Convert.ToInt32(mediaItem.UserData[UserDataKeysKnown.KEY_PLAY_PERCENTAGE]);
            }
            else if (mediaItem.UserData.ContainsKey(PlayerContext.KEY_RESUME_STATE))
            {
                IResumeState        resumeState    = ResumeStateBase.Deserialize(mediaItem.UserData[PlayerContext.KEY_RESUME_STATE]);
                PositionResumeState positionResume = resumeState as PositionResumeState;
                if (positionResume != null)
                {
                    TimeSpan resumePosition = positionResume.ResumePosition;
                    TimeSpan duration       = TimeSpan.FromSeconds(0);
                    IList <MediaItemAspect> aspects;
                    if (mediaItem.Aspects.TryGetValue(VideoStreamAspect.ASPECT_ID, out aspects))
                    {
                        var  aspect  = aspects.First();
                        int? part    = (int?)aspect[VideoStreamAspect.ATTR_VIDEO_PART];
                        int? partSet = (int?)aspect[VideoStreamAspect.ATTR_VIDEO_PART_SET];
                        long?dur     = null;
                        if (!part.HasValue || part < 0)
                        {
                            dur = (long?)aspect[VideoStreamAspect.ATTR_DURATION];
                        }
                        else if (partSet.HasValue)
                        {
                            dur = aspects.Where(a => (int?)a[VideoStreamAspect.ATTR_VIDEO_PART_SET] == partSet &&
                                                aspect[VideoStreamAspect.ATTR_DURATION] != null).Sum(a => (long)a[VideoStreamAspect.ATTR_DURATION]);
                        }
                        if (dur.HasValue)
                        {
                            duration = TimeSpan.FromSeconds(dur.Value);
                        }
                    }
                    else if (mediaItem.Aspects.TryGetValue(AudioAspect.ASPECT_ID, out aspects))
                    {
                        var  aspect = aspects.First();
                        long?dur    = aspect == null ? null : (long?)aspect[AudioAspect.ATTR_DURATION];
                        if (dur.HasValue)
                        {
                            duration = TimeSpan.FromSeconds(dur.Value);
                        }
                    }
                    if (duration.TotalSeconds > 0)
                    {
                        PlayPercentage = (int)(resumePosition.TotalSeconds * 100 / duration.TotalSeconds);
                    }
                    else if (currentPlayCount > 0)
                    {
                        PlayPercentage = 100;
                    }
                    else
                    {
                        PlayPercentage = 0;
                    }
                }
            }
            else
            {
                PlayPercentage = 0;
            }
            if (mediaItem.UserData.ContainsKey(UserDataKeysKnown.KEY_PLAY_COUNT))
            {
                PlayCount = Convert.ToInt32(mediaItem.UserData[UserDataKeysKnown.KEY_PLAY_COUNT]);
            }
            else
            {
                PlayCount = currentPlayCount;
            }
        }
        public virtual void Update(MediaItem mediaItem)
        {
            if (!_mediaItem.Equals(mediaItem))
            {
                throw new ArgumentException("Update can only be done for the same MediaItem!", "mediaItem");
            }

            int?currentPlayCount = null;
            SingleMediaItemAspect mediaAspect;

            if (MediaItemAspect.TryGetAspect(mediaItem.Aspects, MediaAspect.Metadata, out mediaAspect))
            {
                Title            = (string)mediaAspect[MediaAspect.ATTR_TITLE];
                SortString       = (string)mediaAspect[MediaAspect.ATTR_SORT_TITLE];
                Rating           = (int?)mediaAspect[MediaAspect.ATTR_RATING] ?? 0;
                currentPlayCount = (int?)mediaAspect[MediaAspect.ATTR_PLAYCOUNT] ?? 0;
                Virtual          = (bool?)mediaAspect[MediaAspect.ATTR_ISVIRTUAL];
            }

            TimeSpan?duration = null;
            IList <MediaItemAspect> aspects;

            if (mediaItem.Aspects.TryGetValue(VideoStreamAspect.ASPECT_ID, out aspects))
            {
                var  aspect  = aspects.First();
                int? part    = (int?)aspect[VideoStreamAspect.ATTR_VIDEO_PART];
                int? partSet = (int?)aspect[VideoStreamAspect.ATTR_VIDEO_PART_SET];
                long?dur     = null;
                if (!part.HasValue || part < 0)
                {
                    dur = (long?)aspect[VideoStreamAspect.ATTR_DURATION];
                }
                else if (partSet.HasValue)
                {
                    dur = aspects.Where(a => (int?)a[VideoStreamAspect.ATTR_VIDEO_PART_SET] == partSet &&
                                        aspect[VideoStreamAspect.ATTR_DURATION] != null).Sum(a => (long)a[VideoStreamAspect.ATTR_DURATION]);
                }
                if (dur.HasValue)
                {
                    duration = TimeSpan.FromSeconds(dur.Value);
                }
            }
            else if (mediaItem.Aspects.TryGetValue(AudioAspect.ASPECT_ID, out aspects))
            {
                var  aspect = aspects.First();
                long?dur    = aspect == null ? null : (long?)aspect[AudioAspect.ATTR_DURATION];
                if (dur.HasValue)
                {
                    duration = TimeSpan.FromSeconds(dur.Value);
                }
            }
            else if (mediaItem.Aspects.TryGetValue(MovieAspect.ASPECT_ID, out aspects))
            {
                var aspect = aspects.First();
                int?dur    = aspect == null ? null : (int?)aspect[MovieAspect.ATTR_RUNTIME_M];
                if (dur.HasValue)
                {
                    duration = TimeSpan.FromMinutes(dur.Value);
                }
            }
            Duration = duration.HasValue ? FormattingUtils.FormatMediaDuration(duration.Value) : string.Empty;

            if (mediaItem.UserData.ContainsKey(UserDataKeysKnown.KEY_PLAY_PERCENTAGE))
            {
                WatchPercentage = mediaItem.UserData[UserDataKeysKnown.KEY_PLAY_PERCENTAGE];
            }
            else if (mediaItem.UserData.ContainsKey(PlayerContext.KEY_RESUME_STATE))
            {
                IResumeState        resumeState    = ResumeStateBase.Deserialize(mediaItem.UserData[PlayerContext.KEY_RESUME_STATE]);
                PositionResumeState positionResume = resumeState as PositionResumeState;
                if (positionResume != null && duration.HasValue)
                {
                    TimeSpan resumePosition = positionResume.ResumePosition;
                    if (duration.Value.TotalSeconds > 0)
                    {
                        WatchPercentage = ((int)(resumePosition.TotalSeconds * 100 / duration.Value.TotalSeconds)).ToString();
                    }
                    else if (currentPlayCount > 0)
                    {
                        WatchPercentage = "100";
                    }
                    else
                    {
                        WatchPercentage = "0";
                    }
                }
            }

            if (mediaItem.UserData.ContainsKey(UserDataKeysKnown.KEY_PLAY_COUNT))
            {
                PlayCount = Convert.ToInt32(mediaItem.UserData[UserDataKeysKnown.KEY_PLAY_COUNT]);
            }
            else if (currentPlayCount.HasValue)
            {
                PlayCount = currentPlayCount.Value;
            }

            FireChange();
        }