void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) { var item = e.MediaInfo; if (item == null) { _logger.Warn("PlaybackStopped reported with null media info."); return; } var video = e.Item as Video; if (video != null && video.IsThemeMedia) { return; } var type = GetPlaybackStoppedNotificationType(item.MediaType); SendPlaybackNotification(type, e); }
private async void OnPlaybackStopped(object sender, PlaybackStopEventArgs e) { if (!Plugin.Instance.Configuration.UpdateWatchedStatus) { return; } if (e.Item == null) { Logger.LogError("Event details incomplete. Cannot process current media"); return; } if (!e.Item.HasProviderId("Shoko Episode")) { Logger.LogError("Unrecognized file"); return; // Skip if file does exist in Shoko } if (e.Item is Episode episode && e.PlayedToCompletion) { var episodeId = episode.GetProviderId("Shoko Episode"); Logger.LogInformation("Item is played. Marking as watched on Shoko"); Logger.LogInformation($"{episode.SeriesName} S{episode.Season.IndexNumber}E{episode.IndexNumber} - {episode.Name} ({episodeId})"); var result = await ShokoAPI.MarkEpisodeWatched(episodeId); if (result) { Logger.LogInformation("Episode marked as watched!"); } else { Logger.LogError("Error marking episode as watched!"); } } }
void _vlcControl_Stopped(VlcControl sender, VlcEventArgs <EventArgs> e) { var playlist = _playlist.ToList(); var index = CurrentPlaylistIndex; var ticks = CurrentPositionTicks; DisposePlayer(); var media = index != -1 && playlist.Count > 0 ? playlist[index] : null; var args = new PlaybackStopEventArgs { Playlist = playlist, Player = this, EndingPlaylistIndex = index, EndingPositionTicks = ticks, EndingMedia = media }; EventHelper.QueueEventIfNotNull(PlaybackCompleted, this, args, _logger); _playbackManager.ReportPlaybackCompleted(args); }
/// <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) { try { await _apiClient.ReportPlaybackStoppedAsync(e.EndingMedia.Id, _apiClient.CurrentUserId, e.EndingPositionTicks); } catch (Exception ex) { _logger.ErrorException("Error sending playback stopped checking for {0}", ex, e.EndingMedia.Name); } } }
/// <summary> /// Handles the Exited event of the CurrentProcess control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> void CurrentProcess_Exited(object sender, EventArgs e) { _currentProcess = null; _userInput.GlobalKeyDown -= KeyboardListener_KeyDown; var process = (Process)sender; var playlist = _playlist.ToList(); var index = CurrentPlaylistIndex; var ticks = CurrentPositionTicks; process.Dispose(); if (_currentIsoMount != null) { _currentIsoMount.Dispose(); _currentIsoMount = null; } var media = index != -1 && playlist.Count > 0 ? playlist[index] : null; var args = new PlaybackStopEventArgs { Playlist = playlist, Player = this, EndingPlaylistIndex = index, EndingPositionTicks = ticks, EndingMedia = media }; EventHelper.QueueEventIfNotNull(PlaybackCompleted, this, args, Logger); _playbackManager.ReportPlaybackCompleted(args); OnPlayerExited(); }
void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) { var item = e.MediaInfo; if (item == null) { //_logger.Warn("PlaybackStopped reported with null media info."); return; } if (e.Users.Count == 0) { return; } var username = e.Users.First().Name; CreateLogEntry(new ActivityLogEntry { Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), username, item.Name), Type = "PlaybackStopped", ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), e.ClientName, e.DeviceName) }); }
/// <summary> /// Let last.fm know when a track has finished. /// Playback stopped is run when a track is finished. /// </summary> private async 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) { 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) { _logger.LogDebug("Playback ticks for {0} is null", item.Name); return; } var playPercent = ((double)e.PlaybackPositionTicks / item.RunTimeTicks) * 100; if (playPercent < 80) { _logger.LogDebug("'{0}' only played {1}%, not scrobbling", item.Name, playPercent); return; } var user = e.Users.FirstOrDefault(); if (user == null) { return; } var lastfmUser = Utils.UserHelpers.GetUser(user); if (lastfmUser == null) { _logger.LogDebug("Could not find last.fm user"); return; } // User doesn't want to scrobble if (!lastfmUser.Options.Scrobble) { _logger.LogDebug("{0} ({1}) does not want to scrobble", user.Name, lastfmUser.Username); return; } if (string.IsNullOrWhiteSpace(lastfmUser.SessionKey)) { _logger.LogInformation("No session key present, aborting"); return; } if (string.IsNullOrWhiteSpace(item.Artists.First()) || string.IsNullOrWhiteSpace(item.Name)) { _logger.LogInformation("track {0} is missing artist ({1}) or track name ({2}) metadata. Not submitting", item.Path, item.Artists.First(), item.Name); return; } await _apiClient.Scrobble(item, lastfmUser).ConfigureAwait(false); }
private async void OnPlaybackStopped(object sender, PlaybackStopEventArgs e) { await PlaybackEvent(HookEvent.Stop, e.Item, e.Session, e.Users); SetDeviceState(e.DeviceId, DeviceState.Stopped); }
private void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e) { SendData(true); }
void _playbackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e) { Dispatcher.InvokeAsync(() => BackdropContainer.Visibility = Visibility.Visible); }
void _playback_PlaybackCompleted(object sender, PlaybackStopEventArgs e) { _lastInputTime = DateTime.Now; AllowSystemIdle(); }
/// <summary> /// Reports the playback completed. /// </summary> /// <param name="eventArgs">The <see cref="PlaybackStopEventArgs"/> instance containing the event data.</param> public async void ReportPlaybackCompleted(PlaybackStopEventArgs eventArgs) { await _presentationManager.Window.Dispatcher.InvokeAsync(() => _presentationManager.WindowOverlay.SetResourceReference(FrameworkElement.StyleProperty, "WindowBackgroundContent")); EventHelper.QueueEventIfNotNull(PlaybackCompleted, this, eventArgs, _logger); }
private void PlaybackStopped(object sender, PlaybackStopEventArgs e) { logger.Info("Samsung Smart Things Reports Playback Stopped"); var config = Plugin.Instance.Configuration; if (e.IsPaused) { return; } //We check here if a profile exists or return if (!config.SaveSmartThingsProfiles.Exists(p => p.DeviceName.Equals(e.DeviceName) && p.AppName.Equals(e.ClientName))) { return; } //The item was in a paused state when the user stopped it, clean up the paused session list. if (PausedSessionsIds.Exists(s => s.Equals(e.Session.Id))) { PausedSessionsIds.RemoveAll(s => s.Equals(e.Session.Id)); } //We can assume this will not be null, even though he have to assert it is not null below "profile?.{property}" var profile = config.SaveSmartThingsProfiles.FirstOrDefault(p => p.DeviceName.Equals(e.DeviceName) && p.AppName.Equals(e.ClientName)); logger.Info($"Samsung Smart Things Found Profile Device: { e.DeviceName } "); if (!ScheduleAllowScene(profile)) { logger.Info($"Samsung Smart Things profile not allowed to run at this time: { profile?.DeviceName }"); return; } var sceneName = string.Empty; switch (e.MediaInfo.Type) { case "Movie": sceneName = profile?.MoviesPlaybackStopped; break; case "TvChannel": sceneName = profile?.LiveTvPlaybackStopped; break; case "Series": sceneName = profile?.TvPlaybackStopped; break; case "Season": sceneName = profile?.TvPlaybackStopped; break; case "Episode": sceneName = profile?.TvPlaybackStopped; break; } logger.Info("Samsung Smart Things Reports " + e.MediaInfo.Type + " will trigger Playback Stopped Scene on " + e.DeviceName); RunScene(sceneName, config); }
public static void PlaybackStopped(object sender, PlaybackStopEventArgs e) { try { string sceneName = string.Empty; var config = new PluginConfiguration(); var profile = config.SavedDeviceProfiles.Find(p => p.Name.Equals(e.DeviceName) && e.ClientName.Equals(p.AppName)); if (ScheduleAllowScene(profile, config)) { switch (e.MediaInfo.Type) { case "Movie": sceneName = profile.MoviesPlaybackStopped; break; case "TvChannel": sceneName = profile.LiveTvPlaybackStopped; break; case "Series": sceneName = profile.SeriesPlaybackStopped; break; case "Season": sceneName = profile.SeriesPlaybackStopped; break; case "Episode": sceneName = profile.SeriesPlaybackStopped; break; case "Album": sceneName = profile.MusicPlaybackStopped; break; case "Artist": sceneName = profile.MusicPlaybackStopped; break; case "Audio": sceneName = profile.MusicPlaybackStopped; break; default: sceneName = string.Empty; break; } } else { return; } if (sceneName.Equals(string.Empty)) { return; } RunScene(sceneName, config); } catch { } }
private async void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e) { await SendData(true).ConfigureAwait(false); }
private void PlaybackManagerPlaybackManagerCompleted(object sender, PlaybackStopEventArgs e) { _currentPlaybackRate = 1.0; }
void PlaybackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e) { IsPlayingInternalVideo = false; }
void _playback_PlaybackCompleted(object sender, PlaybackStopEventArgs e) { _currentPlayingOwnerId = null; }
/// <summary> /// Let ListenBrainz know when a track has finished. /// Playback stopped is run when a track is finished. /// </summary> private async 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) { 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) { return; } var listenBrainzUser = GetUser(user); if (listenBrainzUser == null) { Plugin.Logger.Debug("Could not find ListenBrainz user"); return; } //User doesn't want to scrobble if (!listenBrainzUser.Options.Scrobble) { Plugin.Logger.Debug("{0} ({1}) does not want to scrobble", user.Name, listenBrainzUser.Username); return; } if (string.IsNullOrWhiteSpace(listenBrainzUser.SessionKey)) { Plugin.Logger.Info("No session key present, aborting"); return; } if (string.IsNullOrWhiteSpace(item.Name)) { Plugin.Logger.Info("No title present, aborting"); return; } if (item.Artists.Length == 0) { Plugin.Logger.Info("No artist present, aborting"); return; } try { await _apiClient.Scrobble(item, listenBrainzUser).ConfigureAwait(false); } catch (Exception ex) { Plugin.Logger.ErrorException("Error scrobbling to ListenBrainz", ex); } }
/// <summary> /// Let last.fm know when a track has finished. /// Playback stopped is run when a track is finished. /// </summary> private async void PlaybackStopped(object sender, PlaybackStopEventArgs e) { //We only care about audio if (!(e.Item is Audio)) { return; } var item = e.Item as Audio; if (e.PlaybackPositionTicks == null) { Plugin.Logger.Debug("Playback ticks for {0} is null", item.Name); return; } // Required checkpoints before scrobbling noted at https://www.last.fm/api/scrobbling#when-is-a-scrobble-a-scrobble . // A track should only be scrobbled when the following conditions have been met: // * The track must be longer than 30 seconds. // * And the track has been played for at least half its duration, or for 4 minutes (whichever occurs earlier.) // is the track length greater than 30 seconds. if (item.RunTimeTicks < minimumSongLengthToScrobbleInTicks) { Plugin.Logger.Debug("{0} - played {1} ticks which is less minimumSongLengthToScrobbleInTicks ({2}), won't scrobble.", item.Name, item.RunTimeTicks, minimumSongLengthToScrobbleInTicks); return; } // the track must have played the minimum percentage (minimumPlayPercentage = 50%) or played for atleast 4 minutes (minimumPlayTimeToScrobbleInTicks). var playPercent = ((double)e.PlaybackPositionTicks / item.RunTimeTicks) * 100; if (playPercent < minimumPlayPercentage & e.PlaybackPositionTicks < minimumPlayTimeToScrobbleInTicks) { Plugin.Logger.Debug("{0} - played {1}%, Last.Fm requires minplayed={2}% . played {3} ticks of minimumPlayTimeToScrobbleInTicks ({4}), won't scrobble", item.Name, playPercent, minimumPlayPercentage, e.PlaybackPositionTicks, minimumPlayTimeToScrobbleInTicks); return; } var user = e.Users.FirstOrDefault(); if (user == null) { 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; } if (string.IsNullOrWhiteSpace(item.Name)) { Plugin.Logger.Info("No title present, aborting"); return; } if (string.IsNullOrWhiteSpace(item.Artists.FirstOrDefault())) { Plugin.Logger.Info("No artist present, aborting"); return; } await _apiClient.Scrobble(item, lastfmUser).ConfigureAwait(false); }
async void _playbackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e) { await _nav.NavigateBack(); }
/// <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; } 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 async void PlaybackStopped(object sender, PlaybackStopEventArgs e) { //We only care about audio if (!(e.Item is Audio)) { return; } var item = (Audio)e.Item; //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 = UserHelpers.GetUser(user); if (lastfmUser == null) { Plugin.Logger.Debug("Could not find last.fm user"); return; } //User doesn't want to scrobble if (!lastfmUser.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; } await _lastfmApi.Scrobble(item, lastfmUser); }
/// <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.LogError("Event details incomplete. Cannot process current media"); return; } try { _logger.LogInformation("Playback Stopped"); foreach (var user in e.Users) { var traktUser = UserHelper.GetTraktUser(user); if (traktUser == null) { _logger.LogError("Could not match trakt user"); continue; } if (!traktUser.Scrobble) { continue; } if (!_traktApi.CanSync(e.Item, traktUser)) { continue; } var video = e.Item as Video; if (e.PlayedToCompletion) { _logger.LogInformation("Item is played. Scrobble"); try { if (video is Movie movie) { await _traktApi.SendMovieStatusUpdateAsync( movie, MediaStatus.Stop, traktUser, 100).ConfigureAwait(false); } else if (video is Episode episode) { await _traktApi.SendEpisodeStatusUpdateAsync( episode, MediaStatus.Stop, traktUser, 100).ConfigureAwait(false); } } catch (Exception ex) { _logger.LogError(ex, "Exception handled sending status update"); } } else { var progressPercent = video.RunTimeTicks.HasValue && video.RunTimeTicks != 0 ? (float)(e.PlaybackPositionTicks ?? 0) / video.RunTimeTicks.Value * 100.0f : 0.0f; _logger.LogInformation("Item Not fully played. Tell trakt.tv we are no longer watching but don't scrobble"); if (video is Movie movie) { await _traktApi.SendMovieStatusUpdateAsync(movie, MediaStatus.Stop, traktUser, progressPercent).ConfigureAwait(false); } else { await _traktApi.SendEpisodeStatusUpdateAsync(video as Episode, MediaStatus.Stop, traktUser, progressPercent).ConfigureAwait(false); } } } } catch (Exception ex) { _logger.LogError(ex, "Error sending scrobble"); } }
void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) { SendData(true); }