title: BackgroundAudio not work in windows 10 mobile
body: <p>I have a list with words(about 200), which I want to play in player. This words reproduce from SpeechSynthesisStream. When I run it's in my PC, all words play perfect, but in my phone play just one word and don't move to next.</p>
  
  <pre><code> #region Helper methods
  
      string GetCurrentTrackId()
      {
          if (playbackList == null)
              return null;
  
          return GetTrackId(playbackList.CurrentItem);
      }
  
      string GetTrackId(MediaPlaybackItem item)
      {
          if (item == null)
              return null; // no track playing
  
          return item.Source.CustomProperties[TitleKey] as string;
      }
      #endregion
  
      #region IBackgroundTask and IBackgroundTaskInstance Interface Members and handlers
      /// &lt;summary&gt;
      /// The Run method is the entry point of a background task. 
      /// &lt;/summary&gt;
      /// &lt;param name="taskInstance"&gt;&lt;/param&gt;
      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;
  
          // Read persisted state of foreground app
          var value = ApplicationSettingsHelper.ReadResetSettingsValue(ApplicationSettingsConstants.AppState);
          if (value == null)
              foregroundAppState = AppState.Unknown;
          else
              foregroundAppState = EnumHelper.Parse&lt;AppState&gt;(value.ToString());
  
          // Add handlers for MediaPlayer
          BackgroundMediaPlayer.Current.CurrentStateChanged += Current_CurrentStateChanged;
  
          // 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
      }
  
      /// &lt;summary&gt;
      /// Indicate that the background task is completed.
      /// &lt;/summary&gt;       
      void TaskCompleted(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
      {
          Debug.WriteLine("MyBackgroundAudioTask " + sender.TaskId + " Completed...");
          deferral.Complete();
      }
  
      /// &lt;summary&gt;
      /// 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.
      /// &lt;/summary&gt;
      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...");
      }
      #endregion
  
      #region SysteMediaTransportControls related functions and handlers
      /// &lt;summary&gt;
      /// Update Universal Volume Control (UVC) using SystemMediaTransPortControl APIs
      /// &lt;/summary&gt;
      private void UpdateUVCOnNewTrack(MediaPlaybackItem item)
      {
          if (item == null)
          {
              smtc.PlaybackStatus = MediaPlaybackStatus.Stopped;
              smtc.DisplayUpdater.MusicProperties.Title = string.Empty;
              smtc.DisplayUpdater.Update();
              return;
          }
  
          smtc.PlaybackStatus = MediaPlaybackStatus.Playing;
          smtc.DisplayUpdater.Type = MediaPlaybackType.Music;
          smtc.DisplayUpdater.MusicProperties.Title = item.Source.CustomProperties[TitleKey] as string;
  
          var albumArtUri = item.Source.CustomProperties[AlbumArtKey] as Uri;
          if (albumArtUri != null)
              smtc.DisplayUpdater.Thumbnail = RandomAccessStreamReference.CreateFromUri(albumArtUri);
          else
              smtc.DisplayUpdater.Thumbnail = null;
  
          smtc.DisplayUpdater.Update();
      }
  
      /// &lt;summary&gt;
      /// Fires when any SystemMediaTransportControl property is changed by system or user
      /// &lt;/summary&gt;
      /// &lt;param name="sender"&gt;&lt;/param&gt;
      /// &lt;param name="args"&gt;&lt;/param&gt;
      void smtc_PropertyChanged(SystemMediaTransportControls sender, SystemMediaTransportControlsPropertyChangedEventArgs args)
      {
          // If soundlevel turns to muted, app can choose to pause the music
      }
  
      /// &lt;summary&gt;
      /// This function controls the button events from UVC.
      /// This code if not run in background process, will not be able to handle button pressed events when app is suspended.
      /// &lt;/summary&gt;
      /// &lt;param name="sender"&gt;&lt;/param&gt;
      /// &lt;param name="args"&gt;&lt;/param&gt;
      private void smtc_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
      {
          switch (args.Button)
          {
              case SystemMediaTransportControlsButton.Play:
                  Debug.WriteLine("UVC play button pressed");
  
                  // When the background task has been suspended and the SMTC
                  // starts it again asynchronously, some time is needed to let
                  // the task startup process in Run() complete.
  
                  // Wait for task to start. 
                  // Once started, this stays signaled until shutdown so it won't wait
                  // again unless it needs to.
                  bool result = backgroundTaskStarted.WaitOne(5000);
                  if (!result)
                      throw new Exception("Background Task didnt initialize in time");
  
                  StartPlayback();
                  break;
              case SystemMediaTransportControlsButton.Pause:
                  Debug.WriteLine("UVC pause button pressed");
                  try
                  {
                      BackgroundMediaPlayer.Current.Pause();
                  }
                  catch (Exception ex)
                  {
                      Debug.WriteLine(ex.ToString());
                  }
                  break;
              case SystemMediaTransportControlsButton.Next:
                  Debug.WriteLine("UVC next button pressed");
                  SkipToNext();
                  break;
              case SystemMediaTransportControlsButton.Previous:
                  Debug.WriteLine("UVC previous button pressed");
                  SkipToPrevious();
                  break;
          }
      }
  
  
  
      #endregion
  
      #region Playlist management functions and handlers
      /// &lt;summary&gt;
      /// Start playlist and change UVC state
      /// &lt;/summary&gt;
      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 =&gt;
                          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&lt;MediaPlaybackList, CurrentMediaPlaybackItemChangedEventArgs&gt; handler = null;
                          handler = (MediaPlaybackList list, CurrentMediaPlaybackItemChangedEventArgs args) =&gt;
                          {
                              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());
          }
      }
  
      /// &lt;summary&gt;
      /// Raised when playlist changes to a new track
      /// &lt;/summary&gt;
      /// &lt;param name="sender"&gt;&lt;/param&gt;
      /// &lt;param name="args"&gt;&lt;/param&gt;
      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
          string currentTrackId = null;
          if (item != null)
              currentTrackId = item.Source.CustomProperties[TrackIdKey] as string;
  
          // 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());
      }
  
      /// &lt;summary&gt;
      /// Skip track and update UVC via SMTC
      /// &lt;/summary&gt;
      private void SkipToPrevious()
      {
          smtc.PlaybackStatus = MediaPlaybackStatus.Changing;
          playbackList.MovePrevious();
      }
  
      /// &lt;summary&gt;
      /// Skip track and update UVC via SMTC
      /// &lt;/summary&gt;
      private void SkipToNext()
      {
          smtc.PlaybackStatus = MediaPlaybackStatus.Changing;
          playbackList.MoveNext();
      }
      #endregion
  
      #region Background Media Player Handlers
      void Current_CurrentStateChanged(MediaPlayer sender, object args)
      {
          if (sender.CurrentState == MediaPlayerState.Playing)
          {
              smtc.PlaybackStatus = MediaPlaybackStatus.Playing;
          }
          else if (sender.CurrentState == MediaPlayerState.Paused)
          {
              smtc.PlaybackStatus = MediaPlaybackStatus.Paused;
          }
          else if (sender.CurrentState == MediaPlayerState.Closed)
          {
              smtc.PlaybackStatus = MediaPlaybackStatus.Closed;
          }
      }
  
      /// &lt;summary&gt;
      /// Raised when a message is recieved from the foreground app
      /// &lt;/summary&gt;
      /// &lt;param name="sender"&gt;&lt;/param&gt;
      /// &lt;param name="e"&gt;&lt;/param&gt;
      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 =&gt; (string)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;
          }
      }
      /// &lt;summary&gt;
      /// Create a playback list from the list of songs received from the foreground app.
      /// &lt;/summary&gt;
      /// &lt;param name="songs"&gt;&lt;/param&gt;
      /// 
      void CreatePlaybackList(IEnumerable&lt;SongModel&gt; songs)
      {
          // Make a new list and enable looping
          playbackList = new MediaPlaybackList();
          playbackList.AutoRepeatEnabled = true;
           // Add playback items to the list
              foreach (var song in songs)
              {
                  Task.Run(async () =&gt; {
                  SpeechSynthesisStream synthesisStream = await GetStream(song.Verbs);
                  var source = MediaSource.CreateFromStream(synthesisStream,synthesisStream.GetType().ToString());
                  source.CustomProperties[TrackIdKey] = song.ID;
                  source.CustomProperties[TitleKey] = song.Title;
                  source.CustomProperties[AlbumArtKey] = song.AlbumArtUri;
                  playbackList.Items.Add(new MediaPlaybackItem(source));
                  });
              }
  
          // Don't auto start
          BackgroundMediaPlayer.Current.AutoPlay = false;
  
          // Assign the list to the player
          BackgroundMediaPlayer.Current.Source = playbackList;
  
          // Add handler for future playlist item changes
          playbackList.CurrentItemChanged += PlaybackList_CurrentItemChanged;
      }
  
      #endregion
  
  
      private async Task&lt;SpeechSynthesisStream&gt; GetStream(string verb)
      {
          SpeechSynthesisStream synthesisStream;
          SpeechSynthesizer synthesizer = new SpeechSynthesizer();
          var voices = SpeechSynthesizer.AllVoices;
          bool speechFound = false;
          foreach (VoiceInformation voice in voices.OrderBy(p =&gt; p.Language))
          {
              if (voice.Language == "de-DE")
              {
                  synthesizer.Voice = voice;
                  speechFound = true;
              }
          }
          if (speechFound)
          {
              synthesisStream = await synthesizer.SynthesizeTextToStreamAsync(verb);
              return synthesisStream;
          }
          return null;
      }
  </code></pre>
  
  <p>I changed just this method</p>
  
  <pre><code> void CreatePlaybackList(IEnumerable&lt;SongModel&gt; songs)
      {
          // Make a new list and enable looping
          playbackList = new MediaPlaybackList();
          playbackList.AutoRepeatEnabled = true;
           // Add playback items to the list
              foreach (var song in songs)
              {
                  Task.Run(async () =&gt; {
                  SpeechSynthesisStream synthesisStream = await GetStream(song.Verbs);
                  var source = MediaSource.CreateFromStream(synthesisStream,synthesisStream.GetType().ToString());
                  source.CustomProperties[TrackIdKey] = song.ID;
                  source.CustomProperties[TitleKey] = song.Title;
                  source.CustomProperties[AlbumArtKey] = song.AlbumArtUri;
                  playbackList.Items.Add(new MediaPlaybackItem(source));
                  });
              }
  
          // Don't auto start
          BackgroundMediaPlayer.Current.AutoPlay = false;
  
          // Assign the list to the player
          BackgroundMediaPlayer.Current.Source = playbackList;
  
          // Add handler for future playlist item changes
          playbackList.CurrentItemChanged += PlaybackList_CurrentItemChanged;
      }
  </code></pre>
  
  <p>Maybe problem is in SpeechSynthesisStream? And it's spend a lot of memory, because playlist have more 200 songs?</p>