private static async void DispatcherTimerOnTick(object sender, EventArgs eventArgs)
        {
            if (_apiClient == null || BackgroundAudioPlayer.Instance.PlayerState != PlayState.Playing)
            {
                return;
            }

            try
            {
                var track = BackgroundAudioPlayer.Instance.Track;
                var info  = new PlaybackProgressInfo
                {
                    ItemId = track.Tag,
                    //UserId = _apiClient.CurrentUserId,
                    PositionTicks = BackgroundAudioPlayer.Instance.Position.Ticks,
                    IsMuted       = false,
                    IsPaused      = false
                };

                await _apiClient.ReportPlaybackProgressAsync(info);
            }
            catch (HttpException ex)
            {
                _logger.FatalException("DispatcherTimerOnTick()", ex);
            }
        }
Пример #2
0
        /// <summary>
        /// Updates the now playing item id.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="info">The information.</param>
        /// <param name="libraryItem">The library item.</param>
        private void UpdateNowPlayingItem(SessionInfo session, PlaybackProgressInfo info, BaseItem libraryItem)
        {
            var runtimeTicks = libraryItem.RunTimeTicks;

            if (string.IsNullOrWhiteSpace(info.MediaSourceId))
            {
                info.MediaSourceId = info.ItemId;
            }

            if (!string.Equals(info.ItemId, info.MediaSourceId) &&
                !string.IsNullOrWhiteSpace(info.MediaSourceId))
            {
                runtimeTicks = _libraryManager.GetItemById(new Guid(info.MediaSourceId)).RunTimeTicks;
            }

            if (!string.IsNullOrWhiteSpace(info.ItemId))
            {
                info.Item = GetItemInfo(libraryItem, runtimeTicks);
            }

            session.NowPlayingItem   = info.Item;
            session.LastActivityDate = DateTime.UtcNow;

            session.PlayState.IsPaused            = info.IsPaused;
            session.PlayState.PositionTicks       = info.PositionTicks;
            session.PlayState.MediaSourceId       = info.MediaSourceId;
            session.PlayState.CanSeek             = info.CanSeek;
            session.PlayState.IsMuted             = info.IsMuted;
            session.PlayState.VolumeLevel         = info.VolumeLevel;
            session.PlayState.AudioStreamIndex    = info.AudioStreamIndex;
            session.PlayState.SubtitleStreamIndex = info.SubtitleStreamIndex;
            session.PlayState.PlayMethod          = info.PlayMethod;
        }
Пример #3
0
        /// <summary>
        /// Used to report playback progress for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackProgress(PlaybackProgressInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            var session = GetSession(info.SessionId);

            var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
                ? null
                : _libraryManager.GetItemById(new Guid(info.ItemId));

            UpdateNowPlayingItem(session, info, libraryItem);

            var users = GetUsers(session);

            if (libraryItem != null)
            {
                var key = libraryItem.GetUserDataKey();

                foreach (var user in users)
                {
                    await OnPlaybackProgress(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false);
                }
            }

            EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
            {
                Item  = libraryItem,
                Users = users,
                PlaybackPositionTicks = session.PlayState.PositionTicks,
                MediaSourceId         = session.PlayState.MediaSourceId
            }, _logger);
        }
Пример #4
0
        /// <summary>
        /// Timers the callback.
        /// </summary>
        /// <param name="state">The state.</param>
        private async void TimerCallback(object state)
        {
            var item = _mediaPlayer.CurrentMedia;

            if (item == null)
            {
                return;
            }

            var info = new PlaybackProgressInfo
            {
                //SessionId = _sessionManager
                //Item = item,
                ItemId = item.Id,
                //MediaSourceId = string.Empty,
                IsMuted             = _playback.IsMuted,
                IsPaused            = _mediaPlayer.PlayState == PlayState.Paused,
                PositionTicks       = _mediaPlayer.CurrentPositionTicks,
                CanSeek             = _mediaPlayer.CanSeek,
                AudioStreamIndex    = _mediaPlayer.CurrentAudioStreamIndex,
                SubtitleStreamIndex = _mediaPlayer.CurrentSubtitleStreamIndex,
                VolumeLevel         = (_mediaPlayer.PlayState != PlayState.Idle) ? (int?)_playback.Volume : null,
                PlayMethod          = PlayMethod.DirectPlay, // todo remove hard coding
            };

            try
            {
                await _apiClient.ReportPlaybackProgressAsync(info);
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error sending playback progress checking for {0}", ex, item.Name);
            }
        }
