Esempio n. 1
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 video = e.Item as Video;

            if (video != null && video.IsThemeMedia)
            {
                return;
            }

            var type = GetPlaybackStoppedNotificationType(item.MediaType);

            SendPlaybackNotification(type, e);
        }
Esempio n. 2
0
        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!");
                }
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        /// <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);
                }
            }
        }
Esempio n. 5
0
        /// <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();
        }
Esempio n. 6
0
        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);
        }
Esempio n. 8
0
        private async void OnPlaybackStopped(object sender, PlaybackStopEventArgs e)
        {
            await PlaybackEvent(HookEvent.Stop, e.Item, e.Session, e.Users);

            SetDeviceState(e.DeviceId, DeviceState.Stopped);
        }
Esempio n. 9
0
 private void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e)
 {
     SendData(true);
 }
Esempio n. 10
0
 void _playbackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e)
 {
     Dispatcher.InvokeAsync(() => BackdropContainer.Visibility = Visibility.Visible);
 }
Esempio n. 11
0
        void _playback_PlaybackCompleted(object sender, PlaybackStopEventArgs e)
        {
            _lastInputTime = DateTime.Now;

            AllowSystemIdle();
        }
Esempio n. 12
0
        /// <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);
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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 { }
        }
Esempio n. 15
0
 private async void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e)
 {
     await SendData(true).ConfigureAwait(false);
 }
Esempio n. 16
0
 private void PlaybackManagerPlaybackManagerCompleted(object sender, PlaybackStopEventArgs e)
 {
     _currentPlaybackRate = 1.0;
 }
Esempio n. 17
0
 void PlaybackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e)
 {
     IsPlayingInternalVideo = false;
 }
Esempio n. 18
0
 void _playback_PlaybackCompleted(object sender, PlaybackStopEventArgs e)
 {
     _currentPlayingOwnerId = null;
 }
Esempio n. 19
0
        /// <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);
            }
        }
Esempio n. 20
0
        /// <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);
        }
Esempio n. 21
0
 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);
        }
Esempio n. 24
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.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");
            }
        }
Esempio n. 25
0
 void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e)
 {
     SendData(true);
 }