Skip to content

@capawesome-team/capacitor-media-session

Capacitor plugin to interact with media controllers, volume keys and media buttons.

Features

We are proud to offer one of the most complete and feature-rich Capacitor plugins for media sessions. Here are some of the key features:

  • 🖥️ Cross-platform: Supports Android, iOS and Web.
  • 🎮 Media Controls: Handle hardware media keys, lock screen controls, and notification controls.
  • 🎵 Rich Metadata: Display song title, artist, album, and artwork on lock screen and notifications.
  • ▶️ Action Handlers: Support for play, pause, seek, next/previous track, and more.
  • 📍 Position State: Track and display playback position, duration, and playback rate.
  • 🔧 Native APIs: Uses MediaSession API on Android and MPNowPlayingInfoCenter on iOS for the best possible integration.
  • 🤝 Compatibility: Compatible with the Audio Player plugin.
  • 📦 SPM: Supports Swift Package Manager for iOS.
  • 🔁 Up-to-date: Always supports the latest Capacitor version.
  • ⭐️ Support: Priority support from the Capawesome Team.
  • Handcrafted: Built from the ground up with care and expertise, not forked or AI-generated.

Missing a feature? Just open an issue and we'll take a look!

Compatibility

Plugin Version Capacitor Version Status
7.x.x >=7.x.x Active support

Demo

Android iOS Web
Android Demo iOS Demo Web Demo

Installation

This plugin is only available to Capawesome Insiders. First, make sure you have the Capawesome npm registry set up. You can do this by running the following commands:

npm config set @capawesome-team:registry https://npm.registry.capawesome.io
npm config set //npm.registry.capawesome.io/:_authToken <YOUR_LICENSE_KEY>

Attention: Replace <YOUR_LICENSE_KEY> with the license key you received from Polar. If you don't have a license key yet, you can get one by becoming a Capawesome Insider.

Next, install the package:

npm install @capawesome-team/capacitor-media-session
npx cap sync

Android

Variables

If needed, you can define the following project variable in your app’s variables.gradle file to change the default version of the dependency:

  • $androidMediaVersion version of androidx.media:media (default: 1.7.1)

Usage

import { AudioPlayer } from '@capawesome-team/capacitor-audio-player';
import {
  MediaSession,
  MediaSessionAction,
  MediaSessionPlaybackState
} from '@capawesome-team/capacitor-media-session';

const setMetadata = async () => {
  await MediaSession.setMetadata({
    title: 'Test Song',
    artist: 'My Awesome Artist',
    album: 'My Awesome Album',
    artwork: [
      {
        src: 'https://example.com/cover-96x96.png',
        sizes: '96x96',
        type: 'image/png',
      },
      {
        src: 'https://example.com/cover-512x512.png',
        sizes: '512x512',
        type: 'image/png',
      },
    ],
  });
};

const registerActions = async () => {
  await MediaSession.registerActionHandler({
    action: MediaSessionAction.Play
  });
  await MediaSession.registerActionHandler({
    action: MediaSessionAction.Pause
  });
  await MediaSession.registerActionHandler({
    action: MediaSessionAction.SeekBackward
  });
  await MediaSession.registerActionHandler({
    action: MediaSessionAction.SeekForward
  });
  await MediaSession.registerActionHandler({
    action: MediaSessionAction.SeekTo
  });
  await MediaSession.registerActionHandler({
    action: MediaSessionAction.Stop
  });
};

const setPlaybackState = async () => {
  await MediaSession.setPlaybackState({
    playbackState: MediaSessionPlaybackState.Playing,
  });
};

const setPositionState = async () => {
  await MediaSession.setPositionState({
    duration: 180,
    playbackRate: 1.0,
    position: 30,
  });
};

const addActionListener = () => {
  MediaSession.addListener('action', async (event) => {
    switch (event.action) {
      case MediaSessionAction.Play:
        await AudioPlayer.resume();
        await MediaSession.setPlaybackState({
          playbackState: MediaSessionPlaybackState.Playing,
        });
        break;
      case MediaSessionAction.Pause:
        await AudioPlayer.pause();
        await MediaSession.setPlaybackState({
          playbackState: MediaSessionPlaybackState.Paused,
        });
        break;
      case MediaSessionAction.SeekBackward:
        const { position: currentPos } = await AudioPlayer.getCurrentPosition();
        const offsetMs = event.seekOffset ? event.seekOffset * 1000 : 10000;
        await AudioPlayer.seekTo({
          position: Math.max(0, currentPos - offsetMs)
        });
        break;
      case MediaSessionAction.SeekForward:
        const { position: pos } = await AudioPlayer.getCurrentPosition();
        const { duration } = await AudioPlayer.getDuration();
        const offset = event.seekOffset ? event.seekOffset * 1000 : 10000;
        await AudioPlayer.seekTo({
          position: Math.min(duration, pos + offset)
        });
        break;
      case MediaSessionAction.SeekTo:
        if (event.seekTime !== undefined) {
          await AudioPlayer.seekTo({
            position: event.seekTime * 1000
          });
        }
        break;
      case MediaSessionAction.Stop:
        await AudioPlayer.stop();
        await MediaSession.setPlaybackState({
          playbackState: MediaSessionPlaybackState.None,
        });
        break;
    }
  });
};

const removeActionListener = async () => {
  await MediaSession.unregisterActionHandler({
    action: MediaSessionAction.Play
  });
  await MediaSession.unregisterActionHandler({
    action: MediaSessionAction.Pause
  });
  await MediaSession.removeAllListeners();
};

