Approximately 10 secs before the current track finishes, LMS requests the next track from Pyrrha. Once Pyrrha has the next track, the displayed metadata (track title, artist, cover art, etc) changes to that of the next track before the current track has finished.
It appears that we can't rely on $song->pluginData(), but it looks like $song->streamUrl is correct so maybe we can maintain our own metadata cache keyed on the streamUrl.
Approximately 10 secs before the current track finishes, LMS requests the next track from Pyrrha. Once Pyrrha has the next track, the displayed metadata (track title, artist, cover art, etc) changes to that of the next track before the current track has finished.