Skip to main content

flutter_media_session 3.1.0-pre.3 copy "flutter_media_session: ^3.1.0-pre.3" to clipboard
flutter_media_session: ^3.1.0-pre.3 copied to clipboard

Sync media metadata and playback state with system controls on Android, iOS, macOS, Windows, and Web.

Banner

flutter_media_session #

pub package pub points CI License: MIT Platform

A Flutter plugin that connects media playback to OS media hubs — Android notifications, iOS Lock Screen & Dynamic Island, macOS Control Center, Windows SMTC, and the Web Media Session API.

The plugin handles metadata and remote command routing only. It does not include an audio engine; you bring your own player (just_audio, media_kit, audioplayers, etc.) and wire it in via an adapter.

Platform Support #

Platform Minimum Version
Android Android Android 7.0 (API 24+)
Apple iOS iOS 12.0+
Apple macOS macOS 10.15+
Windows Windows Windows 10 1809+ (Build 17763+)
Web Modern Browsers
Linux Linux Planned (MPRIS)

For architecture and native backend details (Media3, MediaPlayer, SMTC), see the Architecture Guide.

Installation #

Run this command:

flutter pub add flutter_media_session

Or add flutter_media_session manually to your pubspec.yaml:

dependencies:
  flutter_media_session: ^3.1.0-pre.3

Platform Prerequisites #

iOS #

To keep media controls responsive and receive remote commands while your application is backgrounded, add UIBackgroundModes with audio to ios/Runner/Info.plist:

<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
</array>

Note: While the plugin configures AVAudioSession category to .playback upon activation, iOS background execution relies on the application actively playing audio through an audio session.

Android #

  • Permissions: Core permissions (FOREGROUND_SERVICE, FOREGROUND_SERVICE_MEDIA_PLAYBACK, FOREGROUND_SERVICE_CONNECTED_DEVICE, POST_NOTIFICATIONS, WAKE_LOCK, and ACCESS_WIFI_STATE) are declared in the plugin's AndroidManifest.xml and merged automatically by Gradle. (To strip unused casting permissions, see Opting Out of Permissions.)
  • Android 13+ (API 33+): Notification posting requires runtime permission. Calling FlutterMediaSession().activate() automatically requests notification permission on Android.
  • Custom Icons: Custom notification action drawables must exist in your application's android/app/src/main/res/drawable* folders.

Windows #

  • Packaged Apps (MSIX): When packaged via MSIX, Windows assigns the App User Model ID (AUMID) automatically from the manifest. No configuration required.
  • Unpackaged / Portable Apps: To display your application's name and icon instead of "Unknown Application" in the volume flyout, refer to the Windows Setup Guide.

macOS & Web #

No configuration required.

Quick Start #

Adapters handle the stream subscriptions and state mapping between your player and the media session. Ready-to-use adapters for just_audio and media_kit are available in the docs:

import 'package:flutter_media_session/flutter_media_session.dart';
import 'package:just_audio/just_audio.dart';
// Import your adapter implementation (see doc/adapters/just_audio.md)
import 'just_audio_media_session_adapter.dart';

final player = AudioPlayer();
final session = FlutterMediaSession();

// 1. Activate session (starts Android foreground service, binds SMTC / NowPlaying)
await session.activate();

// 2. Bind adapter to automatically synchronize metadata, playback states, and commands
session.bind(JustAudioMediaSessionAdapter(player));

Approach B: Direct API Usage #

You can also push metadata and playback states manually, and receive system actions via high-level callbacks or streams:

import 'package:flutter_media_session/flutter_media_session.dart';

final session = FlutterMediaSession();

// 1. Activate native session
await session.activate();

// 2. Update media metadata
await FlutterMediaSessionPlatform.instance.updateMetadata(
  const MediaMetadata(
    title: 'Song Title',
    artist: 'Artist Name',
    album: 'Album Title',
    artworkUri: 'https://example.com/cover.jpg',
    duration: Duration(minutes: 3, seconds: 30),
  ),
);

// 3. Update playback state
await FlutterMediaSessionPlatform.instance.updatePlaybackState(
  const PlaybackState(
    status: PlaybackStatus.playing,
    position: Duration(seconds: 45),
    speed: 1.0,
  ),
);

// 4. Handle incoming system media actions
session.setActionHandler(
  onPlay: () => myAudioPlayer.resume(),
  onPause: () => myAudioPlayer.pause(),
  onSeekTo: (position) => myAudioPlayer.seek(position),
  onSkipToNext: () => myPlaylist.next(),
  onSkipToPrevious: () => myPlaylist.previous(),
);

Documentation #

  • Usage Guide: Full API reference, writing custom adapters, configuring Android notification layouts (ActionSlotLayout), audio interruption handling, background keep-alive, and high-level callbacks.
  • Player Adapter Guides:
  • Windows Setup Guide: Resolving the "Unknown Application" display name issue via MSIX, Inno Setup, or dynamic runtime shortcut registration.
  • Architecture & Design Decisions: Platform internals, Android Media3 service lifecycles, iOS/macOS MediaPlayer integration, Windows SMTC thread dispatching, and Web MediaSession limits.
  • Release Guide: Verification steps, build checks, and publishing procedures.