/// <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);
        }
Example #2
0
        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")
            });
        }
Example #3
0
        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);
        }
Example #4
0
        /// <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);
        }