Engineering reality: the player, background and PWA
Making a “playlist in the browser” is easy. Making it feel like radio is harder: you need seamless sound, a stable UI and behaviour that doesn’t break when conditions change (network, device, background).
1) The player as an engine
The “radio” effect rests on two things: crossfade and states. The player works as a state machine (idle → buffering → playing) so there’s no “double sound” and no races during switches. In parallel the next track is prefetched so that reactions to Next/Prev feel fast.
2) Why there’s a “Listen in background” button
On iOS/WebView the “rich” mode (WebAudio, video loops, timers, prefetch) is often cut aggressively when the app is minimised. So the “Listen in background” button moves the radio to a lighter profile: it turns off the heavy parts, leaves stable playback through a simple <audio>, and gives a quick return to the main mode without losing context.
3) PWA
PWA here isn’t about being “native”. It gives a more predictable interface launch and raises the chance that a session will live longer. But I don’t promise the impossible: background on the web can’t be guaranteed, which is why a separate “background mode” is needed.
4) Gesture gate: Telegram Mini App / Safari WebView
There’s one more “grown-up” layer of reliability: when a platform forbids autoplay (especially in WebView), the project doesn’t look broken. Visuals go into a waiting mode until the first user gesture and after a tap start again neatly. It’s a rare but important detail: in this situation most web players silently “don’t play” and look like a bug, while here it’s a meaningful degradation for real constraints.
Telegram content turns into a media object rather than a feed of links, and the system honestly takes platform constraints into account.