Just an update to this issue -- for some reason, in the past month or two, this has suddenly been reported by a huge number of clients out of the blue while it had never been brought to my attention before that. As best I can tell, though, this is how Liquidsoap *always* worked, so I'm not sure what prompted the sudden onslaught of bug reports. But clearly it merits some investigation at this point.
Per AlexiuB's comment, this appears to be "just how Liquidsoap works", so we need to implement a workaround on our end. And to do so, we have to have a number of elements in place in -- first and foremost, we need to have an extremely accurate length for each song in our database. Centova Cast relies on the excellent and widely-used TagLib library to extract details about each song, but unfortunately TagLib explicitly avoids implementing workarounds for poorly-encoded MP3s... and unfortunately, many popular MP3 encoders actually produce technically-incorrect (or at least, "very nonstandard") MP3s, so it's not at all uncommon to find a lot of these MP3s in users' libraries. And TagLib tends to return invalid lengths and/or bitrates for such MP3s.
To tackle this, I've spent the past week or so creating our own in-house patch to TagLib to allow it to handle a wide variety of, shall we say, "differently-encoded" MP3 files, and ensure that our song length calculation is as accurate as it can be. As a benchmark, I calculated song lengths for tens of thousands of MP3s using Winamp, and then ran the same test using our modified TagLib. Our test corpus explicitly included our collection of "misbehaved" MP3s that have been known to cause problems in the past.
In our test, the only cases where the results from our modified TagLib differed from Winamp's were cases in which Winamp either calculated the length incorrectly or was unable to read the MP3 file at all. That is, our modified TagLib is actually more accurate than Winamp for our test corpus.
So that's step 1. The next step will be to integrate our modified TagLib into Centova Cast, and then add code to Centova Cast to guess what Liquidsoap is after when it requests a new song -- i.e., whether it's looking for a song to play "now", or whether it's looking for a song to play "an hour from now when this song finishes".
Of course, that's going to cause complications when it comes to skipping songs as well; that is, if Liquidsoap has already queued a song that's not due to play until an hour from now, and you click "Skip song", Liquidsoap is going to immediately play a track that's not supposed to play until an hour from now. I'm still looking into potential solutions for that problem and a few others; there are a few odd corner cases like this, and I hope this serves as an example of why this hasn't been a simple problem to work around.