Shuffle in music players

I always hear how it is hard to implement shuffle algorithms for music players, but never really the explanation for it. What makes it hard?

Take for example how I would implement one:

  1. First the user adds 5 songs to a playlist
    let songs = [0, 1, 2, 3, 4];
  2. Then the user enables shuffle
  3. The program would then copy the songs array into a new array, say shuffle
  4. Then the shuffle array would be randomly sorted with any algorithm
  5. The shuffle array is stored in eg. a text file for persistence, which is loaded at session start
  6. Let’s say, the shuffle array is now [2, 4, 0, 1, 3]
  7. Then the player plays this array in reverse order
  8. When a song is played, it is removed from shuffle array. Eg.

     // shuffle starts as [2, 4, 0, 1, 3] while (shuffle.length > 0) {[shuffle.length - 1]);   shuffle.pop(); }  // First iteration plays song 3, and the array is then: [2, 4, 0, 1] // The second plays song 1, and the array is then: [2, 4, 0] // Third plays song 0, and the array is then: [2, 4] etc. 
  9. Then when all songs have been played, a new array would be again randomly generated from songs, which could have had new songs added to it. Maybe even say a couple of songs before the last one, so that the new array is ready by the time the previous one finishes.

  10. You could even stop play and resume later, and you would still only hear songs that have not yet been played, since they are not yet removed from shuffle

Even if someone has 20000 songs, the array would only be (given it references by integer index) a 125 KB file.