feat: qbz-1 streaming, gapless prefetch, accurate scrobbling, Range-seek
Port proven playback architecture from qbqt fork: - Bounded VecDeque buffer with condvar backpressure (4MB cap) - decrypt_and_extract_frames for clean FLAC frame extraction from ISOBMFF - Cancel+restart seeking with sub-segment sample skipping - start_prefetch / QueueNext for gapless transitions with pre-started downloads - track_transitioned signaling for scrobbler during gapless playback - Range-request HTTP seeking for non-segmented (MP3) tracks - OnceLock HTTP client singleton with cancel-aware chunked downloads - Accumulated listening time scrobbling (prevents false scrobbles from seeking) - Array-format Last.fm scrobble params (artist[0], track[0], etc.) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -209,21 +209,6 @@ quint64 QobuzBackend::duration() const { return qobuz_backend_get_duration(m_bac
|
||||
int QobuzBackend::volume() const { return qobuz_backend_get_volume(m_backend); }
|
||||
int QobuzBackend::state() const { return qobuz_backend_get_state(m_backend); }
|
||||
|
||||
quint32 QobuzBackend::vizRead(float *buf, quint32 maxSamples)
|
||||
{
|
||||
return qobuz_backend_viz_read(m_backend, buf, maxSamples);
|
||||
}
|
||||
|
||||
quint32 QobuzBackend::vizSampleRate() const
|
||||
{
|
||||
return qobuz_backend_viz_sample_rate(m_backend);
|
||||
}
|
||||
|
||||
quint32 QobuzBackend::vizChannels() const
|
||||
{
|
||||
return qobuz_backend_viz_channels(m_backend);
|
||||
}
|
||||
|
||||
// ---- private slots ----
|
||||
|
||||
void QobuzBackend::onPositionTick()
|
||||
@@ -232,6 +217,9 @@ void QobuzBackend::onPositionTick()
|
||||
|
||||
if (qobuz_backend_take_track_finished(m_backend))
|
||||
emit trackFinished();
|
||||
|
||||
if (qobuz_backend_take_track_transitioned(m_backend))
|
||||
emit trackTransitioned();
|
||||
}
|
||||
|
||||
void QobuzBackend::onEvent(int eventType, const QString &json)
|
||||
|
||||
Reference in New Issue
Block a user