librespot-org / librespot

Open Source Spotify client library
MIT License
4.84k stars 610 forks source link

Fix bug where playlists containing a local track would fail to load #1079

Closed ealasu closed 1 year ago

roderickvd commented 1 year ago

Hey, thanks for this. Can you provide some context how this would happen?

I’m not very experienced with local files, but if it would make a valid Spotify ID, just not one that librespot can handle for playback, maybe it would be better to move this logic to that context.

Also something like pub fn is_local(&self) would then be pretty!

ealasu commented 1 year ago

It seems that local tracks are identified by a 3-digit number instead of a base62 string, so SpotifyId was failing to parse because it checks the length:

if id.len() != Self::SIZE_BASE62 {

That was causing the whole playlist to fail to load, even though most of the tracks were regular ones. Do you think we should add “Local” to the SpotifyItemType enum? Then we could parse the id as a number if it’s a local track, and format the id as a number when converting SpotifyId back to a string, if the item_type is “Local”.

roderickvd commented 1 year ago

That seems like the right thing to do. Who knows, in the future we may be able to play local files too?

ealasu commented 1 year ago

Looks like the last number in a local URI is actually the track duration, not its ID: https://developer.spotify.com/documentation/general/guides/local-files-spotify-playlists/

The ID would be a longer string composed of {artist}:{album_title}:{track_title}:{duration_in_seconds}, which we can’t convert into a u128. If we want to preserve that info, we’d need to add a String field to SpotifyId. But strings don’t implement Copy, so we’d need to remove the derived Copy trait, which would likely be a breaking change. For now it’s probably safer to just discard that info.

roderickvd commented 1 year ago

Thanks, LGTM! Would you also update the changelog?

ealasu commented 1 year ago

I guess this counts as a new feature, so I put it under the “Added” section.