[GH-ISSUE #215] Improve consistency: artist and duration fields #168

Closed
opened 2026-02-27 22:08:24 +03:00 by kerem · 8 comments
Owner

Originally created by @natumbri on GitHub (Jul 20, 2021).
Original GitHub issue: https://github.com/sigma67/ytmusicapi/issues/215

Hi,

Is there a method in the ytmusicapi equivalent to the Search: list (related videos) in the YouTube Data API (https://developers.google.com/youtube/v3/docs/search/list):

Use case -
list (related videos) This example sets the relatedToVideoId parameter to retrieve a list of videos related to that video. Since the relatedToVideoId parameter is set, the request must also set the type parameter value to video.

I noticed that YTMusic.get_artist returns related artists, which is close but not for tracks. Are YTMusic.get_watch_playlist and YTMusic.get_watch_playlist_shuffle what I'm looking for? I'm going to try it, but the answer wasn't clear for me from the Reference

Cheers,
Nik

Originally created by @natumbri on GitHub (Jul 20, 2021). Original GitHub issue: https://github.com/sigma67/ytmusicapi/issues/215 Hi, Is there a method in the ytmusicapi equivalent to the `Search: list (related videos)` in the YouTube Data API (https://developers.google.com/youtube/v3/docs/search/list): Use case | - -- | -- list (related videos) | This example sets the relatedToVideoId parameter to retrieve a list of videos related to that video. Since the relatedToVideoId parameter is set, the request must also set the type parameter value to video. I noticed that `YTMusic.get_artist` returns related artists, which is close but not for tracks. Are `YTMusic.get_watch_playlist` and `YTMusic.get_watch_playlist_shuffle` what I'm looking for? I'm going to try it, but the answer wasn't clear for me from the [Reference](https://ytmusicapi.readthedocs.io/en/latest/reference.html#watch) Cheers, Nik
kerem 2026-02-27 22:08:24 +03:00
Author
Owner

@sigma67 commented on GitHub (Jul 20, 2021):

Yes I think get_watch_playlist is what you're looking for, although the matching algorithm is probably quite different from the YouTube Data API. It gets a list of personalized songs/music videos similar to the one you input. The YouTube Data API is much more generic and will also work with non-music videos.

<!-- gh-comment-id:883174024 --> @sigma67 commented on GitHub (Jul 20, 2021): Yes I think `get_watch_playlist` is what you're looking for, although the matching algorithm is probably quite different from the YouTube Data API. It gets a list of personalized songs/music videos similar to the one you input. The YouTube Data API is much more generic and will also work with non-music videos.
Author
Owner

@natumbri commented on GitHub (Jul 20, 2021):

Thanks; works perfectly (authenticated and not).

Any particular reason it returns {"tracks: [{..., "length": "4:47",...], ...} when YTMusic.get_playlist returns {..., "tracks: [{..., "duration": "4:47",...], ...} ?

<!-- gh-comment-id:883201579 --> @natumbri commented on GitHub (Jul 20, 2021): Thanks; works perfectly (authenticated and not). Any particular reason it returns `{"tracks: [{..., "length": "4:47",...], ...}` when `YTMusic.get_playlist` returns `{..., "tracks: [{..., "duration": "4:47",...], ...}` ?
Author
Owner

@sigma67 commented on GitHub (Jul 20, 2021):

It's a different parser. Usually the keys are derived from the JSON returned by the YouTube Music API. For the watch endpoint the key is lengthText. For the get_playlist I probably used duration because it's common in places like get_album. Sorry that it's not really consistent, but they're semantically equivalent. Just the result of a growing project combined with inconsistently formatted data returned from the server.

<!-- gh-comment-id:883213468 --> @sigma67 commented on GitHub (Jul 20, 2021): It's a different parser. Usually the keys are derived from the JSON returned by the YouTube Music API. For the watch endpoint the key is `lengthText`. For the get_playlist I probably used duration because it's common in places like `get_album`. Sorry that it's not really consistent, but they're semantically equivalent. Just the result of a growing project combined with inconsistently formatted data returned from the server.
Author
Owner

@natumbri commented on GitHub (Jul 20, 2021):

Yeah, I know how annoying it is to try to consistently decode the stuff from YouTube. Any plans to go back and make your API more consistent?
For example

  • for track length you use 6 different names and 3 different formats: lengthText, duration, length, lengthSeconds, durationSeconds, durationMs
  • 'artist' vs 'artists' vs 'byline' which is sometimes a string and sometimes a list of dicts.

I'm sure there are others.

No biggie, it just seems that greater consistency would make using your API easier.

Anyway, thanks for the package - I'm glad not to be scraping and parsing it myself anymore!

Cheers
Nik

<!-- gh-comment-id:883345293 --> @natumbri commented on GitHub (Jul 20, 2021): Yeah, I know how annoying it is to try to consistently decode the stuff from YouTube. Any plans to go back and make your API more consistent? For example - for track length you use 6 different names and 3 different formats: lengthText, duration, length, lengthSeconds, durationSeconds, durationMs - 'artist' vs 'artists' vs 'byline' which is sometimes a string and sometimes a list of dicts. I'm sure there are others. No biggie, it just seems that greater consistency would make using your API easier. Anyway, thanks for the package - I'm glad not to be scraping and parsing it myself anymore! Cheers Nik
Author
Owner

@sigma67 commented on GitHub (Jul 20, 2021):

Thanks for the feedback, it's probably a good idea to do that. Of course it would be at the expense of backwards compatibility.

Regarding your bullets

  • I believe 3 of those are from get_song, where the reponse is mostly unparsed due to its complexity. The duration could probably be formatted as some kind of time object, but formatted durations (like 3m20s) are localization dependent and add a whole new layer of complexity
  • it should usually be artists, do you recall where you saw artist? I don't think byline is a thing anymore, but maybe I'm missing something
<!-- gh-comment-id:883386377 --> @sigma67 commented on GitHub (Jul 20, 2021): Thanks for the feedback, it's probably a good idea to do that. Of course it would be at the expense of backwards compatibility. Regarding your bullets - I believe 3 of those are from `get_song`, where the reponse is mostly unparsed due to its complexity. The duration could probably be formatted as some kind of [time object](https://docs.python.org/3/library/datetime.html#timedelta-objects), but formatted durations (like 3m20s) are localization dependent and add a whole new layer of complexity - it should usually be `artists`, do you recall where you saw `artist`? I don't think byline is a thing anymore, but maybe I'm missing something
Author
Owner

@natumbri commented on GitHub (Jul 21, 2021):

get_album returns artist as a list of dicts.
get_watch_playlist returns byline.

I don't think I've checked, but the Reference suggests that get_library_albums returns artists but as a dict (not a list of dicts, like elsewhere).

I agree there's quite a bit of complexity around times! Rather than a time object, I'd suggest something like seconds or ms, as an integer - the most basic representation of the information. Let people turn it into whatever sort of object they like once the API has returned the value. But that's just a personal preference.

You could probably avoid breaking backwards compatibility (mostly) by just picking a key that you like (say lengthMs) and adding that to every dict that returns a duration (without removing the raw value currently returned by the parser). But then again, breaking backwards compatibility might not be a bad thing - forces people to update their code.

<!-- gh-comment-id:883788856 --> @natumbri commented on GitHub (Jul 21, 2021): `get_album` returns `artist` as a list of dicts. `get_watch_playlist` returns `byline`. I don't think I've checked, but the Reference suggests that `get_library_albums` returns `artists` but as a dict (not a list of dicts, like elsewhere). I agree there's quite a bit of complexity around times! Rather than a time object, I'd suggest something like seconds or ms, as an integer - the most basic representation of the information. Let people turn it into whatever sort of object they like once the API has returned the value. But that's just a personal preference. You could probably avoid breaking backwards compatibility (mostly) by just picking a key that you like (say `lengthMs`) and adding that to every dict that returns a duration (without removing the raw value currently returned by the parser). But then again, breaking backwards compatibility might not be a bad thing - forces people to update their code.
Author
Owner

@sigma67 commented on GitHub (Aug 3, 2021):

Some progress regarding the artists key in 86790c07e2

<!-- gh-comment-id:892151703 --> @sigma67 commented on GitHub (Aug 3, 2021): Some progress regarding the `artists` key in 86790c07e288641139ee1f72b4d2de4997333d89
Author
Owner

@natumbri commented on GitHub (Aug 3, 2021):

Looking good - it's very fiddly work, and breaks things, but I for one will appreciate the simplification it allows downstream.

Cheers
Nik

<!-- gh-comment-id:892217182 --> @natumbri commented on GitHub (Aug 3, 2021): Looking good - it's very fiddly work, and breaks things, but I for one will appreciate the simplification it allows downstream. Cheers Nik
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ytmusicapi#168
No description provided.