搜尋套件、儲存庫與 APP 分類

套件詳情v4.1.0

flutter_radio_player

適用於 Flutter 的線上廣播播放器,支援背景播放、鎖定畫面控制以及 Android 與 iOS 的串流支援。

AndroidiOS
近 30 天下載
109
喜歡數
137
Pub 分數
160

安裝套件

flutter pub add flutter_radio_player

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

Flutter Radio Player 是一個 Flutter 套件,讓開發者能在應用程式中整合線上廣播串流功能,支援 Android 與 iOS 的背景播放與鎖屏控制。它提供無縫的音訊串流,讓使用者能不受中斷地聆聽網路廣播電台。此套件設計注重易用性,提供簡潔的 API 來管理播放、元資料顯示與媒體會話整合。它利用原生平台功能,確保跨裝置的順暢表現。

適用情境

  • 串流網路廣播電台
  • 建構支援背景播放的音樂或播客應用
  • 建立具有鎖定畫面媒體控制的應用程式
  • 開發面向行動裝置的音訊應用
  • 在應用掛起期間啟用連續播放

主要特色

  • 背景音頻播放
  • 鎖屏媒體控制
  • 跨平台支援(Android 與 iOS)
  • 即時串流整合
  • 媒體會話管理
  • 播放期間的元數據顯示

適合對象

  • 移動音頻應用開發者
  • 廣播電台應用開發者
  • 需要持續音頻播放的應用程式
  • 同時針對 Android 和 iOS 的開發者
  • 需要最少設定即可串流傳輸音訊的專案

使用建議

  • 需要適當的權限以在背景執行
  • 可能需要為iOS後台模式進行額外設定
  • 依賴穩定的互聯網連接進行串流
  • 僅限音訊內容
  • 平台特定的行為可能會略有不同

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

logo

Flutter Radio Player

Pub Version Pub Likes Pub Points CI

A Flutter plugin for playing streaming radio with background playback, lock screen controls, and platform-native media integrations.

Example Player

Android iOS
Support SDK 21+ iOS 14+

Features

  • Background audio playback with no extra configuration
  • Lock screen and notification media controls
  • ICY/Shoutcast metadata extraction
  • Multiple source queue with next/previous/jump-to navigation
  • Volume control with stream updates
  • Artwork support (asset paths and remote URLs)
  • watchOS, WearOS, CarPlay, and Android Auto integration
  • Swift Package Manager and CocoaPods support on iOS

Quick Start

Installation
flutter pub add flutter_radio_player
Minimal Example
import 'package:flutter_radio_player/flutter_radio_player.dart';

final player = FlutterRadioPlayer();

await player.initialize([
  const RadioSource(url: 'https://example.com/stream'),
], playWhenReady: true);

Working with Sources

Define your radio stations using the RadioSource model:

const sources = [
  RadioSource(url: 'https://example.com/stream'),
  RadioSource(
    url: 'https://example.com/jazz',
    title: 'Jazz FM',
    artwork: 'assets/jazz_cover.jpg', // bundled asset
  ),
  RadioSource(
    url: 'https://example.com/rock',
    title: 'Rock Radio',
    artwork: 'https://example.com/rock_cover.png', // remote URL
  ),
];

await player.initialize(sources, playWhenReady: true);
Field Type Description
url String Stream URL (required)
title String? Display name for lock screen
artwork String? Asset path or URL for album artwork

Working with Playback Controls

await player.play();
await player.pause();
await player.playOrPause(); // toggle

// Navigate sources
await player.nextSource();
await player.previousSource();
await player.jumpToSourceAtIndex(2);

// Volume (0.0 to 1.0)
await player.setVolume(0.8);
final volume = await player.getVolume();

// Clean up when done
await player.dispose();

Working with Streams

Listen to real-time player state changes using streams:

Playback State
player.isPlayingStream.listen((bool isPlaying) {
  print(isPlaying ? 'Playing' : 'Paused');
});
Now Playing / ICY Metadata
player.nowPlayingStream.listen((NowPlayingInfo info) {
  print('Now playing: ${info.title}');
});

The nowPlayingStream automatically extracts ICY metadata from Shoutcast/Icecast streams. If the stream provides metadata (e.g., artist and song title), it will appear here without any extra configuration.

Volume Changes
player.volumeStream.listen((VolumeInfo vol) {
  print('Volume: ${vol.volume}, Muted: ${vol.isMuted}');
});

Full Example

A complete player widget with play/pause, skip controls, metadata display, and volume slider:

import 'package:flutter/material.dart';
import 'package:flutter_radio_player/flutter_radio_player.dart';

