- Add LogRetryAttempt() helper method for consistent logging
- Fix formatting in ShouldRetryRequest() for better readability
- Use helper method in both GetRecentTracksRequestFinished and GetTopTracksRequestFinished
- Eliminates duplicate logging code
Co-authored-by: jonaski <10343810+jonaski@users.noreply.github.com>
- Add named constants for retry-eligible HTTP status codes (500, 503)
- Add bounds checking in backoff calculation to prevent integer overflow
- Use kMaxBackoffShift constant to limit bit shift operations
- Improves code safety and readability
Co-authored-by: jonaski <10343810+jonaski@users.noreply.github.com>
- Extract retry condition check into ShouldRetryRequest() helper
- Extract backoff delay calculation into CalculateBackoffDelay() helper
- Use helper methods in both GetRecentTracksRequestFinished and GetTopTracksRequestFinished
- Improves code maintainability and consistency
Co-authored-by: jonaski <10343810+jonaski@users.noreply.github.com>
- Add API key field to Last.fm settings UI with helpful info text
- Store and load custom API key from settings
- Use custom API key in lastfmimport if provided, fall back to default
- Implement exponential backoff retry logic (up to 5 retries)
- Retry on HTTP 500/503 errors with increasing delays (5s, 10s, 20s, 40s, 80s)
- Add retry count tracking to request structures
Co-authored-by: jonaski <10343810+jonaski@users.noreply.github.com>
Ignore buffering messages when within 5 seconds of track end and about-to-finish has been signaled. This prevents spurious buffering from blocking playback during track transitions with local files.
Fixes#1725
Wait for ongoing state changes to complete before setting pipeline to NULL.
This prevents race conditions with async state transitions that can cause crashes in GStreamer elements.
Fixes#1875
Qobuz API now requires intent=stream parameter for stream URL requests,
and the app_secret must be extracted using the Spoofbuz decoding method
from bundle.js rather than plain-text values.
Changes:
- Add intent=stream parameter to stream URL requests
- Add QobuzCredentialFetcher class to extract credentials from web player
- Add "Fetch Credentials" button to Qobuz settings page
- Decode obfuscated app secrets using seed/timezone/info/extras method
This fixes "Invalid Request Signature" errors that prevented playback.
Replace per-pipeline QThreadPool with a shared static pool to prevent
file descriptor and thread exhaustion. Each GstEnginePipeline was creating
its own thread pool, leading to resource accumulation during frequent
pipeline creation/destruction (track changes, seeking, crossfade).
The shared pool is limited to 2 threads max since state changes are
typically sequential per pipeline. This prevents the crash in g_wakeup_new()
when creating eventfd for new thread event dispatchers.
Fixes#1687
Add guard in AboutToFinishCallback to prevent race condition when pipeline is being torn down. This prevents the callback from trying to set next URL while the pipeline is being destroyed, which caused crashes in GStreamer's decodebin3.
Fixes issue where rapidly switching tracks could cause segmentation fault in gst_decodebin_input_link_to_slot.
See: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4626Fixes#1863
Co-Authored-By: Jonas Kvinge <jonas@jkvinge.net>