패키지, 저장소 및 앱 카테고리 검색

패키지 상세v4.1.0

flutter_radio_player

Flutter용 온라인 라디오 플레이어로 백그라운드 재생, 잠금 화면 컨트롤 및 안드로이드와 iOS의 스트리밍 지원을 제공합니다.

AndroidiOS
30일 다운로드
109
좋아요
137
Pub 점수
160

패키지 설치

flutter pub add flutter_radio_player

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

Flutter Radio Player는 Android 및 iOS에서 백그라운드 재생과 잠금 화면 컨트롤을 지원하는 Flutter 패키지입니다. 개발자가 앱에 온라인 라디오 스트리밍 기능을 통합할 수 있도록 설계되었으며, 사용자가 인터넷 라디오 방송국을 중단 없이 들을 수 있도록 합니다. 이 패키지는 재생 관리, 메타데이터 표시, 미디어 세션 통합을 위한 깔끔한 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

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.