Пример #5
0
        /// <summary>
        /// Used to report playback progress for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackProgress(PlaybackProgressInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = Sessions.First(i => i.Id.Equals(info.SessionId));

            UpdateNowPlayingItem(session, info.Item, info.IsPaused, info.IsMuted, info.PositionTicks);

            var key = info.Item.GetUserDataKey();

            var users = GetUsers(session);

            foreach (var user in users)
            {
                await OnPlaybackProgress(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
            }

            EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
            {
                Item  = info.Item,
                Users = users,
                PlaybackPositionTicks = info.PositionTicks
            }, _logger);
        }
Пример #6
0
        private async void TimerOnTick(object sender, EventArgs eventArgs)
        {
            try
            {
                var totalTicks = _startPositionTicks + PlayedVideoDuration.Ticks;

                Log.Info("Sending current runtime [{0}] to the server", totalTicks);

                var info = new PlaybackProgressInfo
                {
                    ItemId        = _itemId,
                    IsMuted       = false,
                    IsPaused      = false,
                    PositionTicks = totalTicks
                };

                await _playbackManager.ReportPlaybackProgress(info, _streamInfo, false, ApiClient);

                SetPlaybackTicks(totalTicks);
            }
            catch (HttpException ex)
            {
                Utils.HandleHttpException("TimerOnTick()", ex, NavigationService, Log);
            }
        }
 /// <summary>
 /// Reports playback progress
 /// </summary>
 /// <param name="info">The information.</param>
 /// <param name="isOffline">if set to <c>true</c> [is offline].</param>
 /// <param name="apiClient">The current apiClient. It can be null if offline</param>
 /// <returns>Task.</returns>
 public async Task ReportPlaybackProgress(PlaybackProgressInfo info, bool isOffline, IApiClient apiClient)
 {
     if (!isOffline)
     {
         await apiClient.ReportPlaybackProgressAsync(info).ConfigureAwait(false);
     }
 }
Пример #8
0
        public async Task <ActionResult> ReportPlaybackProgress([FromBody] PlaybackProgressInfo playbackProgressInfo)
        {
            playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
            playbackProgressInfo.SessionId  = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
            await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);

            return(NoContent());
        }
Пример #9
0
        /// <summary>
        /// Reports the playback progress.
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnPlaybackProgress(WebSocketMessageInfo message)
        {
            var session = GetSessionFromMessage(message);

            if (session != null && session.UserId.HasValue)
            {
                var vals = message.Data.Split('|');

                var itemId = vals[0];

                long?positionTicks = null;

                if (vals.Length > 1)
                {
                    long pos;

                    if (long.TryParse(vals[1], out pos))
                    {
                        positionTicks = pos;
                    }
                }

                var isPaused = vals.Length > 2 && string.Equals(vals[2], "true", StringComparison.OrdinalIgnoreCase);
                var isMuted  = vals.Length > 3 && string.Equals(vals[3], "true", StringComparison.OrdinalIgnoreCase);

                var info = new PlaybackProgressInfo
                {
                    ItemId        = itemId,
                    PositionTicks = positionTicks,
                    IsMuted       = isMuted,
                    IsPaused      = isPaused,
                    SessionId     = session.Id
                };

                if (vals.Length > 4)
                {
                    info.MediaSourceId = vals[4];
                }

                if (vals.Length > 5 && !string.IsNullOrWhiteSpace(vals[5]))
                {
                    info.VolumeLevel = int.Parse(vals[5], _usCulture);
                }

                if (vals.Length > 5 && !string.IsNullOrWhiteSpace(vals[6]))
                {
                    info.AudioStreamIndex = int.Parse(vals[6], _usCulture);
                }

                if (vals.Length > 7 && !string.IsNullOrWhiteSpace(vals[7]))
                {
                    info.SubtitleStreamIndex = int.Parse(vals[7], _usCulture);
                }

                _sessionManager.OnPlaybackProgress(info);
            }
        }
