flutter_radio_player 4.0.1
flutter_radio_player: ^4.0.1 copied to clipboard
Online Radio Player for Flutter with background playback, lock screen controls, and streaming support for Android and iOS.
Flutter Radio Player #
A Flutter plugin for playing streaming radio URLs with background playback, lock screen controls, and platform-native media integrations including watchOS, WearOS, CarPlay, and Android Auto.
| Android | iOS | |
|---|---|---|
| Support | SDK 21+ | iOS 14+ |
Features #
- Background audio playback with no extra configuration
- Lock screen and notification media controls
- ICY/stream metadata extraction
- Multiple source queue with next/previous/jump-to navigation
- Volume control with stream updates
- watchOS, WearOS, CarPlay, and Android Auto integration
Getting Started #
Installation #
flutter pub add flutter_radio_player
Usage #
import 'package:flutter_radio_player/flutter_radio_player.dart';
final player = FlutterRadioPlayer();
// Initialize with sources
await player.initialize(
[
const RadioSource(url: 'https://s2-webradio.antenne.de/chillout?icy=https'),
const RadioSource(
url: 'https://radio.lotustechnologieslk.net:2020/stream/sunfmgarden?icy=https',
title: 'SunFM - Sri Lanka',
artwork: 'images/sample-cover.jpg', // bundled asset
),
const RadioSource(url: 'http://stream.riverradio.com:8000/wcvofm.aac'),
],
playWhenReady: true,
);
Controlling Playback #
await player.play();
await player.pause();
await player.playOrPause();
await player.nextSource();
await player.previousSource();
await player.jumpToSourceAtIndex(1);
await player.setVolume(0.8);
final volume = await player.getVolume();
await player.dispose();
Listening to Streams #
player.isPlayingStream.listen((bool isPlaying) {
print('Playing: $isPlaying');
});
player.nowPlayingStream.listen((NowPlayingInfo info) {
print('Now playing: ${info.title}');
});
player.volumeStream.listen((VolumeInfo vol) {
print('Volume: ${vol.volume}, Muted: ${vol.isMuted}');
});
Platform Setup #
Android #
Add the following permissions to your app's AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
These permissions are already declared by the plugin. You only need to add them if your app's manifest merger requires it.
iOS #
Enable Audio, AirPlay, and Picture in Picture under your target's Signing & Capabilities > Background Modes in Xcode.
If your radio streams use plain HTTP, add the following to your Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
API Reference #
Methods #
| Method | Description |
|---|---|
initialize(sources) |
Set sources and optionally auto-play |
play() |
Resume playback |
pause() |
Pause playback |
playOrPause() |
Toggle play/pause |
setVolume(double) |
Set volume (0.0 to 1.0) |
getVolume() |
Get current volume |
nextSource() |
Skip to next source |
previousSource() |
Skip to previous source |
jumpToSourceAtIndex(i) |
Jump to source at index |
dispose() |
Release player resources |
Streams #
| Stream | Type | Description |
|---|---|---|
isPlayingStream |
Stream<bool> |
Playback state changes |
nowPlayingStream |
Stream<NowPlayingInfo> |
Track metadata updates |
volumeStream |
Stream<VolumeInfo> |
Volume and mute changes |
Models #
const RadioSource({required String url, String? title, String? artwork});
const NowPlayingInfo({String? title});
const VolumeInfo({required double volume, required bool isMuted});
Migration from v3 #
// Sources
- player.initialize([{"url": "...", "title": "..."}], true);
+ player.initialize([const RadioSource(url: '...', title: '...')], playWhenReady: true);
// Streams
- player.getPlaybackStream()
+ player.isPlayingStream
- player.getNowPlayingStream()
+ player.nowPlayingStream
- player.getDeviceVolumeChangedStream()
+ player.volumeStream
// Methods
- player.prevSource()
+ player.previousSource()
- player.setVolume(0.5) // unchanged
+ player.setVolume(0.5)
// New
+ await player.dispose();
+ await player.playOrPause(); // now works on iOS too
Example #
See the example app for a complete implementation.
Contributing #
Contributions are welcome. Please open an issue first to discuss what you would like to change.