spotify-player icon indicating copy to clipboard operation
spotify-player copied to clipboard

Fake track repeat

Open apprehensions opened this issue 1 year ago • 1 comments

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.

apprehensions avatar Sep 07 '23 16:09 apprehensions

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.

apprehensions avatar Dec 29 '23 11:12 apprehensions

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.

Colonial-Dev avatar Apr 06 '24 22:04 Colonial-Dev

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.

aome510 avatar Apr 06 '24 22:04 aome510

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?

apprehensions avatar Apr 06 '24 23:04 apprehensions

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.

aome510 avatar Apr 07 '24 15:04 aome510

YAYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

apprehensions avatar Apr 16 '24 02:04 apprehensions

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.

aome510 avatar Apr 16 '24 02:04 aome510

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

apprehensions avatar Apr 16 '24 03:04 apprehensions

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

aome510 avatar Apr 16 '24 03:04 aome510

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.

apprehensions avatar Apr 16 '24 03:04 apprehensions

ahh, super short song won't work with fake repeat mode unfortunately xD.

aome510 avatar Apr 16 '24 04:04 aome510