Пример #10
0
        public async Task UpdatePlaybackStatus(string mediaSourceId, TimeSpan position)
        {
            PlaybackProgressInfo data = new PlaybackProgressInfo();

            if (Guid.TryParse(mediaSourceId, out Guid itemId))
            {
                data.ItemId = itemId;
            }

            data.MediaSourceId = mediaSourceId;
            data.PositionTicks = position.Ticks;
            await DoPost("Sessions/Playing/Progress", data);
        }
Пример #11
0
        /// <summary>
        /// Reports playback progress
        /// </summary>
        /// <param name="info">The information.</param>
        /// <param name="streamInfo">The stream information.</param>
        /// <param name="isOffline">if set to <c>true</c> [is offline].</param>
        /// <param name="apiClient">The current apiClient. It can be null if offline</param>
        /// <returns>Task.</returns>
        public async Task ReportPlaybackProgress(PlaybackProgressInfo info, StreamInfo streamInfo, bool isOffline, IApiClient apiClient)
        {
            if (!isOffline)
            {
                if (streamInfo != null)
                {
                    info.PlaySessionId = streamInfo.PlaySessionId;

                    if (streamInfo.MediaSource != null)
                    {
                        info.LiveStreamId = streamInfo.MediaSource.LiveStreamId;
                    }
                }

                await apiClient.ReportPlaybackProgressAsync(info).ConfigureAwait(false);
            }
        }
Пример #12
0
        /// <summary>
        /// Posts the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        public void Post(OnPlaybackProgress request)
        {
            var user = _userManager.GetUserById(request.UserId);

            var item = _dtoService.GetItemByDtoId(request.Id, user.Id);

            var info = new PlaybackProgressInfo
            {
                Item          = item,
                PositionTicks = request.PositionTicks,
                IsMuted       = request.IsMuted,
                IsPaused      = request.IsPaused,
                SessionId     = GetSession().Id
            };

            var task = _sessionManager.OnPlaybackProgress(info);

            Task.WaitAll(task);
        }
Пример #13
0
        public async Task <ActionResult> OnPlaybackProgress(
            [FromRoute, Required] Guid userId,
            [FromRoute, Required] Guid itemId,
            [FromQuery] string?mediaSourceId,
            [FromQuery] long?positionTicks,
            [FromQuery] int?audioStreamIndex,
            [FromQuery] int?subtitleStreamIndex,
            [FromQuery] int?volumeLevel,
            [FromQuery] PlayMethod?playMethod,
            [FromQuery] string?liveStreamId,
            [FromQuery] string?playSessionId,
            [FromQuery] RepeatMode?repeatMode,
            [FromQuery] bool isPaused = false,
            [FromQuery] bool isMuted  = false)
        {
            var playbackProgressInfo = new PlaybackProgressInfo
            {
                ItemId              = itemId,
                PositionTicks       = positionTicks,
                IsMuted             = isMuted,
                IsPaused            = isPaused,
                MediaSourceId       = mediaSourceId,
                AudioStreamIndex    = audioStreamIndex,
                SubtitleStreamIndex = subtitleStreamIndex,
                VolumeLevel         = volumeLevel,
                PlayMethod          = playMethod ?? PlayMethod.Transcode,
                PlaySessionId       = playSessionId,
                LiveStreamId        = liveStreamId,
                RepeatMode          = repeatMode ?? RepeatMode.RepeatNone
            };

            playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
            playbackProgressInfo.SessionId  = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);

            await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);

            return(NoContent());
        }
Пример #14
0
        /// <summary>
        /// Reports the playback progress.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ReportPlaybackProgress(WebSocketMessageInfo message)
        {
            var session = GetSessionFromMessage(message);

            if (session != null && session.User != null)
            {
                var vals = message.Data.Split('|');

                var item = _dtoService.GetItemByDtoId(vals[0]);

                long?positionTicks = null;

                if (vals.Length > 1)
                {
                    long pos;

                    if (long.TryParse(vals[1], out pos))
                    {
                        positionTicks = pos;
                    }
                }

                var isPaused = vals.Length > 2 && string.Equals(vals[2], "true", StringComparison.OrdinalIgnoreCase);
                var isMuted  = vals.Length > 3 && string.Equals(vals[3], "true", StringComparison.OrdinalIgnoreCase);

                var info = new PlaybackProgressInfo
                {
                    Item          = item,
                    PositionTicks = positionTicks,
                    IsMuted       = isMuted,
                    IsPaused      = isPaused,
                    SessionId     = session.Id
                };

                _sessionManager.OnPlaybackProgress(info);
            }
        }
