49bbb54bb9c67610f2b9eebc0bdc1605d0037050
- 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
24/7 Radio
Personal-use Android app for 24/7 internet radio streaming.
Features
- Custom Raw Audio Pipeline — OkHttp → IcyParser → Mp3FrameSync → MediaCodec → AudioTrack for absolute minimum latency (~26ms per MP3 frame)
- Stay Connected Mode — Aggressive reconnection with exponential backoff, never gives up
- Dual Timers — Session elapsed time and connection elapsed time
- Latency Indicator — Estimated stream-to-speaker latency
- Icecast/Shoutcast Metadata — Track title, artist extraction from ICY protocol
- Album Art — MusicBrainz/Cover Art Archive lookup with fallback chain
- Playlist Management — PLS/M3U import/export with #EXTIMG support
- Station Organization — Playlists, starring/favoriting, manual reorder
Requirements
- Android 9.0+ (API 28)
- Internet connection
Build
./gradlew assembleDebug
Import Stations
- Open the app
- Tap the import icon in the top bar
- Select a .m3u or .pls file
- Stations are added to your list
Architecture
See Design Document and Implementation Plan.
Description
Android app for 24/7 internet radio streaming with minimum latency, aggressive reconnection, and full Icecast/Shoutcast metadata support.
Languages
Kotlin
97.3%
Shell
2.7%