Spotifyd Bug: Playerctl Plays Wrong Song
Hey guys! So, we've got a bit of a head-scratcher on our hands with Spotifyd, and it's all about using playerctl to get your tunes playing exactly how you want them. You'd think that when you tell Spotifyd to play a specific song using playerctl, it would, you know, play that song, right? Well, sometimes it doesn't work out that way. Instead of the banger you requested, you end up with the next track in the album starting up. Super annoying when you're trying to hit replay on that one perfect track, or just want to jump right into a specific jam. We're going to dive deep into this bug, figure out what's going wrong, and hopefully get you jamming to the right song, every single time.
This issue pops up when you try to initiate playback of a specific track using the playerctl open command, often interacting with Spotifyd via DBus. The expectation is straightforward: you provide the URI of a song, and Spotifyd should start playing it. But what's happening in reality is that Spotifyd seems to be misinterpreting the request or getting confused in the playback queue, leading it to launch the subsequent track on the album instead of the one you explicitly chose. This isn't just a minor glitch; it disrupts the listening experience, especially for users who rely on programmatic control of their music playback. Imagine trying to set up a specific song for a notification sound or a particular moment in a script, only for the wrong track to blast out. It's not ideal, to say the least. We've seen this behavior reported with specific albums, like Michael Jackson's Thriller, and when trying to play a track like "Wanna Be Startin' Somethin'". The logs show that instead of initiating playback for the selected track, Spotifyd seems to load and play "Baby Be Mine," which is the track immediately following.
Understanding the Core Problem: Request vs. Execution
So, what's really going on under the hood when this bug hits? The core of the issue seems to lie in how Spotifyd, in conjunction with playerctl and the underlying DBus interface, is handling the playback request. When you use playerctl open spotify:track:YOUR_TRACK_ID, you're essentially sending a command through DBus that tells Spotifyd to load and play that specific track. Normally, Spotifyd should parse this URI, find the track in its catalog, and initiate playback from the beginning of that track. However, in cases where this bug manifests, it appears that Spotifyd might be registering the request for a track but then, for some reason, defaults to playing the track at the next index within the album or playlist context it's currently aware of. This could be due to a few things: perhaps the index handling within the DBus interface is off by one, or maybe the internal state management of the playback queue gets a little jumbled when a specific track is requested rather than just starting playback of the current context.
Looking at the provided logs, we can see some interesting clues. We see lines like [WARN spotifyd::dbus_mpris] loading context_uri spotify:album:2ANVost0y2y52ema1E9xAZ with playing_track_index 1 and later [DEBUG librespot_connect::spirc] play track <Some(Index(1))>. This suggests that when the request comes in, Spotifyd might be identifying the album context and then trying to play track at index 1. If the track you requested was supposed to be at index 0 (or a different index), but Spotifyd defaults to index 1 for playback, that explains why you're hearing the next song. It's like ordering a specific pizza topping but getting the next one on the menu instead. The logs also show [DEBUG librespot_connect::state::tracks] set track to: spotify:track:6XYbMGvtl6tlPoGWaiH7EY at 1 of 9 tracks, which, when compared to the expected track "Wanna be startin' somethin'" (which is track 1 on Thriller), reveals that the URI might be correctly parsed, but the internal representation or playback initiation is pointing to the wrong index, leading to the subsequent track being played. The detailed seeking logs also show the process of the player preparing to play a track, but the ultimate outcome is playing the incorrect one, reinforcing the idea that the issue is likely in the selection or initiation phase rather than a complete failure to load a track.
Steps to Reproduce the Bug: A Clear Path
For anyone wanting to check this out or help us squash this bug, here's exactly how we're seeing it happen. It’s pretty straightforward, and you can replicate it yourself if you have Spotifyd set up with playerctl integration. This is crucial for debugging and ensuring we're all looking at the same problem. A consistent reproduction path helps developers pinpoint the exact lines of code or logic that might be causing the issue. Without this, it's like trying to find a needle in a haystack; with it, we can at least narrow down where to start looking.
Here are the steps:
-
Find a Spotify Album: The first step is to pick an album from Spotify. For the sake of consistency and because it's been used in reports, Michael Jackson's Thriller is a great example. You can find it here: https://open.spotify.com/album/2ANVost0y2y52ema1E9xAZ. Having a fixed reference point makes it easier to compare results.
-
Get a Specific Song URL: Next, you need the unique Spotify URI for a particular song within that album. Let's use "Wanna Be Startin' Somethin'" as our target. Its URI is
spotify:track:1hu2s7qkm5bo03eODpRQO3. Make sure you copy this precisely. -
*Initiate Playback via
playerctl: This is where the magic (or in this case, the bug) happens. Open your terminal and run the following command:playerctl open spotify:track:1hu2s7qkm5bo03eODpRQO3. This command usesplayerctlto send a DBus message to Spotifyd, instructing it to open and play the specified track. It's this command that seems to trigger the unexpected behavior. -
Observe the Outcome: After running the command, pay close attention to what song starts playing. Instead of "Wanna Be Startin' Somethin'" kicking off, you should observe that the next song on the Thriller album, which is "Baby Be Mine," begins to play. This is the definitive sign that the bug has occurred.
This sequence is critical because it isolates the problem to the interaction between playerctl sending the specific track URI and Spotifyd's interpretation and execution of that command. If you follow these steps and experience the same result, it confirms the bug is present in your setup. This is super helpful for anyone trying to debug, as it provides a concrete, repeatable scenario. We need this kind of clarity to nail down exactly why Spotifyd is skipping the requested track and jumping to the next one. It’s like having a diagnostic tool that points directly to the faulty component.
Expected Behavior: The Right Track, Every Time
When you're trying to get your music sorted, the absolute least you expect is for the song you explicitly ask for to play. It sounds simple, right? But when you're deep in the world of command-line control and custom setups, these seemingly small details become super important. With Spotifyd and playerctl, the expectation is crystal clear: if you point it to a specific track, that's the track that should start playing. No skipping, no jumping ahead, just the song you selected, from the very beginning.
Let's break down what this ideal scenario looks like, using our previous example. When you follow the steps and execute playerctl open spotify:track:1hu2s7qkm5bo03eODpRQO3, you're telling Spotifyd, "Hey, I want to hear 'Wanna Be Startin' Somethin'' right now." The expected behavior is that Spotifyd processes this command, locates that specific track URI, and immediately begins playback of "Wanna Be Startin' Somethin'". This means the audio should start from the first note, exactly as the artist intended. It should be a seamless transition from whatever was playing before (or silence) directly into your chosen song.
This also implies that Spotifyd should correctly handle the track's position. If you're requesting a specific track, it's usually implied that you want to hear it from the start (position 0ms). While playerctl can sometimes be used to specify a starting position, the default action when opening a track URI should be to play it from the beginning. So, the expected outcome is not just playing the correct song, but playing it from its intended starting point.
Furthermore, this expected behavior extends to how Spotifyd updates its status. Once playback begins, the DBus interface, which playerctl interacts with, should accurately reflect that "Wanna Be Startin' Somethin'" is now the active track. Any subsequent commands, like 'next' or 'previous', should then operate relative to this correctly identified track. If Spotifyd incorrectly identifies "Baby Be Mine" as the active track after the playerctl open command, then subsequent 'next' commands would skip to the third track on the album, which is definitely not what anyone wants. The whole chain of playback control breaks down if the initial track selection is wrong.
Essentially, the expected behavior is that Spotifyd acts as a reliable music player, responding precisely to the commands it receives. When a specific track is requested, it should be honored. This ensures that users have full and accurate control over their listening experience, allowing them to curate playlists, trigger specific songs programmatically, or simply enjoy their music library without unexpected interruptions or detours. It’s about fulfilling the command as given, providing a predictable and satisfying user experience. We want Spotifyd to be smart enough to know exactly which song you asked for and play that song. Simple, but essential!
Diving into the Logs: What the Data Tells Us
Alright, let's get our hands dirty and dissect those logs you guys provided. Logs are like the secret diary of your software, telling us exactly what was happening at the moment the bug occurred. When we look at the provided snippet, we can piece together a narrative of what Spotifyd was doing, and where things might have gone awry. It's super helpful for narrowing down the source of the problem, kind of like a detective following clues at a crime scene.
One of the most telling lines is: [WARN spotifyd::dbus_mpris] loading context_uri spotify:album:2ANVost0y2y52ema1E9xAZ with playing_track_index 1. This warning immediately tells us that Spotifyd is aware of the album context (spotify:album:2ANVost0y2y52ema1E9xAZ) and it's associating the playback request with playing_track_index 1. Now, if you recall, when we tried to play "Wanna Be Startin' Somethin'" (spotify:track:1hu2s7qkm5bo03eODpRQO3), that song is actually the first track on the Thriller album, which should correspond to index 0. However, Spotifyd seems to be internally setting the index to 1. This is a huge clue, guys!
Following this, we see [DEBUG librespot_connect::spirc] play track <Some(Index(1))>. This debug message confirms that the playback command being executed internally is targeting index 1. This is where the disconnect happens. The playerctl open command might have provided a specific track URI, but internally, Spotifyd is resolving it or prioritizing an index within the album context it has loaded, and it's defaulting to index 1.
Then, the logs show [DEBUG librespot_connect::state::tracks] set track to: spotify:track:6XYbMGvtl6tlPoGWaiH7EY at 1 of 9 tracks. This line explicitly states that the track being set is identified by the URI spotify:track:6XYbMGvtl6tlPoGWaiH7EY. A quick check reveals that this URI corresponds to "Baby Be Mine," which is indeed the second track (index 1) on the Thriller album. So, the log confirms that the incorrect track is being loaded and prepared for playback.
Further down, we have [DEBUG librespot_playback::player] command=Load(SpotifyUri("spotify:track:6XYbMGvtl6tlPoGWaiH7EY"), true, 0). This shows the Load command being issued to the playback engine for the wrong track, even though the true, 0 might suggest it's attempting to load and play it from the beginning. The issue isn't that the track can't be loaded or played, but rather which track is being loaded.
Interestingly, the logs also show [DEBUG spotifyd::dbus_mpris] handling event TrackChanged { audio_item: AudioItem { track_id: SpotifyUri("spotify:track:6XYbMGvtl6tlPoGWaiH7EY"), ... name: "Baby Be Mine", ... number: 2, ... } }. This event is fired after the track has started playing, confirming that the TrackChanged event is reporting "Baby Be Mine" (track number 2) as the currently playing item. This is the final confirmation that the bug has indeed occurred.
What's not clearly visible in this snippet is why the index got set to 1 instead of correctly resolving the specific track URI provided. It could be a race condition, a faulty mapping between the provided URI and the internal index, or an issue with how Spotifyd manages contexts when receiving external commands. But the logs give us a very strong indication that the problem is centered around the track indexing and selection process when using playerctl open.
Compilation Flags and Environment Details
Knowing how Spotifyd was compiled and the environment it's running in is super important for debugging, guys. Different compilation flags can enable or disable certain features, and the operating system and versions can introduce their own quirks. It’s like knowing if your car has ABS before you try to figure out why it’s skidding. For this specific issue, the provided details are quite informative.
Here's a breakdown:
-
Compilation Flags:
[x] dbus_mpris: This is a big one! It means the DBus MPRIS (Media Player Remote Interfacing Specification) interface is enabled. This is precisely howplayerctlcommunicates with Spotifyd. If there were an issue with thedbus_mprisimplementation, it could absolutely lead to commands being misinterpreted, like playing the wrong track. The fact that it's checked ([x]) confirms this integration is active and a potential area for the bug.[x] alsa_backend: This indicates that ALSA (Advanced Linux Sound Architecture) is being used for audio output. While less likely to be the direct cause of selecting the wrong track, audio backend issues can sometimes manifest in strange ways, though typically related to sound quality or playback stopping.[ ] portaudio_backend,[ ] pulseaudio_backend,[ ] rodio_backend: These are unchecked, meaning these alternative audio backends were not used during compilation. This is good for narrowing down possibilities; we don't need to worry about bugs specific to PortAudio, PulseAudio, or Rodio in this context.
-
Versions:
- OS:
Debian Trixie (Raspberry Pi OS): This tells us the underlying operating system. While Debian is generally stable, specific versions or distributions can sometimes have compatibility issues or unique behaviors. Raspberry Pi OS is based on Debian, so it inherits much of that. - Spotifyd:
0.4.1 (self-compiled - With the newest version of librespot to fix the playback issue): This is crucial. The user compiled Spotifyd themselves, which is great for customization but also means they might be running a slightly different build than a standard release. More importantly, they mention compiling with the newest version of librespot.librespotis the core library that handles the Spotify communication and playback logic. If the bug lies withinlibrespot's handling of track requests or indexing, and they've updated it, they might be running a version where the bug is present, or perhaps a fix inlibrespotwasn't fully integrated or effective in this specific scenario. - Cargo:
1.91.0: This is the version of the Rust package manager used for compilation. It's good to know for build reproducibility but unlikely to be the direct cause of the playback bug itself unless there was a very specific Cargo issue during the build process.
- OS:
Given these details, the dbus_mpris flag being enabled and the self-compiled nature of Spotifyd with a recent librespot version are the most relevant factors. It suggests the bug is likely within the interaction logic between playerctl (via DBus) and Spotifyd's core playback handling, possibly stemming from librespot itself or how Spotifyd integrates it. The fact that they updated librespot