Пример #15
0
        /// <summary>
        /// Used to report playback progress for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackProgress(PlaybackProgressInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = Sessions.First(i => i.Id.Equals(info.SessionId));

            UpdateNowPlayingItem(session, info.Item, info.IsPaused, info.IsMuted, info.PositionTicks);

            var key = info.Item.GetUserDataKey();

            var user = session.User;

            if (info.PositionTicks.HasValue)
            {
                var data = _userDataRepository.GetUserData(user.Id, key);

                UpdatePlayState(info.Item, data, info.PositionTicks.Value);

                await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
            }

            EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
            {
                Item = info.Item,
                User = user,
                PlaybackPositionTicks = info.PositionTicks
            }, _logger);
        }
Пример #16
0
        /// <summary>
        /// Used to report playback progress for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackProgress(PlaybackProgressInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            var session = GetSession(info.SessionId);

            var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
                ? null
                : _libraryManager.GetItemById(new Guid(info.ItemId));

            UpdateNowPlayingItem(session, info, libraryItem);

            var users = GetUsers(session);

            if (libraryItem != null)
            {
                var key = libraryItem.GetUserDataKey();

                foreach (var user in users)
                {
                    await OnPlaybackProgress(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false);
                }
            }

            EventHelper.FireEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
            {
                Item = libraryItem,
                Users = users,
                PlaybackPositionTicks = session.PlayState.PositionTicks,
                MediaSourceId = session.PlayState.MediaSourceId,
                MediaInfo = info.Item,
                DeviceName = session.DeviceName,
                ClientName = session.Client,
                DeviceId = session.DeviceId

            }, _logger);
        }
Пример #17
0
        /// <summary>
        /// Updates the now playing item id.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="info">The information.</param>
        /// <param name="libraryItem">The library item.</param>
        private void UpdateNowPlayingItem(SessionInfo session, PlaybackProgressInfo info, BaseItem libraryItem)
        {
            var runtimeTicks = libraryItem == null ? null : libraryItem.RunTimeTicks;

            if (string.IsNullOrWhiteSpace(info.MediaSourceId))
            {
                info.MediaSourceId = info.ItemId;
            }

            if (!string.Equals(info.ItemId, info.MediaSourceId) &&
                !string.IsNullOrWhiteSpace(info.MediaSourceId))
            {
                runtimeTicks = _libraryManager.GetItemById(new Guid(info.MediaSourceId)).RunTimeTicks;
            }

            if (!string.IsNullOrWhiteSpace(info.ItemId) && libraryItem != null)
            {
                var current = session.NowPlayingItem;

                if (current == null || !string.Equals(current.Id, info.ItemId, StringComparison.OrdinalIgnoreCase))
                {
                    info.Item = GetItemInfo(libraryItem, libraryItem, info.MediaSourceId);
                }
                else
                {
                    info.Item = current;
                }

                info.Item.RunTimeTicks = runtimeTicks;
            }

            session.NowPlayingItem = info.Item;
            session.LastActivityDate = DateTime.UtcNow;

            session.PlayState.IsPaused = info.IsPaused;
            session.PlayState.PositionTicks = info.PositionTicks;
            session.PlayState.MediaSourceId = info.MediaSourceId;
            session.PlayState.CanSeek = info.CanSeek;
            session.PlayState.IsMuted = info.IsMuted;
            session.PlayState.VolumeLevel = info.VolumeLevel;
            session.PlayState.AudioStreamIndex = info.AudioStreamIndex;
            session.PlayState.SubtitleStreamIndex = info.SubtitleStreamIndex;
            session.PlayState.PlayMethod = info.PlayMethod;
        }
Пример #18
0
        /// <summary>
        /// Used to report playback progress for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackProgress(PlaybackProgressInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = Sessions.First(i => i.Id.Equals(info.SessionId));

            UpdateNowPlayingItem(session, info.Item, info.IsPaused, info.IsMuted, info.PositionTicks);

            var key = info.Item.GetUserDataKey();

            var user = session.User;

            if (info.PositionTicks.HasValue)
            {
                var data = _userDataRepository.GetUserData(user.Id, key);

                UpdatePlayState(info.Item, data, info.PositionTicks.Value);

                await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
            }

            EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
            {
                Item = info.Item,
                User = user,
                PlaybackPositionTicks = info.PositionTicks

            }, _logger);
        }
