Files
Android-247-Radio/chat-summaries/2026-03-09_full-implementation-summary.md
cottongin 49bbb54bb9 fix: star visibility, station switching, skip-ahead, and latency optimizations
- Star icons now use distinct tint colors (primary vs faded) for clear state
- Station switching no longer races — old playback job is cancelled before new
- Skip-ahead drops ~1s of buffered audio per tap via atomic counter
- Custom SocketFactory with SO_RCVBUF=16KB and TCP_NODELAY for minimal TCP buffering
- Catch-up drain: discards pre-buffered frames until network reads block (live edge)
- AudioTrack PERFORMANCE_MODE_LOW_LATENCY for smallest hardware buffer

Made-with: Cursor
2026-03-10 04:41:40 -04:00

76 lines
3.1 KiB
Markdown

# Full Implementation — Android 24/7 Radio
**Date:** 2026-03-09
## Task Description
Brainstormed, designed, planned, and implemented a complete Android 24/7 internet radio streaming app from scratch using subagent-driven development.
## What Was Built
### Audio Engine (custom raw pipeline)
- **StreamConnection** — OkHttp HTTP client with ICY metadata header support
- **IcyParser** — Separates audio bytes from ICY metadata, parses StreamTitle into artist/title
- **Mp3FrameSync** — Finds MP3 frame boundaries with two-frame validation and re-sync
- **AudioEngine** — Wires pipeline: StreamConnection → IcyParser → RingBuffer → Mp3FrameSync → MediaCodec → AudioTrack
### Android Service Layer
- **RadioPlaybackService** — Foreground service with wake lock, wifi lock, MediaSession
- **Stay Connected** — Exponential backoff reconnection (1s→30s cap), ConnectivityManager callback for instant retry
- **NotificationHelper** — Media-style notification with stop action
- **RadioController** — Shared state between service and UI via StateFlow
### Data Layer
- **Room Database** — Station, Playlist, MetadataSnapshot, ListeningSession, ConnectionSpan entities with full DAOs
- **DataStore Preferences** — stayConnected, bufferMs, lastStationId
- **PLS/M3U Import/Export** — Full parsers with #EXTIMG support, round-trip tested
### UI (Jetpack Compose + Material 3)
- **Station List** — Playlists as expandable groups, starring, tap-to-play, long-press menu, import
- **Now Playing** — Album art, dual timers (session + connection), latency indicator, stay connected toggle, buffer slider
- **Settings** — Playback prefs, playlist export, recently played, track history with search
- **MiniPlayer** — Bottom bar on station list when playing
### Metadata
- **AlbumArtResolver** — MusicBrainz/Cover Art Archive → ICY StreamUrl → #EXTIMG → placeholder
- **ArtCache** — In-memory LRU cache (500 entries)
- **Coil 3** — Image loading in Compose
## Commit History (20 commits)
1. Design document and implementation plan
2. Project scaffolding (Gradle, manifest, dependencies)
3. Room entities, DAOs, database, DataStore
4. M3U/PLS import/export with tests
5. ICY metadata parser with tests
6. MP3 frame synchronizer with tests
7. HTTP stream connection with tests
8. Audio engine integration
9. Foreground service with Stay Connected
10. Material 3 theme and navigation
11. Station List screen
12. Now Playing screen with dual timers
13. Settings screen with history
14. Album art resolution with MusicBrainz
15. Final integration and README
## Test Coverage
- IcyParser: 10 tests
- Mp3FrameSync: 9 tests
- StreamConnection: 6 tests
- M3uParser: 6 tests
- PlsParser: 5 tests
- PlaylistExporter: 4 tests
- RingBuffer: 4 tests
- AlbumArtResolver: 9 tests (MockWebServer)
## Follow-Up Items
- Test on actual Android 9 device with real Icecast/Shoutcast streams
- Add drag-to-reorder for stations and playlists
- Implement latency estimation from AudioTrack write/play head positions
- Add Bluetooth headset AUDIO_BECOMING_NOISY handling
- Add audio focus management
- Future: recording, clips, analytics (schema already supports it)