If you are building a radio app, flutter just_audio streaming is one of the most popular ways to play live audio on Android and iOS. The just_audio package is powerful and well maintained, but live radio streams bring their own set of headaches. A stream that plays fine in your browser can stay silent in your app, cut out after a few minutes, or work on Android and fail on iPhone.
In this guide we walk through the most common radio playback errors, explain why they happen in plain language, and show you how to fix them. You don't need to be an expert. A basic Flutter project and a stream URL are enough to follow along.
How flutter just_audio streaming works (in simple terms)
Before fixing errors, it helps to know what is happening behind the scenes. When you give just_audio a URL, it hands that URL to the native player on each platform. On Android that is ExoPlayer. On iOS it is AVPlayer. Your Dart code is just the remote control.
This matters because most streaming errors are not Flutter bugs. They come from platform rules, server settings or the stream format. A basic setup looks like this in practice:
- Create an AudioPlayer instance.
- Call setUrl() with your stream address.
- Call play() and listen to the player state.
- Dispose of the player when the screen closes.
If any step fails, just_audio usually throws a PlayerException or simply never reaches the "ready" state. Always wrap setUrl() in a try/catch block and print the error. That one habit will save you hours.
Error 1: The stream works on Android but not on iOS
This is the most common complaint we hear. The cause is almost always HTTP instead of HTTPS.
Why it happens
Apple's App Transport Security (ATS) blocks plain HTTP connections by default. Many older Shoutcast and Icecast servers still broadcast on addresses like http://yourserver:8000/stream. iOS refuses to connect, and the player fails silently or throws a generic error.
How to fix it
- Best option: use an HTTPS stream URL. Most modern radio panels can provide one with an SSL certificate.
- Quick option: add an ATS exception in ios/Runner/Info.plist using NSAppTransportSecurity. You can allow arbitrary loads or allow only your stream domain, which is safer.
Keep in mind that Apple reviewers may ask why you need an exception, so HTTPS is the cleaner long-term answer.
Error 2: Android shows "Cleartext HTTP traffic not permitted"
Android has a similar rule. Since Android 9, apps block cleartext (HTTP) traffic unless you allow it.
How to fix it
- Switch to an HTTPS stream if you can.
- Or add android:usesCleartextTraffic="true" to the application tag in your AndroidManifest.xml.
- For tighter security, create a network security config that allows cleartext only for your stream domain.
Also check that the INTERNET permission is in your release manifest. Debug builds include it automatically, but release builds may not. This is a classic "it worked yesterday" bug when you publish your first build.
Error 3: The URL is not actually a stream
Many beginners copy a link from a radio website and paste it into the app. Often that link points to a web player page, a .pls file or an .m3u playlist, not the audio itself.
How to check your URL
- Open the URL in VLC. If audio plays straight away, it is likely a real stream.
- If the link downloads a small text file, open it. The real stream address is inside.
- Look for endings like /stream, /live, ;stream.mp3 or .m3u8 for HLS.
For flutter just_audio streaming, MP3 and AAC streams are the most reliable across both platforms. HLS works well too, especially on mobile networks. Unusual codecs may play on one platform and fail on the other, so test both early.
Error 4: Playback stops in the background or after a few minutes
Radio listeners expect music to keep playing when they lock the screen. By default, just_audio alone will not keep your app alive in the background.
Enable background audio
- Add the just_audio_background package (or audio_service for more control).
- On iOS, enable the "Audio, AirPlay and Picture in Picture" background mode in Xcode.
- On Android, add the required service and permissions described in the package documentation, including the foreground service settings.
- Provide a MediaItem tag so the lock screen shows your station name and artwork.
Handle dropouts with auto-reconnect
Live streams can drop when a user moves from Wi-Fi to mobile data, or when the server restarts. Listen to playbackEventStream for errors and to processingState for a "completed" state. Since a live stream should never really "complete", treat that as a disconnect: wait a couple of seconds, call setUrl() again and resume. A simple retry loop with a short delay makes your app feel much more professional.
Error 5: Slow start, buffering and server problems
Sometimes the app code is perfect but the stream itself is the weak link. If your station takes ages to start or buffers constantly, look at the server side:
- Bitrate: a very high bitrate struggles on weak mobile connections. 64–128 kbps is a common balance for radio.
- Listener limits: if your plan caps listeners, new users may be refused when you are full.
- Server location and stability: an unreliable or overloaded server causes dropouts no matter how good your app is.
- Metadata: if you want live song titles in the app, make sure your server sends ICY metadata. just_audio exposes it through icyMetadataStream.
If you need a dedicated radio server, take a look at our SonicPanel radio hosting plans (Radio Lite, Pro and Max), built for running online radio stations.
A quick troubleshooting checklist
When flutter just_audio streaming fails, run through this list before digging deeper:
- Does the URL play in VLC?
- Is it HTTPS? If not, have you added the iOS and Android exceptions?
- Is the INTERNET permission in your release manifest?
- Are you catching and printing PlayerException errors?
- Is background audio configured on both platforms?
- Do you have reconnect logic for dropped streams?
- Have you tested on a real device, not just an emulator?
Fixing these seven points solves the vast majority of radio playback issues we see.
Want a ready-made radio app instead?
Building and debugging a streaming app from scratch takes time. If you would rather launch quickly, our Single Radio Flutter app is a single-station radio app for Android and iOS with a music visualizer, sleep timer and AdMob support. If you need a full directory of stations, the WorldRadios radio directory script combines a Laravel website with a Flutter app for Android and iPhone.
Prefer something built around your own idea? Our team can create a custom radio app for you. Visit our Flutter App Development service to see how we can help, or get a free quote today and tell us about your project.
Frequently asked questions
Why does my radio stream play on Android but not on iOS?
The most common cause is an HTTP stream. iOS App Transport Security blocks plain HTTP by default, so use an HTTPS stream URL or add an exception in your Info.plist.
Can just_audio play Shoutcast and Icecast streams?
Yes. just_audio can play most Shoutcast and Icecast streams that use MP3 or AAC. Make sure you use the direct stream URL, not a playlist file or a web player page.
How do I keep the radio playing when the app is in the background?
Pair just_audio with the just_audio_background or audio_service package and add the required background audio settings for Android and iOS.
Why does my stream keep stopping after a few minutes?
This usually comes from an unstable server connection, a weak mobile network or the operating system killing the app. Listen for errors and add automatic reconnect logic in your code.
What stream format works best with just_audio?
MP3 and AAC streams over HTTPS are the most reliable choice across Android and iOS. HLS (.m3u8) is also supported and works well on mobile networks.


