Skip to content

Listen to Events

This guide covers how to subscribe to playback lifecycle events and remote control events.

CategoryNamespaceDescription
Player eventsaudioPlayerPlayback state, track changes, progress, errors
Remote eventsmediaSessionLock screen, Bluetooth, headphone controls
import {
onPlaybackStateChanged,
onPlaybackEnded,
onPlaybackProgress,
onPlaybackError,
} from '@ddgutierrezc/legato-capacitor';
// State changes
const unsubState = onPlaybackStateChanged(({ state }) => {
console.log('State:', state);
});
// Progress updates
const unsubProgress = onPlaybackProgress(({ position, duration, bufferedPosition }) => {
console.log(`Position: ${position.toFixed(1)}s / ${duration}s`);
});
// Playback ended
const unsubEnded = onPlaybackEnded(({ snapshot }) => {
console.log('Playback ended. Final state:', snapshot.state);
});
// Errors
const unsubError = onPlaybackError(({ error }) => {
console.error('Error:', error.code, error.message);
});
// Clean up
await unsubState.remove();
await unsubProgress.remove();
await unsubEnded.remove();
await unsubError.remove();
import { audioPlayer, mediaSession, LEGATO_EVENTS } from '@ddgutierrezc/legato-capacitor';
// Player events via audioPlayer
const playerHandle = await audioPlayer.addListener('playback-state-changed', (payload) => {
console.log('State:', payload.state);
});
// Remote events via mediaSession
const remoteHandle = await mediaSession.addListener('remote-play', () => {
console.log('User pressed play');
});
// Clean up via handle
await playerHandle.remove();
await remoteHandle.remove();
import { addLegatoListener, addAudioPlayerListener, addMediaSessionListener } from '@ddgutierrezc/legato-capacitor';
// Any Legato event
const handle1 = await addLegatoListener('playback-progress', (payload) => {
console.log('Progress:', payload.position);
});
// Player event only
const handle2 = await addAudioPlayerListener('playback-active-track-changed', (payload) => {
console.log('Track:', payload.track?.title);
});
// Media session only
const handle3 = await addMediaSessionListener('remote-seek', (payload) => {
console.log('Seek to:', payload.position);
});

Subscribe to system media control events:

import { onRemotePlay, onRemotePause, onRemoteNext, onRemotePrevious } from '@ddgutierrezc/legato-capacitor';
// Handle remote commands
onRemotePlay(() => {
audioPlayer.play();
});
onRemotePause(() => {
audioPlayer.pause();
});
onRemoteNext(() => {
audioPlayer.skipToNext();
});
onRemotePrevious(() => {
audioPlayer.skipToPrevious();
});
// Remove all player listeners
await audioPlayer.removeAllListeners();
// Remove all media session listeners
await mediaSession.removeAllListeners();
ActionResult
onPlaybackStateChanged(...)Listener fires on every state transition
onPlaybackProgress(...)Listener fires periodically during playback
onPlaybackError(...)Listener fires when playback encounters an error
onRemotePlay(...)Listener fires when user taps play on remote control
.remove()Listener is detached and stops firing
removeAllListeners()All listeners for the namespace are removed
  1. Always clean up — Remove listeners in component unmount handlers or when no longer needed
  2. Use handles — Store handles from addListener() for manual removal
  3. Check capabilitiesremote-seek only fires when runtime supports seek