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> /// Handles the MediaChanged event of the _mediaPlayer control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="MediaChangeEventArgs"/> instance containing the event data.</param> async void _mediaPlayer_MediaChanged(object sender, MediaChangeEventArgs e) { if (e.PreviousMedia != null) { var info = new PlaybackStopInfo { ItemId = e.PreviousMedia.Id, UserId = _apiClient.CurrentUserId, PositionTicks = e.EndingPositionTicks }; try { await _apiClient.ReportPlaybackStoppedAsync(info); } catch (Exception ex) { _logger.ErrorException("Error sending playback stopped checking for {0}", ex, e.PreviousMedia.Name); } } if (e.NewMedia != null) { try { var queueTypes = _mediaPlayer.CanQueue ? new List<string> { e.NewMedia.MediaType } : new List<string> { }; var info = new PlaybackStartInfo { ItemId = e.NewMedia.Id, UserId = _apiClient.CurrentUserId, IsSeekable = _mediaPlayer.CanSeek, QueueableMediaTypes = queueTypes.ToArray() }; await _apiClient.ReportPlaybackStartAsync(info); } catch (Exception ex) { _logger.ErrorException("Error sending playback start checking for {0}", ex, e.NewMedia.Name); } } }
/// <summary> /// Handles the PlaybackCompleted event of the _mediaPlayer control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="PlaybackStopEventArgs"/> instance containing the event data.</param> async void _mediaPlayer_PlaybackCompleted(object sender, PlaybackStopEventArgs e) { _mediaPlayer.MediaChanged -= _mediaPlayer_MediaChanged; _mediaPlayer.PlaybackCompleted -= _mediaPlayer_PlaybackCompleted; if (_timer != null) { _timer.Dispose(); _timer = null; } if (e.EndingMedia != null) { var info = new PlaybackStopInfo { ItemId = e.EndingMedia.Id, UserId = _apiClient.CurrentUserId, PositionTicks = e.EndingPositionTicks }; try { await _apiClient.ReportPlaybackStoppedAsync(info); } catch (Exception ex) { _logger.ErrorException("Error sending playback stopped checking for {0}", ex, e.EndingMedia.Name); } } }
/// <summary> /// Handles the MediaChanged event of the _mediaPlayer control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="MediaChangeEventArgs"/> instance containing the event data.</param> async void _mediaPlayer_MediaChanged(object sender, MediaChangeEventArgs e) { if (e.PreviousMedia != null) { var info = new PlaybackStopInfo { ItemId = e.PreviousMedia.Id, PositionTicks = e.EndingPositionTicks }; var apiClient = _connectionManager.GetApiClient(e.PreviousMedia); try { await apiClient.ReportPlaybackStoppedAsync(info); } catch (Exception ex) { _logger.ErrorException("Error sending playback stopped checking for {0}", ex, e.PreviousMedia.Name); } } if (e.NewMedia != null) { try { var queueTypes = _mediaPlayer.CanQueue ? new List<string> { e.NewMedia.MediaType } : new List<string> { }; var info = new PlaybackStartInfo { ItemId = e.NewMedia.Id, CanSeek = _mediaPlayer.CanSeek, QueueableMediaTypes = queueTypes.ToList(), // TODO: Remove this hardcoding PlayMethod = PlayMethod.DirectPlay }; var apiClient = _connectionManager.GetApiClient(e.NewMedia); await apiClient.ReportPlaybackStartAsync(info); } catch (Exception ex) { _logger.ErrorException("Error sending playback start checking for {0}", ex, e.NewMedia.Name); } } }
/// <summary> /// Handles the PlaybackCompleted event of the _mediaPlayer control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="eventArgs">The <see cref="PlaybackStopEventArgs"/> instance containing the event data.</param> async void _mediaPlayer_PlaybackCompleted(object sender, PlaybackStopEventArgs eventArgs) { _mediaPlayer.MediaChanged -= _mediaPlayer_MediaChanged; _mediaPlayer.PlaybackCompleted -= _mediaPlayer_PlaybackCompleted; var item = eventArgs.EndingMedia; if (item != null) { var apiClient = _connectionManager.GetApiClient(item); var stopInfo = new PlaybackStopInfo { ItemId = item.Id, PositionTicks = eventArgs.EndingPositionTicks }; // Have to test this for null because external players are currently not supplying this // Also some players will play in contexts not currently supported by common playback managers, e.g. direct play of folder rips, and iso-mounted media // Remove when implemented if (eventArgs.StreamInfo != null) { await _apiPlaybackManager.ReportPlaybackStopped(stopInfo, eventArgs.StreamInfo, item.ServerId, apiClient.CurrentUserId, false, apiClient); } else { await apiClient.ReportPlaybackStoppedAsync(stopInfo); } } var timer = _timer; if (timer != null) { timer.Dispose(); _timer = null; } }
/// <summary> /// Handles the MediaChanged event of the _mediaPlayer control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="eventArgs">The <see cref="MediaChangeEventArgs"/> instance containing the event data.</param> async void _mediaPlayer_MediaChanged(object sender, MediaChangeEventArgs eventArgs) { if (eventArgs.PreviousMedia != null) { var apiClient = _connectionManager.GetApiClient(eventArgs.PreviousMedia); var stopInfo = new PlaybackStopInfo { ItemId = eventArgs.PreviousMedia.Id, PositionTicks = eventArgs.EndingPositionTicks }; // Have to test this for null because external players are currently not supplying this // Also some players will play in contexts not currently supported by common playback managers, e.g. direct play of folder rips, and iso-mounted media // Remove when implemented if (eventArgs.PreviousStreamInfo != null) { await _apiPlaybackManager.ReportPlaybackStopped(stopInfo, eventArgs.PreviousStreamInfo, eventArgs.PreviousMedia.ServerId, apiClient.CurrentUserId, false, apiClient); } else { await apiClient.ReportPlaybackStoppedAsync(stopInfo); } } if (eventArgs.NewMedia != null) { try { var queueTypes = _mediaPlayer.CanQueue ? new List<string> { eventArgs.NewMedia.MediaType } : new List<string> { }; var info = new PlaybackStartInfo { ItemId = eventArgs.NewMedia.Id, CanSeek = _mediaPlayer.CanSeek, QueueableMediaTypes = queueTypes.ToList(), // TODO: Remove this hardcoding PlayMethod = PlayMethod.DirectPlay }; var apiClient = _connectionManager.GetApiClient(eventArgs.NewMedia); await apiClient.ReportPlaybackStartAsync(info); } catch (Exception ex) { _logger.ErrorException("Error sending internalPlaybackManager start checking for {0}", ex, eventArgs.NewMedia.Name); } } }
/// <summary> /// Reports playback progress /// </summary> /// <param name="info">The information.</param> /// <param name="streamInfo">The stream information.</param> /// <param name="serverId">The server identifier.</param> /// <param name="userId">The user identifier.</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 ReportPlaybackStopped(PlaybackStopInfo info, StreamInfo streamInfo, string serverId, string userId, bool isOffline, IApiClient apiClient) { if (isOffline) { var action = new UserAction { Date = DateTime.UtcNow, ItemId = info.ItemId, PositionTicks = info.PositionTicks, ServerId = serverId, Type = UserActionType.PlayedItem, UserId = userId }; await _localAssetManager.RecordUserAction(action).ConfigureAwait(false); return; } if (streamInfo != null) { info.PlaySessionId = streamInfo.PlaySessionId; if (streamInfo.MediaSource != null) { info.LiveStreamId = streamInfo.MediaSource.LiveStreamId; } } // Put a try/catch here because we need to stop transcoding regardless try { await apiClient.ReportPlaybackStoppedAsync(info).ConfigureAwait(false); } catch (Exception ex) { _logger.ErrorException("Error in ReportPlaybackStoppedAsync", ex); } }
private async Task InformOfStoppedTrack() { if (_apiClient == null) { return; } try { var track = BackgroundAudioPlayer.Instance.Track; if (track != null) { var info = new PlaybackStopInfo { ItemId = track.Tag, //UserId = _apiClient.CurrentUserId }; await _apiClient.ReportPlaybackStoppedAsync(info); } } catch (HttpException ex) { _logger.FatalException("InformOfStoppedTrack()", ex); } NotifyComplete(); }