I had a recent examination where I was asked what music was someone listening to at a point in time on an iOS device. Here’s what I found! (TLDR at the bottom)
I was able to determine that the Spotify app was in use at my time of interest, and dug in to see if there was anything that could help me identify what was playing. For further information about how you can determine what app was controlling to audio output, check out Sarah’s research.
Usually on an iOS device I’d expect a combination of plists and SQLite databases but, because Spotify wants to be different that’s not what I found.
After performing a regular backup on my iPod Touch (old iOS, but still valid) I navigated to the apps directory and found the Spotify directory, AppDomain-com.spotify.client.
Inside the “Library/Application Support/Users” directory you can see my logged in user. I’ve seen it have a number ID, or an actual name. I haven’t really looked into the difference. It could have to do with a user changing a setting, or maybe if they’re a premium subscriber? Not sure.
A lot of these files appear to be encoded in some way, and I was able to view the recently_played.bnk file in UFED Physical Analysers file format viewer with no issues. Unfortunately, I couldn’t report on this data, and I had to convert all the timestamps manually.
I put the call out on Twitter, because I had no idea what file format Spotify was using, and super smart Sarah pointed out that it looked like protobuf … of course it was. I’d briefly looked into protobuf in my Google URL parsing and Google Home research, and I still didn’t quite get it. Sarah, on the other hand, showed that just by throwing your protobuf encoded file at “protoc –decode_raw” you can decode the data
Running some test data over the protoc executable (downloaded from here) gave me track listings and unix timestamps. That’s useful!
Using this, I was able to make some educated guesses about the different fields and created a proto file: recently_played.proto
After the proto file is created you can use protoc to generate the Python code to interpret a protobuf encoded file.
Make sure that you download the right protoc version to the protobuf library that you’ve installed onto your tool of choice (in my case Python). If you download the latest version of protoc (3.6.1 at the time of writing), but you have installed protobuf 3.5 (which I think comes down with pip) then things won’t work. It’s an easy fix though, just rebuild the Python script with “protoc –python_out=. recently_played.proto”
Next was trying to create a script that would pull it all together for me into a timeline. But more test data was required!
I generated some data, and friend-of-the-blog, Alexis Brignoni supplied me with some of his own test data (almost two months ago, I told you I wasn’t going to rush so you didn’t need to!), and took a look.
Looking at the data sets it seemed to show that the recently played file was populated with data from the account, not necessarily from the device. I saw data from sessions prior to listening on the iOS device in both mine and Alexis’ datasets. There may be information about whether the music was listened to on a specific device but I haven’t seen it.
I haven’t done extensive testing on what’s recorded if someone is listening across multiple devices, or what happens when they change songs partway through, but it looks like it would log that as a new track – so you could calculate the expected end time with the song length and if the next song is played before that, that would suggest someone changed the music.
In the test data Alexis provided I could see what songs he listened to, and sometimes the artist or album. I haven’t really looked into what makes the app list an item in the album list or the track list. I also wasn’t able to easily see in here if something was added to a playlist or just searched for without listening. Was outside the scope of my requirements.
- If you do a backup of an iOS device you can get access to the users recently played songs from Spotify.
- The file, recently_played.bnk, is stored in protobuf format
- The timestamps in the file are stored in UTC
- The songs will appear in the album list and the track list. From what I can tell any of the songs listed in either of the lists have been accessed.
- You can either use the embedded player or an API call to get the song names
The script for parsing is here
As a side note, I was able to get a script together to look up the track names based on their URN. The script will require you to do a few things though because I’m not giving out my API key etc.
- Download the Python Spotipy library (pip install spotipy)
- Download my script
- Login to https://developer.spotify.com/
- Create an app (you have to agree that this is for non-commercial purposes, which for me it isn’t)
- On the left hand side you will see a client id and client secret. Copy them into the script.
- Usage is python track.py <trackid>
You get a JSON object back, so you can actually pull out much more information that I’m displaying.
Any questions or comments reach out and let me know!