Exemple #1
0
        /// <summary>
        /// Raised when playlist changes to a new track
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void PlaybackList_CurrentItemChanged(MediaPlaybackList sender, CurrentMediaPlaybackItemChangedEventArgs args)
        {
            // Get the new item
            var item = args.NewItem;

            Debug.WriteLine("PlaybackList_CurrentItemChanged: " + (item == null ? "null" : GetTrackId(item).ToString()));

            // Update the system view
            UpdateUVCOnNewTrack(item);

            // Get the current track
            Uri currentTrackId = null;

            if (item != null)
            {
                currentTrackId = item.Source.CustomProperties[TrackIdKey] as Uri;
            }

            // Notify foreground of change or persist for later
            if (foregroundAppState == AppState.Active)
            {
                MessageService.SendMessageToForeground(new TrackChangedMessage(currentTrackId));
            }
            else
            {
                ApplicationSettingsHelper.SaveSettingsValue(TrackIdKey, currentTrackId == null ? null : currentTrackId.ToString());
            }
        }
Exemple #2
0
        /// <summary>
        /// Fires when a message is recieved from the foreground app
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e)
        {
            foreach (string key in e.Data.Keys)
            {
                switch (key.ToLower())
                {
                case Constants.AppSuspended:
                    Debug.WriteLine("App suspending");     // App is suspended, you can save your task state at this point
                    foregroundAppState = ForegroundAppStatus.Suspended;
                    ApplicationSettingsHelper.SaveSettingsValue(Constants.CurrentTrack, Playlist.CurrentTrackName);
                    ApplicationSettingsHelper.SaveSettingsValue(Constants.BackgroundTaskState, Constants.BackgroundTaskRunning);
                    break;

                case Constants.AppResumed:
                    Debug.WriteLine("App resuming");     // App is resumed, now subscribe to message channel
                    foregroundAppState = ForegroundAppStatus.Active;
                    break;

                case Constants.StartPlayback:     //Foreground App process has signalled that it is ready for playback
                    Debug.WriteLine("Starting Playback");
                    StartPlayback();
                    break;

                case Constants.SkipNext:     // User has chosen to skip track from app context.
                    Debug.WriteLine("Skipping to next");
                    SkipToNext();
                    break;

                case Constants.SkipPrevious:     // User has chosen to skip track from app context.
                    Debug.WriteLine("Skipping to previous");
                    SkipToPrevious();
                    break;
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Handles background task cancellation. Task cancellation happens due to:
        /// 1. Another Media app comes into foreground and starts playing music
        /// 2. Resource pressure. Your task is consuming more CPU and memory than allowed.
        /// In either case, save state so that if foreground app resumes it can know where to start.
        /// </summary>
        private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            // You get some time here to save your state before process and resources are reclaimed
            Debug.WriteLine("MyBackgroundAudioTask " + sender.Task.TaskId + " Cancel Requested...");
            try
            {
                // immediately set not running
                backgroundTaskStarted.Reset();

                // save state
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.TrackId, GetCurrentTrackId() == null ? null : GetCurrentTrackId().ToString());
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.Position, BackgroundMediaPlayer.Current.Position.ToString());
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.BackgroundTaskState, BackgroundTaskState.Canceled.ToString());
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.AppState, Enum.GetName(typeof(AppState), foregroundAppState));

                // unsubscribe from list changes
                if (playbackList != null)
                {
                    playbackList.CurrentItemChanged -= PlaybackList_CurrentItemChanged;
                    playbackList = null;
                }

                // unsubscribe event handlers
                BackgroundMediaPlayer.MessageReceivedFromForeground -= BackgroundMediaPlayer_MessageReceivedFromForeground;
                smtc.ButtonPressed   -= smtc_ButtonPressed;
                smtc.PropertyChanged -= smtc_PropertyChanged;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
            deferral.Complete(); // signals task completion.
            Debug.WriteLine("MyBackgroundAudioTask Cancel complete...");
        }