API

registerActionHandler(...)

registerActionHandler(options: RegisterActionHandlerOptions) => Promise<void>

Register a handler for a media session action.

If the action handler is registered, the media session will respond to the action by calling the action event listener. If the action handler is not registered, the media session will not respond to the action.

Make sure to unregister the action handler when it is no longer needed.

Param Type
options RegisterActionHandlerOptions

Since: 0.0.1


setCameraActive(...)

setCameraActive(options: SetCameraActiveOptions) => Promise<void>

Set the camera active state.

Only available on Web.

Param Type
options SetCameraActiveOptions

Since: 0.0.1


setMetadata(...)

setMetadata(options: SetMetadataOptions) => Promise<void>

Set the metadata for the media session.

Param Type
options SetMetadataOptions

Since: 0.0.1


setMicrophoneActive(...)

setMicrophoneActive(options: SetMicrophoneActive) => Promise<void>

Set the microphone active state.

Only available on Web.

Param Type
options SetMicrophoneActive

Since: 0.0.1


setPlaybackState(...)

setPlaybackState(options: SetPlaybackStateOptions) => Promise<void>

Set the playback state.

Param Type
options SetPlaybackStateOptions

Since: 0.0.1


setPositionState(...)

setPositionState(options: SetPositionStateOptions) => Promise<void>

Set the position state.

Param Type
options SetPositionStateOptions

Since: 0.0.1


unregisterActionHandler(...)

unregisterActionHandler(options: UnregisterActionHandlerOptions) => Promise<void>

Unregister a handler for a media session action.

If the action handler is unregistered, the media session will no longer respond to the action and the action event listener will no longer be called for the specific action.

Param Type
options UnregisterActionHandlerOptions

Since: 0.0.1


addListener('action', ...)

addListener(eventName: 'action', listenerFunc: (event: ActionEvent) => void) => Promise<PluginListenerHandle>
Param Type
eventName 'action'
listenerFunc (event: ActionEvent) => void

Returns: Promise<PluginListenerHandle>

Since: 0.0.1


removeAllListeners()

removeAllListeners() => Promise<void>

Remove all listeners for this plugin.

Since: 0.0.1


Interfaces

RegisterActionHandlerOptions

Prop Type Description Since
action MediaSessionAction The action to handle. 0.0.1

SetCameraActiveOptions

Prop Type Description Since
active boolean Whether or not the camera is active. 0.0.1

SetMetadataOptions

Prop Type Description Since
album string 0.0.1
artist string 0.0.1
artwork MediaMetadataArtwork[] Only available on iOS and Web. 0.0.1
title string 0.0.1

MediaMetadataArtwork

Prop Type Description Since
sizes string The size of the artwork. 0.0.1
src string The URL from which the user agent fetches the image's data. 0.0.1
type string The MIME type hint for the user agent. 0.0.1

SetMicrophoneActive

Prop Type Description Since
active boolean Whether or not the microphone is active. 0.0.1

SetPlaybackStateOptions

Prop Type Description Since
playbackState MediaSessionPlaybackState The playback state to set. 0.0.1

SetPositionStateOptions

Prop Type Description Since
duration number The duration of the media in seconds. 0.0.1
playbackRate number The playback rate of the media. 0.0.1
position number The current position of the media in seconds. 0.0.1

UnregisterActionHandlerOptions

Prop Type Description Since
action MediaSessionAction The action to unregister. 0.0.1

PluginListenerHandle

Prop Type
remove () => Promise<void>

ActionEvent

Prop Type Description Since
action MediaSessionAction The action that was handled. 0.0.1
fastSeek boolean Whether or not the action was a fast seek. 0.0.1
seekOffset number The offset in seconds to seek to. 0.0.1
seekTime number The time in seconds to seek to. 0.0.1

Enums

MediaSessionAction

Members Value Description Since
Play 'PLAY' 0.0.1
Pause 'PAUSE' 0.0.1
SeekBackward 'SEEK_BACKWARD' 0.0.1
SeekForward 'SEEK_FORWARD' 0.0.1
PreviousTrack 'PREVIOUS_TRACK' 0.0.1
NextTrack 'NEXT_TRACK' 0.0.1
SkipAd 'SKIP_AD' Only available on Web. 0.0.1
Stop 'STOP' 0.0.1
SeekTo 'SEEK_TO' 0.0.1
ToggleMicrophone 'TOGGLE_MICROPHONE' Only available on Web. 0.0.1
ToggleCamera 'TOGGLE_CAMERA' Only available on Web. 0.0.1
ToggleScreenShare 'TOGGLE_SCREEN_SHARE' Only available on Web. 0.0.1
HangUp 'HANG_UP' Only available on Web. 0.0.1
PreviousSlide 'PREVIOUS_SLIDE' Only available on Web. 0.0.1
NextSlide 'NEXT_SLIDE' Only available on Web. 0.0.1
EnterPictureInPicture 'ENTER_PICTURE_IN_PICTURE' Only available on Web. 0.0.1
VoiceActivity 'VOICE_ACTIVITY' Only available on Web. 0.0.1

MediaSessionPlaybackState

Members Value Since
None 'NONE' 0.0.1
Paused 'PAUSED' 0.0.1
Playing 'PLAYING' 0.0.1

Changelog

See CHANGELOG.md.

Breaking Changes

See BREAKING.md.

License

See LICENSE.