/// <summary> /// Media playback has stopped. Depending on playback progress, let Trakt.tv know the user has /// completed watching the item. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void KernelPlaybackStopped(object sender, PlaybackStopEventArgs e) { if (e.Users == null || !e.Users.Any() || e.Item == null) { _logger.Error("Event details incomplete. Cannot process current media"); return; } try { var traktUser = UserHelper.GetTraktUser(e.Users.FirstOrDefault()); if (traktUser == null) { _logger.Error("Could not match trakt user"); return; } if (!_traktApi.CanSync(e.Item, traktUser)) { return; } var video = e.Item as Video; if (e.PlayedToCompletion) { _logger.Info("Item is played. Scrobble"); try { if (video is Movie) { await _traktApi.SendMovieStatusUpdateAsync(video as Movie, MediaStatus.Stop, traktUser, 100). ConfigureAwait(false); } else if (video is Episode) { await _traktApi.SendEpisodeStatusUpdateAsync(video as Episode, MediaStatus.Stop, traktUser, 100) .ConfigureAwait(false); } } catch (Exception ex) { _logger.ErrorException("Exception handled sending status update", ex); } } else { var progressPercent = video.RunTimeTicks.HasValue && video.RunTimeTicks != 0 ? (float)(e.PlaybackPositionTicks ?? 0) / video.RunTimeTicks.Value * 100.0f : 0.0f; _logger.Info("Item Not fully played. Tell trakt.tv we are no longer watching but don't scrobble"); if (video is Movie) { await _traktApi.SendMovieStatusUpdateAsync(video as Movie, MediaStatus.Stop, traktUser, progressPercent); } else { await _traktApi.SendEpisodeStatusUpdateAsync(video as Episode, MediaStatus.Stop, traktUser, progressPercent); } } } catch (Exception ex) { _logger.ErrorException("Error sending scrobble", ex, null); } // No longer need to track the item var playEvent = _progressEvents.FirstOrDefault(ev => ev.UserId.Equals(e.Users.First().Id) && ev.ItemId.Equals(e.Item.Id)); if (playEvent != null) _progressEvents.Remove(playEvent); }
void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) { var item = e.MediaInfo; if (item == null) { //_logger.Warn("PlaybackStopped reported with null media info."); return; } var themeMedia = item as IThemeMedia; if (themeMedia != null && themeMedia.IsThemeMedia) { // Don't report theme song or local trailer playback return; } if (e.Users.Count == 0) { return; } var user = e.Users.First(); CreateLogEntry(new ActivityLogEntry { Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, item.Name), Type = "PlaybackStopped", ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), e.ClientName, e.DeviceName), UserId = user.Id.ToString("N") }); }
void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) { var item = e.MediaInfo; if (item == null) { _logger.Warn("PlaybackStopped reported with null media info."); return; } var type = GetPlaybackStoppedNotificationType(item.MediaType); SendPlaybackNotification(type, e); }
/// <summary> /// Media playback has stopped. Depending on playback progress, let Trakt.tv know the user has /// completed watching the item. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void KernelPlaybackStopped(object sender, PlaybackStopEventArgs e) { if (e.Users == null || !e.Users.Any() || e.Item == null) { _logger.Error("Event details incomplete. Cannot process current media"); return; } try { var traktUser = UserHelper.GetTraktUser(e.Users.FirstOrDefault()); if (traktUser == null) { _logger.Error("Could not match trakt user"); return; } // Still need to make sure it's a trakt monitored location before sending notice to trakt.tv if (traktUser.TraktLocations == null) return; foreach ( var location in traktUser.TraktLocations.Where(location => _fileSystem.ContainsSubPath(location, e.Item.Path)) .Where(location => e.Item is Episode || e.Item is Movie)) { var video = e.Item as Video; if (e.PlayedToCompletion) { _logger.Info("Item is played. Scrobble"); try { if (video is Movie) { await _traktApi.SendMovieStatusUpdateAsync(video as Movie, MediaStatus.Scrobble, traktUser). ConfigureAwait(false); } else if (video is Episode) { await _traktApi.SendEpisodeStatusUpdateAsync(video as Episode, MediaStatus.Scrobble, traktUser) .ConfigureAwait(false); } } catch (Exception ex) { _logger.ErrorException("Exception handled sending status update", ex); } } else { _logger.Info("Item Not fully played. Tell trakt.tv we are no longer watching but don't scrobble"); if (video is Movie) { await _traktApi.SendCancelWatchingMovie(traktUser); } else { await _traktApi.SendCancelWatchingShow(traktUser); } } } } catch (Exception ex) { _logger.ErrorException("Error sending scrobble", ex, null); } // No longer need to track the item var playEvent = _progressEvents.FirstOrDefault(ev => ev.UserId.Equals(e.Users.First().Id) && ev.ItemId.Equals(e.Item.Id)); if (playEvent != null) _progressEvents.Remove(playEvent); }
/// <summary> /// Let last.fm know when a track has finished. /// Playback stopped is run when a track is finished. /// </summary> private void PlaybackStopped(object sender, PlaybackStopEventArgs e) { //We only care about audio if (!(e.Item is Audio)) return; var item = e.Item as Audio; //Make sure the track has been fully played if (!e.PlayedToCompletion) { Plugin.Logger.Debug("'{0}' not played to completion, not scrobbling", item.Name); return; } //Played to completion will sometimes be true even if the track has only played 10% so check the playback ourselfs (it must use the app settings or something) //Make sure 80% of the track has been played back if (e.PlaybackPositionTicks == null) { Plugin.Logger.Debug("Playback ticks for {0} is null", item.Name); return; } var playPercent = ((double)e.PlaybackPositionTicks / item.RunTimeTicks) * 100; if (playPercent < 80) { Plugin.Logger.Debug("'{0}' only played {1}%, not scrobbling", item.Name, playPercent); return; } var user = e.Users.FirstOrDefault(); if (user == null) { Plugin.Logger.Debug("No user"); return; } var lastfmUser = Utils.UserHelpers.GetUser(user); if (lastfmUser == null) { Plugin.Logger.Debug("Could not find last.fm user"); return; } //User doesn't want to scrobble if (!lastfmUser.Options.Scrobble) { Plugin.Logger.Debug("{0} ({1}) does not want to scrobble", user.Name, lastfmUser.Username); return; } if (string.IsNullOrWhiteSpace(lastfmUser.SessionKey)) { Plugin.Logger.Info("No session key present, aborting"); return; } _apiClient.Scrobble(item, lastfmUser); }