Exemple #4
0
        /// <summary>
        /// Handles background task cancellation. Task cancellation happens due to :
        /// 1. Another Media app comes into foreground and starts playing music
        /// 2. Resource pressure. Your task is consuming more CPU and memory than allowed.
        /// In either case, save state so that if foreground app resumes it can know where to start.
        /// </summary>
        private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            // You get some time here to save your state before process and resources are reclaimed
            Debug.WriteLine("MyBackgroundAudioTask " + sender.Task.TaskId + " Cancel Requested...");
            try
            {
                //save state
                ApplicationSettingsHelper.SaveSettingsValue(Constants.CurrentTrack, Playlist.CurrentTrackName);
                ApplicationSettingsHelper.SaveSettingsValue(Constants.Position, BackgroundMediaPlayer.Current.Position.ToString());
                ApplicationSettingsHelper.SaveSettingsValue(Constants.BackgroundTaskState, Constants.BackgroundTaskCancelled);
                ApplicationSettingsHelper.SaveSettingsValue(Constants.AppState, Enum.GetName(typeof(ForegroundAppStatus), foregroundAppState));
                backgroundtaskrunning = false;
                //unsubscribe event handlers
                systemmediatransportcontrol.ButtonPressed   -= systemmediatransportcontrol_ButtonPressed;
                systemmediatransportcontrol.PropertyChanged -= systemmediatransportcontrol_PropertyChanged;
                Playlist.TrackChanged -= playList_TrackChanged;

                //clear objects task cancellation can happen uninterrupted
                playlistManager.ClearPlaylist();
                playlistManager = null;
                BackgroundMediaPlayer.Shutdown(); // shutdown media pipeline
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
            deferral.Complete(); // signals task completion.
            Debug.WriteLine("MyBackgroundAudioTask Cancel complete...");
        }
        /// <summary>
        /// Skip track and update UVC via SMTC
        /// </summary>
        private async Task SkipToNext()
        {
            int CurrentIndex = Playlist.ToList().FindIndex(m => m.InternalID == CurrentMix.InternalID);

            if (CurrentIndex == -1)
            {
                BackgroundMediaPlayer.Current.Pause();
                return;
            }

            if (CurrentIndex == Playlist.Count() - 1)
            {
                CurrentIndex = 0;
            }
            else
            {
                CurrentIndex++;
            }

            ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.TrackId, CurrentMix.InternalID);
            smtc.PlaybackStatus = MediaPlaybackStatus.Changing;
            CurrentMix          = Playlist[CurrentIndex];
            await PlayCurrentMix();

            MessageService.SendMessageToForeground(new TrackChangedMessage(CurrentMix.InternalID));
        }
        /// <summary>
        /// The Run method is the entry point of a background task.
        /// </summary>
        /// <param name="taskInstance"></param>
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            Debug.WriteLine("Background Audio Task " + taskInstance.Task.Name + " starting...");

            // Initialize SystemMediaTransportControls (SMTC) for integration with
            // the Universal Volume Control (UVC).
            //
            // The UI for the UVC must update even when the foreground process has been terminated
            // and therefore the SMTC is configured and updated from the background task.
            smtc = BackgroundMediaPlayer.Current.SystemMediaTransportControls;
            smtc.ButtonPressed          += smtc_ButtonPressed;
            smtc.PropertyChanged        += smtc_PropertyChanged;
            smtc.IsEnabled               = true;
            smtc.IsPauseEnabled          = true;
            smtc.IsPlayEnabled           = true;
            smtc.IsNextEnabled           = true;
            smtc.IsPreviousEnabled       = true;
            DataObject.DisableDispatcher = true;

            // Read persisted state of foreground app
            var value = ApplicationSettingsHelper.ReadResetSettingsValue(ApplicationSettingsConstants.AppState);

            if (value == null)
            {
                foregroundAppState = AppState.Unknown;
            }
            else
            {
                foregroundAppState = EnumHelper.Parse <AppState>(value.ToString());
            }

            // Add handlers for MediaPlayer
            BackgroundMediaPlayer.Current.CurrentStateChanged += Current_CurrentStateChanged;
            BackgroundMediaPlayer.Current.MediaEnded          += Current_MediaEnded;

            // Initialize message channel
            BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayer_MessageReceivedFromForeground;

            // Send information to foreground that background task has been started if app is active
            if (foregroundAppState != AppState.Suspended)
            {
                MessageService.SendMessageToForeground(new BackgroundAudioTaskStartedMessage());
            }

            ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.BackgroundTaskState, BackgroundTaskState.Running.ToString());

            deferral = taskInstance.GetDeferral(); // This must be retrieved prior to subscribing to events below which use it

            // Mark the background task as started to unblock SMTC Play operation (see related WaitOne on this signal)
            backgroundTaskStarted.Set();

            // Associate a cancellation and completed handlers with the background task.
            taskInstance.Task.Completed += TaskCompleted;
            taskInstance.Canceled       += new BackgroundTaskCanceledEventHandler(OnCanceled); // event may raise immediately before continung thread excecution so must be at the end
        }
