spotify-player
spotify-player copied to clipboard
Fake track repeat
Is your feature request related to a problem? Please describe. I want to play a song on loop.
Describe the solution you'd like (when using the local device) to fake repeat the track by re-playing it after it finishes when the loop on single track is enabled.
Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
Additional context Currently, Librespot does not support looping a single track once.
I believe to make this possible, it would require a custom new 'playback' mode that is not available to Spotify API, as 'repeated once track' behavior is going to be inferred from spotify_player AFAIK.
For what it's worth, ncspot
(another Rust/librespot
based Spotify TUI client) seems to have figured out a hack, although what distinguishes it from this project isn't immediately obvious. I'll try and dig deeper if I can find the time.
For what it's worth,
ncspot
(another Rust/librespot
based Spotify TUI client) seems to have figured out a hack, although what distinguishes it from this project isn't immediately obvious. I'll try and dig deeper if I can find the time.
The main difference is that ncspot
itself is an Spotify client (for streaming), while spotify_player
uses an integrated client from librespot. In other words, it's easier for ncspot
to implement the hack as they own the client implementation.
Is it that difficult to just check if the user has 'repeat once' and just replay the song after it ends? Or am I underestimating how difficult it is?
spotify_player
operates on API boundary and streaming client is just an "add-on" compared to ncspot
with streaming client as the main component. As a result, the app cannot have any assumption regarding the streaming client's behaviour.
Is it that difficult to just check if the user has 'repeat once' and just replay the song after it ends?
The problem is that you don't know when user has 'repeat once'. The integrated streaming client will automatically switch to repeat context
mode as repeat once
is not supported. As a result, when you query get-repeat-mode
API, the returned mode will be repeat context
.
There are different ways to implement the "hack". The easiest one is to start a new "one-track" playback if user wants to change the repeat mode to repeat once
. The drawback of this approach is that you will lose the previous context, or you cannot play the previous context when switching to different repeat mode.
Another approach is to add a separate fake track repeat
mode and a command to enable/disable the mode. The integrated client can be updated to queue the current song when it is about to end. I would prefer this approach as a workaround for the integrated client's limitation. Can start working on this when I'm free.
YAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
Implemented with #410. @apprehensions can you try the latest master
? The command is ToggleFakeTrackRepeatMode
with default binding M-r
(alt + r). Should see repeat: track (fake)
if the fake track repeat mode is enabled.
It plays the 'fake repeat' track twice, and then plays the next song in queue, then the 'fake repeat' track again.
2024-04-16T03:34:47.982937Z INFO spotify_player::streaming: Got a new player event: Playing { track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf"), position_ms: 0, duration_ms: 6400 }
2024-04-16T03:34:48.954772Z INFO spotify_player::client: Retrieving an image from the file: /home/sewn/.cache/spotify-player/image/Putrefaction in Progress-Last Days Of Humanity-cover.jpg
2024-04-16T03:34:49.428103Z INFO client_request{request=GetCurrentUserQueue}: spotify_player::client: successfully handled the client request, took: 416ms
2024-04-16T03:34:50.012162Z INFO spotify_player::client::handlers: fake track repeat mode is enabled, add the current track (Allowing the Carvings for Mutual Compassion) to queue
2024-04-16T03:34:50.240719Z INFO client_request{request=AddTrackToQueue(TrackId("4YkbI4N8UQZ5I5PZ2pRvcf"))}: spotify_player::client: successfully handled the client request, took: 228ms
2024-04-16T03:34:53.881673Z INFO spotify_player::streaming: Got a new player event: EndOfTrack { track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf") }
2024-04-16T03:34:53.881720Z INFO spotify_player::streaming: Got a new player event: Changed { old_track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf"), new_track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf") }
2024-04-16T03:34:53.881766Z INFO spotify_player::streaming: Got a new player event: Playing { track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf"), position_ms: 0, duration_ms: 6400 }
2024-04-16T03:34:55.272983Z INFO client_request{request=GetCurrentPlayback}: spotify_player::client: successfully handled the client request, took: 255ms
2024-04-16T03:35:00.026055Z INFO spotify_player::client::handlers: fake track repeat mode is enabled, add the current track (Allowing the Carvings for Mutual Compassion) to queue
2024-04-16T03:35:00.253885Z INFO client_request{request=AddTrackToQueue(TrackId("4YkbI4N8UQZ5I5PZ2pRvcf"))}: spotify_player::client: successfully handled the client request, took: 227ms
2024-04-16T03:35:00.281555Z INFO spotify_player::streaming: Got a new player event: EndOfTrack { track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf") }
2024-04-16T03:35:00.281606Z INFO spotify_player::streaming: Got a new player event: Changed { old_track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf"), new_track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf") }
2024-04-16T03:35:00.281657Z INFO spotify_player::streaming: Got a new player event: Playing { track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf"), position_ms: 0, duration_ms: 6400 }
2024-04-16T03:35:01.280046Z INFO client_request{request=GetCurrentPlayback}: spotify_player::client: successfully handled the client request, took: 252ms
2024-04-16T03:35:06.677844Z INFO spotify_player::streaming: Got a new player event: EndOfTrack { track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf") }
2024-04-16T03:35:06.677972Z INFO spotify_player::streaming: Got a new player event: Changed { old_track_id: TrackId("4YkbI4N8UQZ5I5PZ2pRvcf"), new_track_id: TrackId("1TA7Pw6JkLjhLyelvv2321") }
2024-04-16T03:35:06.678001Z INFO spotify_player::streaming: Got a new player event: Playing { track_id: TrackId("1TA7Pw6JkLjhLyelvv2321"), position_ms: 0, duration_ms: 39653 }
2024-04-16T03:35:07.342517Z INFO client_request{request=GetCurrentPlayback}: spotify_player::client: Retrieving an image from the file: /home/sewn/.cache/spotify-player/image/Putrefaction in Progress-Last Days Of Humanity-cover.jpg
2024-04-16T03:35:07.342625Z INFO client_request{request=GetCurrentPlayback}: spotify_player::client: successfully handled the client request, took: 308ms
2024-04-16T03:35:08.426592Z INFO client_request{request=GetCurrentUserQueue}: spotify_player::client: successfully handled the client request, took: 390ms
The timing between EndOfTrack
events seems too short. Did you seek to the end of the track to test the feature? The queue the current song when it is about to end
logic only applies once every 10s to avoid making duplicated requests. That might be the reason why it doesn't work well
No.. The song I was listening to was 9 seconds (that's grindcore for you, see track I'd) I am unable to test right now but given this I suppose it males sense.
ahh, super short song won't work with fake repeat mode unfortunately xD.