/// <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)); }
/// <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; BackgroundMediaPlayer.Shutdown(); // shutdown media pipeline } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } deferral.Complete(); // signals task completion. Debug.WriteLine("MyBackgroundAudioTask Cancel complete..."); }
/// <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); 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; } } }
/// <summary> /// Start playlist and change UVC state /// </summary> private void StartPlayback() { try { //If the task was cancelled we would have saved the current track and its position. We will try playback from there var currenttrackname = ApplicationSettingsHelper.ReadResetSettingsValue(Constants.CurrentTrack); Debug.WriteLine("Start Playback! || TrackName: " + Playlist.CurrentTrackName.ToString()); Playlist.StartSelectedStream((string)currenttrackname); if (Playlist.CurrentTrackName == "128") { currentTitle = "Vocaloid Radio 128 kbps"; } else { currentTitle = "Vocaloid Radio 192 kbps"; } UpdateUVCOnNewTrack(); BackgroundMediaPlayer.Current.Play(); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } }
/// <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> /// Start playlist and change UVC state /// </summary> private void StartPlayback() { try { // If playback was already started once we can just resume playing. if (!playbackStartedPreviously) { playbackStartedPreviously = true; // If the task was cancelled we would have saved the current track and its position. We will try playback from there. var currentTrackId = ApplicationSettingsHelper.ReadResetSettingsValue(ApplicationSettingsConstants.TrackId); var currentTrackPosition = ApplicationSettingsHelper.ReadResetSettingsValue(ApplicationSettingsConstants.Position); if (currentTrackId != null) { // Find the index of the item by name var index = playbackList.Items.ToList().FindIndex(item => GetTrackId(item).ToString() == (string)currentTrackId); if (currentTrackPosition == null) { // Play from start if we dont have position Debug.WriteLine("StartPlayback: Switching to track " + index); playbackList.MoveTo((uint)index); // Begin playing BackgroundMediaPlayer.Current.Play(); } else { // Play from exact position otherwise TypedEventHandler <MediaPlaybackList, CurrentMediaPlaybackItemChangedEventArgs> handler = null; handler = (MediaPlaybackList list, CurrentMediaPlaybackItemChangedEventArgs args) => { if (args.NewItem == playbackList.Items[index]) { // Unsubscribe because this only had to run once for this item playbackList.CurrentItemChanged -= handler; // Set position var position = TimeSpan.Parse((string)currentTrackPosition); Debug.WriteLine("StartPlayback: Setting Position " + position); BackgroundMediaPlayer.Current.Position = position; // Begin playing BackgroundMediaPlayer.Current.Play(); } }; playbackList.CurrentItemChanged += handler; // Switch to the track which will trigger an item changed event Debug.WriteLine("StartPlayback: Switching to track " + index); playbackList.MoveTo((uint)index); } } else { // Begin playing BackgroundMediaPlayer.Current.Play(); } } else { // Begin playing BackgroundMediaPlayer.Current.Play(); } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); } }
/// <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); }