Exemple #7
0
        /// <summary>
        /// The Run method is the entry point of a background task.
        /// </summary>
        /// <param name="taskInstance"></param>
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            Debug.WriteLine("Background Audio Task " + taskInstance.Task.Name + " starting...");
            // Initialize SMTC object to talk with UVC.
            //Note that, this is intended to run after app is paused and
            //hence all the logic must be written to run in background process
            systemmediatransportcontrol = SystemMediaTransportControls.GetForCurrentView();
            systemmediatransportcontrol.ButtonPressed       += systemmediatransportcontrol_ButtonPressed;
            systemmediatransportcontrol.PropertyChanged     += systemmediatransportcontrol_PropertyChanged;
            systemmediatransportcontrol.IsEnabled            = true;
            systemmediatransportcontrol.IsPauseEnabled       = true;
            systemmediatransportcontrol.IsPlayEnabled        = true;
            systemmediatransportcontrol.IsNextEnabled        = false;
            systemmediatransportcontrol.IsPreviousEnabled    = false;
            systemmediatransportcontrol.IsFastForwardEnabled = false;

            // Associate a cancellation and completed handlers with the background task.
            taskInstance.Canceled       += new BackgroundTaskCanceledEventHandler(OnCanceled);
            taskInstance.Task.Completed += Taskcompleted;

            var value = ApplicationSettingsHelper.ReadResetSettingsValue(Constants.AppState);

            if (value == null)
            {
                foregroundAppState = ForegroundAppStatus.Unknown;
            }
            else
            {
                foregroundAppState = (ForegroundAppStatus)Enum.Parse(typeof(ForegroundAppStatus), value.ToString());
            }

            //Add handlers for MediaPlayer
            BackgroundMediaPlayer.Current.CurrentStateChanged += Current_CurrentStateChanged;

            //Add handlers for playlist trackchanged
            Playlist.TrackChanged += playList_TrackChanged;

            //Initialize message channel
            BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayer_MessageReceivedFromForeground;

            //Send information to foreground that background task has been started if app is active
            if (foregroundAppState != ForegroundAppStatus.Suspended)
            {
                ValueSet message = new ValueSet();
                message.Add(Constants.BackgroundTaskStarted, "BC Started");
                BackgroundMediaPlayer.SendMessageToForeground(message);
            }
            BackgroundTaskStarted.Set();
            backgroundtaskrunning = true;

            ApplicationSettingsHelper.SaveSettingsValue(Constants.BackgroundTaskState, Constants.BackgroundTaskRunning);
            deferral = taskInstance.GetDeferral();
        }
Exemple #8
0
        /// <summary>
        /// Fires when playlist changes to a new track
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void playList_TrackChanged(MyPlaylist sender, object args)
        {
            UpdateUVCOnNewTrack();
            ApplicationSettingsHelper.SaveSettingsValue(Constants.CurrentTrack, sender.CurrentTrackName);

            if (foregroundAppState == ForegroundAppStatus.Active)
            {
                //Message channel that can be used to send messages to foreground
                ValueSet message = new ValueSet();
                message.Add(Constants.Trackchanged, sender.CurrentTrackName);
                BackgroundMediaPlayer.SendMessageToForeground(message);
            }
        }
        /// <summary>
        /// Raised when playlist changes to a new track
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void PlaybackList_CurrentItemChanged(MediaPlaybackList sender, CurrentMediaPlaybackItemChangedEventArgs args)
        {
            //Uri s =    GetCurrentTrackId();

            // Get the new item
            var item = args.NewItem;

            Debug.WriteLine("PlaybackList_CurrentItemChanged: " + (item == null ? "null" : Convert.ToString(GetTrackId(item))));

            // Update the system view
            UpdateUVCOnNewTrack(item);

            // Get the current track
            Uri currentTrackId = null;

            if (item != null)
            {
                string trackIdKey = item.Source.CustomProperties[TrackIdKey].ToString();
                currentTrackId = new Uri(trackIdKey);
            }

            ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.TrackId, currentTrackId == null ? null : currentTrackId.ToString());
            MessageService.SendMessageToForeground(new TrackChangedMessage(currentTrackId));
        }
