maxcrofts.com

Was 2025 a Good Year for Music?

One man’s extremely subjective analysis.

Last weekend marked a time-honoured tradition where millions of people from all over Australia have their voices heard to decide what matters most. I am of course referring to Triple J’s Hottest 100, an annual poll that attempts to distil the musical zeitgeist of the past year into an easily-digestible list of 100 songs.

I must confess that I have never actually voted in the poll, but I have always religiously observed the results.

Enter: Wrapped

What else is a yearly list of 100 songs? Spotify Wrapped! The thought came to me to analyze what I had listened to over the past few years to see if I had truly lost touch.

Unfortunately I immediately ran into an issue:

spotipy.exceptions.SpotifyException: http status: 404, code: -1 - https://api.spotify.com/v1/playlists/37i9dQZEVXcXHWVVT0lfDq/tracks?limit=100&offset=0&additional_types=track:
 Resource not found, reason: None

You see, Spotify Wrapped is deemed an “algorithmic playlist” and as such is not made available to apps registered after November 2024. Presumably this change was made to prevent analysis of Spotify’s recommendations, especially in the age of AI. I feel in the case of Wrapped however that the restriction is a bit egregious given that the playlist is generated based on a concrete, user-driven metric. But I digress.

I needed to find another way to extract the playlist data. Clearly the tracks are displayed on the webpage, so what if we just looked at the DOM? This does require removing the context event listener from the document so we can inspect the link elements directly. Unless, of course, you’re a fan of weeding through your favourite browser’s dev tools.

<a draggable="false" class="eYJgrgW01l7dHKuMJidG" data-testid="internal-track-link" href="/track/1nV6VafLPuRSsXgbDY3i6L" tabindex="-1">
	<div class="e-91000-text encore-text-body-medium encore-internal-color-text-base eYJgrgW01l7dHKuMJidG standalone-ellipsis-one-line" data-encore-id="text" dir="auto">One Last Dance</div>
</a>

Thankfully the developers at Spotify have included a data-testid property we can leverage. All track links have been helpfully annotated with internal-track-link. From there we can extract the track ID from the URL:

Array.from(
	document.querySelectorAll('a[data-testid="internal-track-link"]')
).map((element) => element.href.split("/").at(-1));

It is worth noting that, because Spotify’s playlist view uses list virtualization, the above snippet will only give you the tracks that you can see; if you want them to return all at once you’ll need a pretty tall viewport. Armed with this array of track IDs we can now query Spotify’s API to retrieve each track’s metadata:

┌────────────────────────┬──────────────┬───────────────────────────────────────────┬──────────────────────────────────┬──────┐
│ id                     │ isrc         │ artist                                    │ name                             │ year │
├────────────────────────┼──────────────┼───────────────────────────────────────────┼──────────────────────────────────┼──────┤
│ 1nV6VafLPuRSsXgbDY3i6L │ NLF712200574 │ Audien, XIRA                              │ One Last Dance                   │ 2022 │
│ 0lCAveJllBTyMexVfWOLH6 │ USSR20600480 │ Halo, Martin O'Donnell, Michael Salvatori │ Unforgotten                      │ 2006 │
│ 3Dr0xDJwXy6JkiHNJfv5zd │ NLF712107041 │ Audien, Cate Downey                       │ Wish It Was You                  │ 2021 │
│ 2H2ytI7ompfNmRkI2sq8Uk │ USUG12401760 │ Camila Cabello, Playboi Carti             │ I LUV IT (feat. Playboi Carti)   │ 2024 │
│ 3yDhZq8f17SmumVmEyCaRN │ USSM19801505 │ KC & The Sunshine Band                    │ Give It Up                       │ 2016 │
│ 5SBsYJjr5Dg09XNV6RZpUy │ USUG12208049 │ DallasK, GALE                             │ Exceso (feat. GALE)              │ 2022 │
│ 6Wobsw9uZ0D0xkfOjxXSq9 │ USAT22503389 │ ROSÉ, F1 The Album                        │ Messy (From F1® The Movie)       │ 2025 │
│ 5S8VwnB4sLi6W0lYTWYylu │ USUG12408497 │ Kendrick Lamar, Dody6                     │ hey now (feat. dody6)            │ 2024 │
│ 3OfqwyE7RrZrtuxCRixfII │ USRC12402692 │ Tate McRae                                │ It's ok I'm ok                   │ 2025 │
│ 46z0f8JOwgIDBuW3Z9zdlY │ GBUM71500399 │ Eric Prydz, CHVRCHES                      │ Tether (Eric Prydz Vs. CHVRCHES) │ 2014 │
└────────────────────────┴──────────────┴───────────────────────────────────────────┴──────────────────────────────────┴──────┘

It is evident there are a few issues here, beyond my questionable taste of course. The song Give It Up is certainly not from 2016 even if it may have been re-released then. Both Halo and F1 The Album definitely aren’t artists. So it looks like we will need to do some data cleaning. This is where the isrc field (containing the track’s International Standard Recording Code) comes into play. We can use this code to query other sources such as MusicBrainz to try and canonicalize these release dates.

Hot or Not?

The logical place to start seemed to be to directly compare my most recent Wrapped playlist against the Hottest 100.

1510152025303540455055606570758085909510015101520253035404550556065707580859095100Tame Impala - LoserTame Impala - End Of SummerTate McRae - TIT FOR TATTate McRae - Sports carWrapped v. Hottest 100Wrapped PositionHottest 100 Position

A whopping intersection of just four songs! At least two of them ranked almost the same, so I am not completely out of touch. Of course the Hottest 100 is solely comprised of tracks released from December 2024 onwards, whereas Spotify is free to populate my playlist with tracks from any year. So what have I actually been listening to?

2019202020212022202320242025197019751980198519901995200020052010201520202025Release Year SpreadReleasedWrapped

For 2020 through 2022 the median follows the trend of being the previous year. Year-on-year there is a general trend of my listening extending further and further into the past.

20192020202120222023202420250510152025303540455055New ReleasesWrappedTracks

A grand total of just 15 new releases made the cut for 2025—no wonder the intersection was so small. Had I just been listening to the same stuff over and over, now with a few oldies thrown in for good measure?

20202021202220232024202505101520253035404550556065707580859095100Playlist TurnoverWrappedTracksFreshStale

It should have been obvious by inspection but it came as a surprise to me that the churn was so high. No more than 18 songs made it from one year to the next. I wasn’t listening to the same songs all the time, I just wasn’t necessarily listening to new releases.

202020212022202320242025010203040506070809010011012013014015016060%40%66%34%43%57%46%54%50%50%45%55%Artist DiscoveryWrappedArtistsNewKnown

With that said, some consistency could be found in the artists I was listening to. Usually around half of any year’s playlist was comprised of tracks credited to artists I had listened to in the past. Note that this is a slightly different metric to how I was counting stale tracks; if an artist had appeared on any past Wrapped they were counted as known, where a track had to be on the immediately preceding playlist to be considered stale.

3LAUAva MaxBTCharli xcxNWYRKSHMRAshley WallbridgeDillon FrancisW&WTame Impala0246810121416182022242628Top 10 ArtistsArtistsTracks2019202020212022202320242025