Пример #19
0
        public override void WireMessages()
        {
            Messenger.Default.Register <VideoMessage>(this, m =>
            {
                PlaylistItems = null;
                switch (m.PlayerSourceType)
                {
                case PlayerSourceType.Video:
                    if (m.VideoItem != null)
                    {
                        SelectedItem  = m.VideoItem;
                        PlaylistItems = null;
                    }
                    break;

                case PlayerSourceType.Recording:
                    if (m.VideoItem != null)
                    {
                        RecordingItem = m.VideoItem;
                        PlaylistItems = null;
                    }
                    break;

                case PlayerSourceType.Programme:
                    if (m.VideoItem != null)
                    {
                        ProgrammeItem = m.VideoItem;
                        PlaylistItems = null;
                    }
                    break;

                case PlayerSourceType.Playlist:
                    PlaylistItems = m.VideoPlaylists;
                    SelectedItem  = m.VideoItem;
                    break;
                }

                PlayerSourceType    = m.PlayerSourceType;
                _isResume           = m.IsResume;
                _startPositionTicks = m.ResumeTicks ?? 0;
            });

            Messenger.Default.Register <NotificationMessage>(this, async m =>
            {
                if (m.Notification.Equals(Constants.Messages.SetResumeMsg))
                {
                    _isResume = true;
                }

                if (m.Notification.Equals(Constants.Messages.SendVideoTimeToServerMsg))
                {
                    try
                    {
                        var totalTicks = _startPositionTicks + PlayedVideoDuration.Ticks;

                        Log.Info("Sending current runtime [{0}] to the server", totalTicks);

                        var info = new PlaybackStopInfo
                        {
                            ItemId        = _itemId,
                            PositionTicks = totalTicks
                        };

                        await _playbackManager.ReportPlaybackStopped(info, _streamInfo, App.ServerInfo.Id, AuthenticationService.Current.LoggedInUserId, false, ApiClient);

                        SetPlaybackTicks(totalTicks);

                        if (_timer != null && _timer.IsEnabled)
                        {
                            _timer.Stop();
                        }

                        Messenger.Default.Send(new NotificationMessage(_itemId, totalTicks, Constants.Messages.RefreshResumeMsg));
                    }
                    catch (HttpException ex)
                    {
                        Utils.HandleHttpException("SendVideoTimeToServer", ex, NavigationService, Log);
                    }

                    if (!PlaylistItems.IsNullOrEmpty())
                    {
                        var index = PlaylistItems.IndexOf(SelectedItem);
                        if (index >= 0 && index < PlaylistItems.Count - 1)
                        {
                            SelectedItem = PlaylistItems[index + 1];
                            await InitiatePlayback(false);
                        }
                    }
                }

                if (m.Notification.Equals(Constants.Messages.VideoStateChangedMsg))
                {
                    try
                    {
                        var totalTicks = _startPositionTicks + PlayedVideoDuration.Ticks;
                        var isPaused   = m.Sender != null && (bool)m.Sender;

                        if (_timer != null)
                        {
                            if (isPaused)
                            {
                                if (_timer.IsEnabled)
                                {
                                    _timer.Stop();
                                }
                            }
                            else
                            {
                                if (!_timer.IsEnabled)
                                {
                                    _timer.Start();
                                }
                            }
                        }

                        Log.Info("Sending current runtime [{0}] to the server", totalTicks);

                        var info = new PlaybackProgressInfo
                        {
                            IsMuted       = false,
                            ItemId        = _itemId,
                            PositionTicks = totalTicks,
                            IsPaused      = isPaused
                        };

                        await ApiClient.ReportPlaybackProgressAsync(info);
                        SetPlaybackTicks(totalTicks);
                    }
                    catch (HttpException ex)
                    {
                        Utils.HandleHttpException("VideoStateChanged", ex, NavigationService, Log);
                    }
                }
            });
        }
        /// <summary>
        /// Reports the playback progress.
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnPlaybackProgress(WebSocketMessageInfo message)
        {
            var session = GetSessionFromMessage(message);

            if (session != null && session.UserId.HasValue)
            {
                var vals = message.Data.Split('|');

                var itemId = vals[0];

                long? positionTicks = null;

                if (vals.Length > 1)
                {
                    long pos;

                    if (long.TryParse(vals[1], out pos))
                    {
                        positionTicks = pos;
                    }
                }

                var isPaused = vals.Length > 2 && string.Equals(vals[2], "true", StringComparison.OrdinalIgnoreCase);
                var isMuted = vals.Length > 3 && string.Equals(vals[3], "true", StringComparison.OrdinalIgnoreCase);

                var info = new PlaybackProgressInfo
                {
                    ItemId = itemId,
                    PositionTicks = positionTicks,
                    IsMuted = isMuted,
                    IsPaused = isPaused,
                    SessionId = session.Id
                };

                if (vals.Length > 4)
                {
                    info.MediaSourceId = vals[4];
                }

                if (vals.Length > 5 && !string.IsNullOrWhiteSpace(vals[5]))
                {
                    info.VolumeLevel = int.Parse(vals[5], _usCulture);
                }

                if (vals.Length > 5 && !string.IsNullOrWhiteSpace(vals[6]))
                {
                    info.AudioStreamIndex = int.Parse(vals[6], _usCulture);
                }

                if (vals.Length > 7 && !string.IsNullOrWhiteSpace(vals[7]))
                {
                    info.SubtitleStreamIndex = int.Parse(vals[7], _usCulture);
                }

                _sessionManager.OnPlaybackProgress(info);
            }
        }
        private void ReportEmbyStatus()
        {
            //used to report position on stop - by the time the reporter polls, the player might have closed already
            //long lastPosition = 0;
            //when MPC-HC is loading a file, its state is None;
            //before playback starts properly, newer versions of MPC-HC may also report Paused or even Stopped
            //This flag prevents the reporter from terminating before the player loads the file
            bool startedPlaying = false;

            var stopwatch = new Stopwatch();

            log.Debug("ProgressReporter thread starting");
            for (;;)
            {
                stopwatch.Start();
                var status = player.GetPlayerStatus();

                if (!startedPlaying)
                {
                    startedPlaying = status.State == PlayerState.Playing;
                }
                else
                {
                    if (status.State == PlayerState.Stopped)
                    {
                        log.Info("MPC-HC is no longer playing");
                        var stopInfo = new PlaybackStopInfo
                        {
                            ItemId        = itemId,
                            PositionTicks = status.Position * Utils.EmbyTicksPerMs
                        };
                        Utils.IgnoreExceptions(() => embyClient.ReportPlaybackStoppedAsync(stopInfo).Wait());
                        OnPlayerStopped(EventArgs.Empty);
                        log.Info("Progress reporter terminating");
                        return;
                    }

                    var progressInfo = new PlaybackProgressInfo
                    {
                        CanSeek       = player.CanSeek(),
                        IsPaused      = status.State == PlayerState.Paused,
                        IsMuted       = status.Muted,
                        ItemId        = itemId,
                        PlayMethod    = PlayMethod.DirectPlay,
                        PositionTicks = status.Position * Utils.EmbyTicksPerMs,
                        VolumeLevel   = status.VolumeLevel,
                        RepeatMode    = RepeatMode.RepeatNone
                    };
                    Utils.IgnoreExceptions(() => embyClient.ReportPlaybackProgressAsync(progressInfo).Wait());
                    //lastPosition = status.Position;
                }

                stopwatch.Stop();
                int sleepTime = reportPeriod - (int)stopwatch.ElapsedMilliseconds;
                log.DebugFormat("Status report took {0}ms.", stopwatch.ElapsedMilliseconds);
                lock (monitor)
                {
                    if (stop)
                    {
                        break;
                    }
                    if (sleepTime > 0)
                    {
                        Monitor.Wait(monitor, sleepTime);
                    }
                    if (stop)
                    {
                        break;
                    }
                }
                stopwatch.Reset();
            }
        }
Пример #22
0
        /// <summary>
        /// Used to report playback progress for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackProgress(PlaybackProgressInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = Sessions.First(i => i.Id.Equals(info.SessionId));

            UpdateNowPlayingItem(session, info.Item, info.IsPaused, info.IsMuted, info.PositionTicks);

            var key = info.Item.GetUserDataKey();

            var users = GetUsers(session);

            foreach (var user in users)
            {
                await OnPlaybackProgress(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
            }

            EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
            {
                Item = info.Item,
                Users = users,
                PlaybackPositionTicks = info.PositionTicks

            }, _logger);
        }