Exemple #10
0
        /// <summary>
        /// Raised when a message is recieved from the foreground app
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e)
        {
            AppSuspendedMessage appSuspendedMessage;

            if (MessageService.TryParseMessage(e.Data, out appSuspendedMessage))
            {
                Debug.WriteLine("App suspending"); // App is suspended, you can save your task state at this point
                foregroundAppState = AppState.Suspended;
                var currentTrackId = GetCurrentTrackId();
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.TrackId, currentTrackId == null ? null : currentTrackId.ToString());
                return;
            }

            AppResumedMessage appResumedMessage;

            if (MessageService.TryParseMessage(e.Data, out appResumedMessage))
            {
                Debug.WriteLine("App resuming"); // App is resumed, now subscribe to message channel
                foregroundAppState = AppState.Active;
                return;
            }

            StartPlaybackMessage startPlaybackMessage;

            if (MessageService.TryParseMessage(e.Data, out startPlaybackMessage))
            {
                //Foreground App process has signalled that it is ready for playback
                Debug.WriteLine("Starting Playback");
                StartPlayback();
                return;
            }

            SkipNextMessage skipNextMessage;

            if (MessageService.TryParseMessage(e.Data, out skipNextMessage))
            {
                // User has chosen to skip track from app context.
                Debug.WriteLine("Skipping to next");
                SkipToNext();
                return;
            }

            SkipPreviousMessage skipPreviousMessage;

            if (MessageService.TryParseMessage(e.Data, out skipPreviousMessage))
            {
                // User has chosen to skip track from app context.
                Debug.WriteLine("Skipping to previous");
                SkipToPrevious();
                return;
            }

            TrackChangedMessage trackChangedMessage;

            if (MessageService.TryParseMessage(e.Data, out trackChangedMessage))
            {
                var index = playbackList.Items.ToList().FindIndex(i => (Uri)i.Source.CustomProperties[TrackIdKey] == trackChangedMessage.TrackId);
                Debug.WriteLine("Skipping to track " + index);
                smtc.PlaybackStatus = MediaPlaybackStatus.Changing;
                playbackList.MoveTo((uint)index);
                return;
            }

            UpdatePlaylistMessage updatePlaylistMessage;

            if (MessageService.TryParseMessage(e.Data, out updatePlaylistMessage))
            {
                CreatePlaybackList(updatePlaylistMessage.Songs);
                return;
            }
        }
        /// <summary>
        /// Raised when a message is recieved from the foreground app
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e)
        {
            AppSuspendedMessage appSuspendedMessage;

            if (MessageService.TryParseMessage(e.Data, out appSuspendedMessage))
            {
                Debug.WriteLine("App suspending"); // App is suspended, you can save your task state at this point
                foregroundAppState = AppState.Suspended;
                ApplicationSettingsHelper.SaveSettingsValue(ApplicationSettingsConstants.TrackId, CurrentMix == null ? 0 : CurrentMix.InternalID);
                return;
            }

            AppResumedMessage appResumedMessage;

            if (MessageService.TryParseMessage(e.Data, out appResumedMessage))
            {
                Debug.WriteLine("App resuming"); // App is resumed, now subscribe to message channel
                foregroundAppState = AppState.Active;
                return;
            }

            StartPlaybackMessage startPlaybackMessage;

            if (MessageService.TryParseMessage(e.Data, out startPlaybackMessage))
            {
                //Foreground App process has signalled that it is ready for playback
                Debug.WriteLine("Starting Playback");
                await StartPlayback();
            }

            SkipNextMessage skipNextMessage;

            if (MessageService.TryParseMessage(e.Data, out skipNextMessage))
            {
                // User has chosen to skip track from app context.
                Debug.WriteLine("Skipping to next");
                await SkipToNext();
            }

            SkipPreviousMessage skipPreviousMessage;

            if (MessageService.TryParseMessage(e.Data, out skipPreviousMessage))
            {
                // User has chosen to skip track from app context.
                Debug.WriteLine("Skipping to previous");
                await SkipToPrevious();
            }

            TrackChangedMessage trackChangedMessage;

            if (MessageService.TryParseMessage(e.Data, out trackChangedMessage))
            {
                await UpdateOptions();

                CurrentMix = Playlist.Single(m => m.InternalID == trackChangedMessage.InternalMixID);
                Debug.WriteLine("Skipping to track " + trackChangedMessage.InternalMixID);
                smtc.PlaybackStatus = MediaPlaybackStatus.Changing;
                await PlayCurrentMix();
            }

            UpdatePlaylistMessage updatePlaylistMessage;

            if (MessageService.TryParseMessage(e.Data, out updatePlaylistMessage))
            {
                try
                {
                    while (true)
                    {
                        try
                        {
                            await UpdateOptions();

                            break;
                        }
                        catch
                        {
                        }
                    }

                    if (updatePlaylistMessage.SendUpdateMessage)
                    {
                        MessageService.SendMessageToForeground(new UpdateMediaPlayerInfoMessage(CurrentMix == null ? 0 : CurrentMix.InternalID));
                    }
                }
                catch
                {
                }
            }

            UpdateUVCOnNewTrack(CurrentMix);
        }