Search code examples
c#uwpwin-universal-app

UWP MediaPlayer replays music unexpectedly


I am so sorry that I want you guys to debug for me but I really have no idea what's going wrong...

So this is the code that doesn't work as expected:

    public static async Task SetPlaylist(ICollection<Music> playlist, Music music = null)
    {
        int index = 0;
        if (CurrentPlaylist.Count > 0)
        {
            if (music == null)
            {
                CurrentPlaylist.Clear();
                PlayBackList.Items.Clear();
            }
            else
            {
                Debug.WriteLine(music.Name);
                foreach (var item in CurrentPlaylist.ToArray())
                {
                    if (item.Equals(music)) index = 1;
                    else RemoveMusic(item);
                }
                Debug.WriteLine(new string('=', 20));
            }
        }
        foreach (var item in playlist.Skip(index))
            await AddMusic(item);
        if (!CurrentPlaylist.Contains(CurrentMusic))
            CurrentMusic = null;
    }

What this function does is that, it resets the playlist, and if music is specified, do not remove that music from the playlist. This function is helpful when you set your music player to the shuffle mode while you are still playing the music. It will only shuffle the rest of the playlist without interrupting the current.

The problem is that, if I set a breakpoint on the first foreach and run through the foreach step by step, then it runs perfectly without any errors. However, if I press continue when it is still in the first foreach, then the current playing music will stop and restart, meaning that the current playing music might be removed and re-added to the playlist.

I have no idea how to debug it. I can only guess it might have something to do with the async. It is also giving the correct output even it doesn't behave as expected.

My source code is here: https://github.com/SeakyLuo/SMPlayer/blob/master/SMPlayer/Helpers/MediaHelper.cs.


Solution

  • I tested your code, and the problem was found in the SetPlaylist(ICollection<Music> playlist, Music music = null) method, which may be caused by frequent remove and add operations, and a conflict occurred. So I tried to test by updating the elements in the array and found that it worked, so you can try it with the code below.

    public static async Task SetPlaylist(ICollection<Music> playlist, Music music = null)
    {
        int index = 0;
        foreach (var item in playlist.Skip(1))
        {
            index++;
            await FayAddMusic(item, index);
        }
    
        if (!CurrentPlaylist.Contains(CurrentMusic))
            CurrentMusic = null;
    
    }
    
    public static async Task FayAddMusic(Music music, int index)
    {
        try
         {
             var file = await StorageFile.GetFileFromPathAsync(music.Path);
             var source = MediaSource.CreateFromStorageFile(file);
             music.IsPlaying = false;
             source.CustomProperties.Add("Source", music);
             var item = new MediaPlaybackItem(source);
    
             // update element
             PlayBackList.Items[index] = item;
             CurrentPlaylist[index] = music;
          }
          catch (System.IO.FileNotFoundException)
          {
    
    
          }
    }