fix(player): lazy-load and cache real bitrate and sample rate for local songs - #38
Closed
adam-adrian wants to merge 11 commits into
Closed
fix(player): lazy-load and cache real bitrate and sample rate for local songs#38adam-adrian wants to merge 11 commits into
adam-adrian wants to merge 11 commits into
Conversation
adam-adrian
force-pushed
the
fix/local-media-bitrate-info
branch
from
July 6, 2026 07:29
581ed30 to
cdba7d0
Compare
|
I think this needs a bit more cleanup before merge. main issue: the retry/cache logic can still keep re-running also, cached bitrate/sampleRate should probably be reset when the local file changes ( |
adam-adrian
force-pushed
the
fix/local-media-bitrate-info
branch
from
July 7, 2026 04:24
cdc22b5 to
53e9800
Compare
…al songs Implements an on-demand background extraction of real audio metadata (bitrate and sample rate) for local files to replace the default "Unknown" representation on the player screen: 1. Dynamic Lazy-Loading: Integrates a Coroutines flow collector inside PlayerConnection to trigger extraction precisely when a local song starts playing. This guarantees that full library scans remain lightning fast without blocking physical I/O. 2. Safe Persistence & Anti-Overwrite: Adds a targeted database update query to save successfully extracted metadata to the FormatEntity. Concurrently refactors LocalSongScanner to preserve these extracted values during full-library rescans. 3. MediaExtractor & Sentinel Defense: Uses Android's native MediaExtractor for universal API level compatibility. Implements a sentinel value of '-1' for corrupted or unreadable local files to prevent wasteful and battery-draining repeated extraction loops. 4. Robust Concurrency: Employs collectLatest combined with Coroutine's native isActive check to prevent race conditions or out-of-order database writes during fast-skipping.
…erformance Refactors and optimizes the local audio metadata lazy-loading and database preservation flow to prevent visual regressions, eliminate N+1 queries, and secure cache invalidation: 1. Optimize Scanner Performance (Batch Load): Replaced the N+1 single-row "getFormatById" database query inside the LocalSongScanner loop with a single targeted batch query "getFormatsByIds" executed at scan start, reducing database roundtrips to O(1) via an in-memory Map. 2. Automatic Cache Invalidation: Introduced a file size comparison check (contentLength vs sizeBytes) during device scans. If a local file has changed in size (e.g. via re-encoding), the cached bitrate/sampleRate is safely reset to force an updated extraction on the next play. 3. Perfect Sentinel & Retry Defense: Refactored the player evaluation block to check both 'bitrate == 0' and 'sampleRate == null'. This guarantees that if metadata is only partially successfully extracted, or falls back to a failed sentinel of '-1', we permanently prevent repetitive and battery-draining MediaExtractor execution.
…n failures
Formally declares the targeted 'getFormatsByIds(ids: List<String>)' batch query within DatabaseDao.kt. This resolves the unresolved reference compilation errors on the scanner side ('LocalSongScanner.kt') introduced in the previous optimization commit.
… bitrate is missing
Optimizes CodecInfoRow invocation logic across player styles V1, V3, V4, V7, and V9. When the local audio file's bitrate is unavailable ("Unknown"), the player dynamically substitutes the missing bitrate field with the extracted high-resolution sample rate (e.g. "FLAC • 44.1 kHz • 25 MB"). Player V2 is safely untouched as it natively renders all fields by default. This guarantees high-fidelity Lossless flexing is always displayed beautifully, regardless of the chosen player style.
adam-adrian
force-pushed
the
fix/local-media-bitrate-info
branch
2 times, most recently
from
July 7, 2026 04:56
1de9c79 to
a9644cf
Compare
…y helper Refactors player codec information rows (V1, V3, V4, V7, and V9 player styles) by consolidating the duplicate fallback evaluation block into a single, clean extension function inside FormatEntity.kt: 1. Unify Codec Evaluation: Added 'RatePriority' enum and 'FormatEntity.autoRateDisplay(priority)' helper in FormatEntity.kt. This unified function gracefully manages sample rate and bitrate fallback priorities, while ensuring absolute robust handling of empty string or null conversions. 2. Clean Up UI Duplication: Replaced over 60 lines of redundant and duplicated Kotlin evaluation logic scattered across 5 collapsed player styles inside QueueComponents.kt with a single, highly readable O(1) invocation call 'currentFormat.autoRateDisplay()'.
adam-adrian
force-pushed
the
fix/local-media-bitrate-info
branch
from
July 7, 2026 05:33
6dd3fd2 to
749be02
Compare
…SQL variable limit Hardens PlayerConnection and LocalSongScanner against critical production-level issues: 1. Fix Coroutine Cancellation Swallowing: Converted 'extractLocalAudioProperties' into a suspend function running on 'withContext(Dispatchers.IO)'. Propagates 'CancellationException' by invoking 'ensureActive()' inside the try-catch block to prevent leaking background thread I/O during skip transitions. 2. Safe SQLite Batch Chunking: Implemented '.chunked(SqlBatchSize)' grouping inside the scanner on scannedIds before executing 'database.getFormatsByIds' query. This ensures large local music libraries (>999 songs) are 100% immune to SQLiteException variables limit crash. 3. Idiomatic Cancellation Check: Replaced manual 'isActive' check in PlayerConnection with explicit 'ensureActive()' precisely before updating SQLite database records.
- Store metadata extraction Job reference, cancel on dispose() - Reset all file-derived metadata when file changes, not just bitrate/sampleRate - Check dateModified in addition to size for cache invalidation - Distinguish temporary vs permanent failures in metadata extraction - Confirm global autoRateDisplay() behavior is intentional - Fix string-based business logic in autoRateDisplay()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.