Git Product home page Git Product logo

Comments (11)

kingosticks avatar kingosticks commented on June 24, 2024 1

I think https://github.com/librespot-org/librespot/blob/dev/playback/src/player.rs#L941 is the culprit but I don't know/remember why that

In any case we go into a Loading state to load the track

means we also need to stop the sink (and cause your pop).

It might be possible to trigger TimeToPreloadNextTrack event (or similar) before we do the actual load but it probably needs something blocking. Maybe something like preload_data_before_playback() e.g. preload_data_before_next(). These both feel like sticking plasters.

from librespot.

jrfaller avatar jrfaller commented on June 24, 2024 1

Status update: got librespot working fine using @kingosticks fix for #1179: librespot] librespot 0.5.0-dev 1896611 (Built on 2023-10-27, Build ID: Rjfa9F0L, Profile: debug).

On this version, the behavior is the same as 0.4.2.

I tried removing self.ensure_sink_stopped(play); as suggested by @roderickvd and 🥁 there is no longer a pop when clicking next, which fixes my problem 👍🏻

from librespot.

jrfaller avatar jrfaller commented on June 24, 2024

Thanks for the pointer!

Fun fact, if I wait to be near the end of the song (a little after the total time of the song minus PRELOAD_NEXT_TRACK_BEFORE_END_DURATION_MS) and I click next, then there is no pop, meaning there is probably enough data to make a gapless play. Therefore, it makes me wonder two things:

  • I am not sure why it's a good thing to wait this long before preloading the data since triggering the next button can happen anytime. Could data be loaded as soon as the buffer for the current song is full?
  • When clicking next, it is expected that there will be a new song to be played, so even with no available data for the next song, why release the sink?

Maybe it would be a good idea regardless of my pop problem to have a "gapless" next for instance if one-day crossfading gets implemented.

Cheers!

from librespot.

roderickvd avatar roderickvd commented on June 24, 2024

As part of the shift to the HTTP CDN in dev, I also rewrote large parts of the preloading logic. Unfortunately I got little to no feedback at that time, so not sure if this is a regression or not.

For purpose of diagnostics, would you please try the latest 0.4 release and see what happens there?

I think https://github.com/librespot-org/librespot/blob/dev/playback/src/player.rs#L941 is the culprit but I don't know/remember why that

In any case we go into a Loading state to load the track

means we also need to stop the sink (and cause your pop).

I also think that's wrong. This already deals with this correctly:

if !self.config.gapless {
So I think this would be safe to remove:
self.ensure_sink_stopped(play);

It might be possible to trigger TimeToPreloadNextTrack event (or similar) before we do the actual load but it probably needs something blocking. Maybe something like preload_data_before_playback() e.g. preload_data_before_next(). These both feel like sticking plasters.

Fun fact, if I wait to be near the end of the song (a little after the total time of the song minus PRELOAD_NEXT_TRACK_BEFORE_END_DURATION_MS) and I click next, then there is no pop, meaning there is probably enough data to make a gapless play. Therefore, it makes me wonder two things:

  • I am not sure why it's a good thing to wait this long before preloading the data since triggering the next button can happen anytime. Could data be loaded as soon as the buffer for the current song is full?

This preloading implementation, like the previous one, estimates when it should start downloading depending on network throughput and time left. So it's optimised to save bandwidth. I never gave it much thought, but I think you are right. In this age there is little reason not start the preload immediately. Though I'm no longer an active developer, from what I remember this should be easy to do.

Of course, it's also entirely possible that a user selects a "next" song which is not next in queue. That could still trigger your pop. It never did for me, so I guess it depends on the output device. So an alternative to preloading immediately, covering this case as well, is to a quick mute-unmute cycle when manually changing songs. Somewhere in the area of 20 ms ramp time should work fine. This will take a little more effort to put in.

from librespot.

jrfaller avatar jrfaller commented on June 24, 2024

Thanks for the detailed answer!

For purpose of diagnostics, would you please try the latest 0.4 release and see what happens there?

I ran into the issue with the following release on moodeaudio: [2023-10-25T18:31:33Z INFO librespot] librespot 0.4.2 22f8aed (Built on 2022-08-18, Build ID: LQ4hikXT, Profile: release) would you like me to try with other releases?

This preloading implementation, like the previous one, estimates when it should start downloading depending on network throughput and time left. So it's optimised to save bandwidth. I never gave it much thought, but I think you are right. In this age there is little reason not start the preload immediately. Though I'm no longer an active developer, from what I remember this should be easy to do.

I believe that it would be nice to have a more eager strategy for preloading since users with bad bandwidth can disable gapless playing

Of course, it's also entirely possible that a user selects a "next" song which is not next in queue. That could still trigger your pop. It never did for me, so I guess it depends on the output device. So an alternative to preloading immediately, covering this case as well, is to a quick mute-unmute cycle when manually changing songs. Somewhere in the area of 20 ms ramp time should work fine. This will take a little more effort to put in.

The pop is clearly a design mistake from my DAC manufacturer, I totally can live with a pop if my playlist has ended, and I do not have autoplay 😆

from librespot.

roderickvd avatar roderickvd commented on June 24, 2024

Yeah in that case please try compiling from dev?

from librespot.

kingosticks avatar kingosticks commented on June 24, 2024

covering this case as well, is to a quick mute-unmute cycle when manually changing songs.

That's a nice idea.

from librespot.

jrfaller avatar jrfaller commented on June 24, 2024

covering this case as well, is to a quick mute-unmute cycle when manually changing songs.

That's a nice idea.

Oooh maybe I did not understand the proposal, it means that when clicking the next button librespot would mute / load the next song / unmute instead of recreating a sink?

Yeah in that case please try compiling from dev?

Ok tried that, surprisingly easy on the raspberry. Got [2023-10-26T18:36:41Z INFO librespot] librespot 0.5.0-dev 054074c (Built on 2023-10-26, Build ID: GBF8F7wi, Profile: debug) running. Unfortunately, ran over some ERROR librespot_core::mercury] error 403 for uri hm://keymaster/token/authenticated?scope=playlist-read&client_id= errors that I do not understand because connexion and authentication seemed to work fine (and got no sound to test the pop).

from librespot.

jrfaller avatar jrfaller commented on June 24, 2024

Another testing update: not only does the removal of self.ensure_sink_stopped(play); fix the sink closing when clicking on the next button but it also avoids closing the sink when directly changing to another song when a song is playing. As far as I can tell, no regression was detected!

from librespot.

roderickvd avatar roderickvd commented on June 24, 2024

Could you put in a PR to fix it for everyone?

from librespot.

jrfaller avatar jrfaller commented on June 24, 2024

Of course! Here it is at #1223

from librespot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.