class RadioPlayerWidget extends StatefulWidget {
  const RadioPlayerWidget({super.key});

  @override
  State<RadioPlayerWidget> createState() => _RadioPlayerWidgetState();
}

class _RadioPlayerWidgetState extends State<RadioPlayerWidget> {
  final _player = FlutterRadioPlayer();
  double _volume = 0.5;

  @override
  void initState() {
    super.initState();
    _player.initialize([
      const RadioSource(
        url: 'https://s2-webradio.antenne.de/chillout?icy=https',
        title: 'Antenne Chillout',
      ),
      const RadioSource(
        url: 'https://radio.lotustechnologieslk.net:2020/stream/sunfmgarden?icy=https',
        title: 'SunFM - Sri Lanka',
      ),
    ], playWhenReady: true);
  }

  @override
  void dispose() {
    _player.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        // Now playing info
        StreamBuilder<NowPlayingInfo>(
          stream: _player.nowPlayingStream,
          builder: (context, snapshot) {
            final title = snapshot.data?.title ?? 'No track info';
            return Text(title, style: Theme.of(context).textTheme.titleLarge);
          },
        ),
        const SizedBox(height: 24),

        // Transport controls
        StreamBuilder<bool>(
          stream: _player.isPlayingStream,
          builder: (context, snapshot) {
            final isPlaying = snapshot.data ?? false;
            return Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                IconButton(
                  iconSize: 36,
                  onPressed: _player.previousSource,
                  icon: const Icon(Icons.skip_previous_rounded),
                ),
                IconButton(
                  iconSize: 48,
                  onPressed: () => isPlaying ? _player.pause() : _player.play(),
                  icon: Icon(isPlaying ? Icons.pause_rounded : Icons.play_arrow_rounded),
                ),
                IconButton(
                  iconSize: 36,
                  onPressed: _player.nextSource,
                  icon: const Icon(Icons.skip_next_rounded),
                ),
              ],
            );
          },
        ),
        const SizedBox(height: 16),

        // Volume slider
        Row(
          children: [
            const Icon(Icons.volume_down_rounded),
            Expanded(
              child: Slider(
                value: _volume,
                onChanged: (value) {
                  setState(() => _volume = value);
                  _player.setVolume(value);
                },
              ),
            ),
            const Icon(Icons.volume_up_rounded),
          ],
        ),
      ],
    );
  }
}

See the example app for the full runnable project.

Platform Setup

Android

Add the following permissions to your 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" />

FOREGROUND_SERVICE and FOREGROUND_SERVICE_MEDIA_PLAYBACK are already declared by the plugin. INTERNET must be declared by the host app.

If your radio streams use plain HTTP (not HTTPS), opt in to cleartext traffic. Either add the attribute to your <application> tag:

<application
    android:usesCleartextTraffic="true"
    ...>

Or, preferred, whitelist only the streaming domains via a network security config (res/xml/network_security_config.xml):

<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">your-stream-host.example.com</domain>
    </domain-config>
</network-security-config>

Then reference it from your <application> tag: android:networkSecurityConfig="@xml/network_security_config".

iOS
  1. Enable Audio, AirPlay, and Picture in Picture under your target's Signing & Capabilities > Background Modes in Xcode:

Xcode Configuration

  1. If your radio streams use plain HTTP, add the following to your Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
  1. Swift Package Manager is supported alongside CocoaPods (Flutter 3.24+). No additional configuration is needed.

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
Model Fields
RadioSource url (String), title (String?), artwork (String?)
NowPlayingInfo title (String?)
VolumeInfo volume (double), isMuted (bool)

Architecture

This is a federated plugin split into four packages:

Package Description
flutter_radio_player App-facing API
flutter_radio_player_platform_interface Shared interface and models
flutter_radio_player_android Android implementation (Media3/ExoPlayer)
flutter_radio_player_ios iOS implementation (AVFoundation)

Platform communication uses Pigeon for type-safe code generation.

Migration from v3

See the Migration Guide for detailed upgrade instructions.

Support the Plugin

If you find this plugin useful:

  • Give it a star on GitHub
  • Leave a like on pub.dev
  • Buy me a coffee via USDT-TR20: TNuTkL1ZJGu2xntmtzHzSiH5YdVqUeAujr

Contributing

Contributions are welcome. Please open an issue first to discuss what you would like to change.

License

MIT

所屬分類

依賴

依賴清單 3 項

  • flutter_radio_player_android^4.1.0
  • flutter_radio_player_ios^4.1.0
  • flutter_radio_player_platform_interface^4.1.0

原始碼儲存庫

使用此套件的專案

暫無相關資料。