public BackgroundAudioRun(Guid id)
        {
            _id = id;
            _foregroundNotifier = new ForegroundNotifier(id);
            _timer = new Timer(_ =>
            {
                var metadataHandler = _metadataHandler;

                if (null == metadataHandler)
                {
                    return;
                }

                metadataHandler.Refresh();
            }, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);

            _notificationQueue = new ValueSetWorkerQueue(vs =>
            {
                HandleNotification(vs);

                return(TplTaskExtensions.CompletedTask);
            });

            _watchdogTimer = new Timer(
                _ =>
            {
                Debug.WriteLine("BackgroundAudioRun watchdog");

                var barks = 1;

                try
                {
                    var foregroundId = BackgroundSettings.ForegroundId;

                    if (!foregroundId.HasValue || _completionSource.Task.IsCompleted)
                    {
                        Interlocked.Exchange(ref _watchdogBarks, 0);

                        StopWatchdog();

                        return;
                    }

                    barks = Interlocked.Increment(ref _watchdogBarks);

                    if (barks > 3)
                    {
                        Debug.WriteLine("BackgroundAudioRun watchdog exiting");

                        _completionSource.TrySetCanceled();

                        Cancel();

                        return;
                    }

                    _foregroundNotifier.Notify(BackgroundNotificationType.Ping);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("BackgroundAudioRun watchdog failed: " + ex.ExtendedMessage());
                }

                RequestWatchdog(TimeSpan.FromTicks(WatchdogTimeout.Ticks >> barks));
            },
                null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
        }
        Task Update()
        {
            Debug.WriteLine("SmtcMetadataHandler.Update()");

            try
            {
                var smtc = _systemMediaTransportControls;

                var position = _getPosition();

                TimeSpan?nextEvent = null;

                lock (_lock)
                {
                    nextEvent = _metadataSink.Update(_state, position);
                }

                var title  = GetTitle();
                var artist = GetArtist();

                if (title != _title || artist != _artist)
                {
                    Debug.WriteLine("SmtcMetadataHandler.Update() set " + title);

                    _title  = title;
                    _artist = artist;

                    smtc.DisplayUpdater.ClearAll();
                    smtc.DisplayUpdater.Type = MediaPlaybackType.Music;

                    var properties = smtc.DisplayUpdater.MusicProperties;

                    if (null != title)
                    {
                        properties.Title = title;
                    }

                    if (null != artist)
                    {
                        properties.Artist = artist;
                    }

                    smtc.DisplayUpdater.Update();

                    _notifier.Notify(BackgroundNotificationType.Track, title);
                }

                if (nextEvent.HasValue && nextEvent > position)
                {
                    if (nextEvent.Value != _lastReport)
                    {
                        _lastReport = nextEvent.Value;
                        _reportNextEvent(_lastReport);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("SmtcMetadataSink.Update() failed: " + ex.Message);
            }

            return(TplTaskExtensions.CompletedTask);
        }
        public async Task ExecuteAsync()
        {
            Debug.WriteLine("BackgroundAudioRun.ExecuteAsync()");

            try
            {
                _systemMediaTransportControls = SystemMediaTransportControls.GetForCurrentView();

                var smtc = _systemMediaTransportControls;

                var isOk = false;

                BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayerOnMessageReceivedFromForeground;

                var mediaPlayer = BackgroundMediaPlayer.Current;

                _metadataHandler = new MetadataHandler(_systemMediaTransportControls, _foregroundNotifier,
                                                       () => mediaPlayer.Position,
                                                       position => UpdateMediaPlayerEvents(mediaPlayer, position),
                                                       _cancellationTokenSource.Token);

                try
                {
                    mediaPlayer.CurrentStateChanged        += OnCurrentStateChanged;
                    mediaPlayer.PlaybackMediaMarkerReached += OnPlaybackMediaMarkerReached;

                    BackgroundSettings.SetBackgroundId(_id);

                    isOk = true;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("BackgroundAudioRun.ExecuteAsync() initialization failed: " + ex.ExtendedMessage());
                }

                MediaPlayerManager mediaPlayerManager = null;

                if (isOk)
                {
                    try
                    {
                        mediaPlayerManager = new MediaPlayerManager(mediaPlayer, _metadataHandler, _cancellationTokenSource.Token);

                        mediaPlayerManager.TrackChanged += MediaPlayerManagerOnTrackChanged;
                        mediaPlayerManager.Failed       += MediaPlayerManagerOnFailed;
                        mediaPlayerManager.Ended        += MediaPlayerManagerOnEnded;

                        _mediaPlayerManager = mediaPlayerManager;

                        smtc.ButtonPressed   += SystemMediaTransportControlsOnButtonPressed;
                        smtc.PropertyChanged += SystemMediaTransportControlsOnPropertyChanged;

                        smtc.IsEnabled         = true;
                        smtc.IsPauseEnabled    = true;
                        smtc.IsPlayEnabled     = true;
                        smtc.IsNextEnabled     = true;
                        smtc.IsPreviousEnabled = true;

                        SyncNotification();

                        Debug.WriteLine("BackgroundAudioRun.ExecuteAsync() running");

                        await _completionSource.Task.ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("BackgroundAudioRun.ExecuteAsync() playback failed: " + ex.ExtendedMessage());
                    }
                }

                Debug.WriteLine("BackgroundAudioRun.ExecuteAsync() done running");

                BackgroundSettings.RemoveBackgroundId(_id);

                try
                {
                    _timer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
                }
                catch (Exception)
                {
                    // Guard against race with cleanup
                }

                _mediaPlayerManager = null;

                smtc.PropertyChanged -= SystemMediaTransportControlsOnPropertyChanged;
                smtc.ButtonPressed   -= SystemMediaTransportControlsOnButtonPressed;

                if (null != mediaPlayerManager)
                {
                    mediaPlayerManager.TrackChanged -= MediaPlayerManagerOnTrackChanged;
                    mediaPlayerManager.Failed       -= MediaPlayerManagerOnFailed;
                    mediaPlayerManager.Ended        -= MediaPlayerManagerOnEnded;

                    await mediaPlayerManager.CloseAsync().ConfigureAwait(false);

                    mediaPlayerManager.Dispose();
                }

                if (_appId.HasValue)
                {
                    _foregroundNotifier.Notify(BackgroundNotificationType.Stop);
                }

                mediaPlayer.CurrentStateChanged        -= OnCurrentStateChanged;
                mediaPlayer.PlaybackMediaMarkerReached -= OnPlaybackMediaMarkerReached;
                BackgroundMediaPlayer.MessageReceivedFromForeground -= BackgroundMediaPlayerOnMessageReceivedFromForeground;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("BackgroundAudioRun.ExecuteAsync() failed: " + ex.ExtendedMessage());
            }
            finally
            {
                Debug.WriteLine("BackgroundAudioRun.ExecuteAsync() completed");
            }
        }
예제 #4
0
        public BackgroundAudioRun(Guid id)
        {
            _id = id;
            _foregroundNotifier = new ForegroundNotifier(id);
            _timer = new Timer(_ =>
            {
                var metadataHandler = _metadataHandler;

                if (null == metadataHandler)
                    return;

                metadataHandler.Refresh();
            }, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);

            _notificationQueue = new ValueSetWorkerQueue(vs =>
            {
                HandleNotification(vs);

                return TplTaskExtensions.CompletedTask;
            });

            _watchdogTimer = new Timer(
                _ =>
                {
                    Debug.WriteLine("BackgroundAudioRun watchdog");

                    var barks = 1;

                    try
                    {
                        var foregroundId = BackgroundSettings.ForegroundId;

                        if (!foregroundId.HasValue || _completionSource.Task.IsCompleted)
                        {
                            Interlocked.Exchange(ref _watchdogBarks, 0);

                            StopWatchdog();

                            return;
                        }

                        barks = Interlocked.Increment(ref _watchdogBarks);

                        if (barks > 3)
                        {
                            Debug.WriteLine("BackgroundAudioRun watchdog exiting");

                            _completionSource.TrySetCanceled();

                            Cancel();

                            return;
                        }

                        _foregroundNotifier.Notify(BackgroundNotificationType.Ping);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("BackgroundAudioRun watchdog failed: " + ex.ExtendedMessage());
                    }

                    RequestWatchdog(TimeSpan.FromTicks(WatchdogTimeout.Ticks >> barks));
                },
                null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
        }