capacitor-plugin-playlist

July 27, 2026 · View on GitHub

Capacitor plugin for Android, iOS, and Web with native audio playlist playback, background support, lock-screen / notification controls, and video handoff.

Requires Capacitor 8+ (peer dependency @capacitor/core >= 8.0.0).

Index

  1. Features
  2. Background
  3. Notes
  4. Installation
  5. Usage
  6. Events
  7. Video handoff
  8. API
  9. Migrating from cordova-plugin-playlist
  10. Changes
  11. Credits
  12. License

Features

Playlist management

  • setPlaylistItems — replace entire playlist (optional position retention)
  • addItem / addAllItems — append tracks; addItem accepts optional insert index (“play next”)
  • moveItem — reorder without disrupting current playback
  • replaceItem — swap track metadata/URL in place (e.g. stream → offline file)
  • removeItem / removeItems / clearAllItems — remove tracks
  • getPlaylist — snapshot of current items
  • setLoop — loop entire playlist when the last track completes

Playback controls

  • play / pause
  • skipForward / skipBack
  • seekTo (seconds)
  • playTrackByIndex / playTrackById — jump and play
  • selectTrackByIndex / selectTrackById — select without playing
  • setPlaybackVolume (0–1)
  • setPlaybackRate (0 pauses, 1 = normal speed)

Native platform integration

PlatformEngineOS controls
AndroidExoMedia + PlaylistCoreMediaStyle notification, MediaSession, foreground mediaPlayback service
iOSCustom AVBidirectionalQueuePlayerLock screen + Control Center via MPNowPlayingInfoCenter / MPRemoteCommandCenter
WebHTMLAudioElement + optional HLS.jsBrowser media controls only

Background audio

  • Android: foreground media service with WAKE_LOCK, FOREGROUND_SERVICE, and FOREGROUND_SERVICE_MEDIA_PLAYBACK (Android 14+)
  • iOS: UIBackgroundModesaudio
  • Position events throttled while WebView is backgrounded; one live snapshot emitted on foreground resume (0.9.1+)

Tracks and sources

  • Remote URLs, local files (file:// or app-resolved paths), and streams
  • Set isStream: true on streaming URLs so pause/resume buffering behaves correctly
  • albumArt shown in notification / lock screen (Glide on Android)
  • No built-in download manager — resolve offline paths in your app and pass them as assetUrl

Status event stream

Single status listener with RmxAudioStatusMessage events (see Events).

Video handoff

When switching from background audio to native fullscreen video:

  • prepareForVideoHandoff() — release audio focus / session
  • getLastKnownPosition() — saved head position (seconds)
  • resumeAfterVideoHandoff({ position, prewarm? }) — re-arm audio after video

See Video handoff.

Cordova-compatible wrapper

RmxAudioPlayer (src/RmxAudioPlayer.ts) is a drop-in replacement for cordova-plugin-playlist with on('status') / off('status') and state getters (isPlaying, currentTrack, etc.).

Not exposed on RmxAudioPlayer: getPlaylist, video handoff methods — call Playlist directly for those.

Not supported

  • Shuffle
  • Audio ads / IMA integration (#71)
  • Mixable / low-latency game audio (use cordova-plugin-nativeaudio instead)
  • Simultaneous audio mixing (lock-screen controls require exclusive audio focus)

Background

Forked from cordova-plugin-playlist for Capacitor.

Notes

Android

Uses ExoMedia (ExoPlayer wrapper) with PlaylistCore for notification and MediaSession integration.

iOS

Uses a customized AVQueuePlayer (AVBidirectionalQueuePlayer) for track-change feedback and continuous audio session between songs. Minimum iOS 18 (0.9.4+). Swift Package Manager supported (0.10.0+).

Installation

npm i capacitor-plugin-playlist
npx cap sync

Web

Include HLS.js in your build for HLS streams.

Angular example

npm i hls.js

Add to angular.json → architect → build → options → scripts:

"scripts": [
  {
    "input": "node_modules/hls.js/dist/hls.min.js"
  }
]

Android

AndroidManifest.xml

From 0.11.0, the plugin library manifest merges the media playback service and required permissions into your app automatically:

  • android.permission.WAKE_LOCK
  • android.permission.FOREGROUND_SERVICE
  • android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK
  • org.dwbn.plugins.playlist.service.MediaService (exported="false", foregroundServiceType="mediaPlayback")

After upgrading, run npx cap sync android. You do not need to copy these entries into your host AndroidManifest.xml unless you want to override plugin defaults.

Keep your application's existing Android Application class. The legacy org.dwbn.plugins.playlist.App class remains available for compatibility, but it is no longer required — remove android:name="org.dwbn.plugins.playlist.App" from <application> when upgrading from older setups.

Gradle 9+

Ensure the Kotlin plugin is declared in your root android/build.gradle (this plugin no longer ships its own buildscript block):

buildscript {
    ext.kotlin_version = '2.3.0'
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.13.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
ext {
    kotlin_version = '2.3.0'
}

Glide (notification album art)

Create MyAppGlideModule.java:

package org.your.package.namespace;

import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

See https://guides.codepath.com/android/Displaying-Images-with-the-Glide-Library

Notification icon

Create a transparent silhouette icon (e.g. ic_notification.png) and pass it via setOptions:

await Playlist.setOptions({
  verbose: !environment.production,
  options: { icon: 'ic_notification' },
});

In Android Studio: right-click res → New → Image Asset → Notification Icons.

iOS

Add to Info.plist:

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

Without audio background mode, iOS stops playback when the app backgrounds.

Usage

See also examples/audio-provider.ts for an Angular/Ionic integration.

Basic flow (Playlist API)

import { Playlist, AudioTrack, RmxAudioStatusMessage } from 'capacitor-plugin-playlist';

await Playlist.setOptions({
  verbose: true,
  resetStreamOnPause: true,
  options: { icon: 'ic_notification' },
});

await Playlist.initialize();

const handle = await Playlist.addListener('status', ({ status }) => {
  if (status.msgType === RmxAudioStatusMessage.RMXSTATUS_PLAYBACK_POSITION) {
    // update UI progress
  }
});

const track: AudioTrack = {
  trackId: 'track-1',
  assetUrl: 'https://example.com/audio.mp3',
  title: 'Track title',
  artist: 'Artist name',
  album: 'Album name',
  albumArt: 'https://example.com/cover.jpg',
  isStream: false,
};

await Playlist.setPlaylistItems({
  items: [track],
  options: { startPaused: false },
});

await Playlist.play();
// later: handle.remove();

RmxAudioPlayer wrapper (Cordova migration)

import { RmxAudioPlayer, AudioTrack } from 'capacitor-plugin-playlist';

const player = new RmxAudioPlayer();
await player.initialize();

player.on('status', (data) => {
  console.log('status', data.msgType, data);
});

await player.setLoop(true);
await player.setPlaylistItems([track], { retainPosition: true, playFromId: track.trackId });
await player.play();

Events

Subscribe via Playlist.addListener('status', …) or RmxAudioPlayer.on('status', …).

Each callback receives { action: 'status', status: OnStatusCallbackData } where:

  • status.trackId — current track id, "NONE" when idle, "INVALID" when playlist completed
  • status.msgTypeRmxAudioStatusMessage enum value
  • status.value — payload (shape depends on msgType)
msgTypeNameWhenPayload
5ERRORPlayback or network failureOnStatusErrorCallbackData (code, message)
10LOADINGTrack loading startedOnStatusCallbackUpdateData
11CANPLAYTrack ready to playOnStatusCallbackUpdateData
15LOADEDTrack fully loadedOnStatusCallbackUpdateData
20STALLEDiOS: network stallOnStatusCallbackUpdateData
25BUFFERINGBuffer progress updateOnStatusCallbackUpdateData
30PLAYINGPlayback started/resumedOnStatusCallbackUpdateData
35PAUSEPlayback pausedOnStatusCallbackUpdateData
40PLAYBACK_POSITIONPeriodic position tickOnStatusCallbackUpdateData (suppressed while WebView backgrounded)
45SEEKUser or app seekedOnStatusCallbackUpdateData
50COMPLETEDCurrent track finishedOnStatusCallbackUpdateData
55DURATIONDuration first knownOnStatusCallbackUpdateData
60STOPPEDAll playback stoppedOnStatusCallbackUpdateData
90SKIP_FORWARDSkipped to next trackOnStatusCallbackUpdateData
95SKIP_BACKSkipped to previous trackOnStatusCallbackUpdateData
100TRACK_CHANGEDActive track changedOnStatusTrackChangedData
105PLAYLIST_COMPLETEDEntire playlist finishedOnStatusCallbackUpdateData
110ITEM_ADDEDTrack addedOnStatusCallbackUpdateData
115ITEM_REMOVEDTrack removedOnStatusCallbackUpdateData
120PLAYLIST_CLEAREDAll tracks removedOnStatusCallbackUpdateData

For track changes, prefer handling TRACK_CHANGED over SKIP_FORWARD / SKIP_BACK.

Video handoff

Native audio and native fullscreen video cannot share audio focus. These three methods coordinate a clean handoff when the user opens video while audio was playing (or when switching back to audio after video).

Works with any native Capacitor video plugin (or other player) that needs exclusive audio focus.

Methods

MethodPurpose
prepareForVideoHandoff()Pause audio, capture head position, release audio focus / session
getLastKnownPosition()Read captured position (seconds) after prepare
resumeAfterVideoHandoff({ position, prewarm? })Re-arm audio after video, or prewarm Android FGS before video

Call these on the Playlist plugin directly — they are not exposed on RmxAudioPlayer.

Lifecycle

sequenceDiagram
    participant App
    participant Playlist
    participant VideoPlayer

    Note over App,VideoPlayer: Entering video
    App->>Playlist: prepareForVideoHandoff()
    Playlist-->>App: audio paused, focus released
    App->>Playlist: getLastKnownPosition() optional
    App->>Playlist: resumeAfterVideoHandoff position prewarm true
    Note over Playlist: Android only silent FGS prewarm
    App->>VideoPlayer: initPlayer
    VideoPlayer-->>App: video playing

    Note over App,VideoPlayer: Exiting video
    App->>Playlist: resumeAfterVideoHandoff position
    Note over Playlist: re-arm session no prewarm
    App->>Playlist: play optional
    Playlist-->>App: audio resumes

Basic sequence

import { Playlist } from 'capacitor-plugin-playlist';

// --- Entering native video ---
await Playlist.prepareForVideoHandoff();
const { position: audioPosition } = await Playlist.getLastKnownPosition();

await nativeVideoPlayer.init({ /* url, fullscreen, … */ });

// --- Exiting native video (use video head, not audioPosition) ---
const videoPosition = 120; // from your video player's position events
await Playlist.resumeAfterVideoHandoff({ position: videoPosition });
await Playlist.play(); // if user should resume audible playback

On Android 14+ (especially Android 17), starting or re-promoting the media foreground service from the background can fail or mute playback. Prewarm while the app is still visible before video starts:

// 1. Release audio focus
await Playlist.prepareForVideoHandoff();

// 2. Prewarm FGS silently at the video start position (Android)
await Playlist.resumeAfterVideoHandoff({
  position: Math.floor(videoStartSec),
  prewarm: true,
});

// 3. Start native video
await nativeVideoPlayer.init({ /* … */ });

// … user watches video; track video position via player events …

// 4. After video closes — re-arm without prewarm
await Playlist.resumeAfterVideoHandoff({ position: Math.floor(videoExitSec) });
await Playlist.play(); // when ready

What prewarm: true does on Android:

  • Promotes MediaService to foreground (mediaPlayback FGS) while the app is foregrounded
  • Prepares the playlist item at position but stays silent — no audio focus request, no audible playback
  • Prevents video sound from dropping when audio would otherwise re-request focus
  • During prewarm, Playlist.play() is a no-op for audible playback (only keeps FGS notification updated)

iOS: prewarm is accepted but ignored. Use prepareForVideoHandoff() → video → resumeAfterVideoHandoff({ position })play().

Web: Both methods are stubs (pause + store position). No native session handoff.

Platform behaviour

StepAndroidiOSWeb
prepareForVideoHandoffPause, abandon audio focus, store position via MediaProgressPause, store track time, AVAudioSession.setActive(false)Pause HTMLAudioElement, store currentTime
getLastKnownPositionReturns stored handoff position (seconds)SameSame
resumeAfterVideoHandoff (no prewarm)Re-request focus; in-place resume if FGS still foreground from prewarm, else beginPlaybackReactivate audio session; reset track-id guard for PLAYING eventsStore position only
resumeAfterVideoHandoff (prewarm)Silent FGS + prepare at position, no focus/playNo-opN/A
After resumeCall play() to start audible playbackCall play() to start audible playbackCall play() on web player

Position: audio vs video head

  • getLastKnownPosition() after prepareForVideoHandoff — last audio head before video opened. Useful if video never started or for debugging.
  • On video exit — pass the video playback position (from your video player's position events), not the stale audio position, so audio resumes where the user left off in the video timeline.
  • Track video head while video plays and persist it if the app may cold-start (e.g. after PiP dismiss on Android).

Integration checklist

  1. Call prepareForVideoHandoff() immediately before your native video player starts — never after.
  2. On Android, call resumeAfterVideoHandoff({ position, prewarm: true }) after prepare and before video init, while the WebView is still foregrounded.
  3. On video exit, call resumeAfterVideoHandoff({ position }) without prewarm, then play() if playback should resume.
  4. resumeAfterVideoHandoff must complete before seekTo() / play() on the audio side.
  5. Do not call Playlist.release() between prepare and resume unless you intend to tear down the native player entirely.
  6. Idempotent exit handling: guard against duplicate resumeAfterVideoHandoff calls from concurrent native exit events (merge to a single call with max(position)).

Common pitfalls

SymptomLikely cause
Video has no sound shortly after startAudio re-requested focus after prepare; use Android prewarm: true before video starts
Audio silent after long video sessionFGS stopped while backgrounded; prewarm before video + in-place resume on exit (0.8.10+)
JS stuck in PAUSED after video (iOS, index > 0)Missing play() after resume, or PLAYING event suppressed — fixed in 0.8.11
PLAYBACK_POSITION flood after backgroundExpected — position events suppressed while WebView backgrounded (0.9.1+)

See CHANGELOG.md for version-specific fixes (0.8.8–0.10.3).

API

addListener('status', ...)

addListener(eventName: 'status', listenerFunc: PlaylistStatusChangeCallback) => Promise<PluginListenerHandle>

Subscribe to native playback status events (track changes, position, errors, etc.).

ParamTypeDescription
eventName'status'Must be 'status'.
listenerFuncPlaylistStatusChangeCallbackCallback receiving { action, status } where status.msgType is a RmxAudioStatusMessage.

Returns: Promise<PluginListenerHandle>


setOptions(...)

setOptions(options: AudioPlayerOptions) => Promise<void>

Configure plugin behaviour (verbose logging, stream pause handling, notification icon). Can be called at any time; not required before playback.

ParamType
optionsAudioPlayerOptions

initialize()

initialize() => Promise<void>

Initialise the native player, register status callbacks, and arm lock-screen / notification controls. Call once before playback (e.g. on app start).


release()

release() => Promise<void>

Tear down native resources (audio session, media service, observers). Call when the app no longer needs background audio (e.g. on logout).


setPlaylistItems(...)

setPlaylistItems(options: PlaylistOptions) => Promise<void>

Replace the entire playlist. Clears all previous items. Use options.retainPosition to keep the current track and playback position.

ParamType
optionsPlaylistOptions

addItem(...)

addItem(options: AddItemOptions) => Promise<void>

Append a single track to the end of the playlist, or insert at a 0-based index. When index is omitted the track is appended. Insertion does not interrupt playback of the current track.

ParamType
optionsAddItemOptions

moveItem(...)

moveItem(options: MoveItemOptions) => Promise<void>

Move a track from one index to another without restarting the current track.

ParamType
optionsMoveItemOptions

replaceItem(...)

replaceItem(options: ReplaceItemOptions) => Promise<void>

Replace a track's metadata and source URL in place (e.g. stream URL → local file). When replacing the currently playing track, playback position and play/pause state are preserved.

ParamType
optionsReplaceItemOptions

addAllItems(...)

addAllItems(options: AddAllItemOptions) => Promise<void>

Append multiple tracks to the end of the playlist. Raises one RMXSTATUS_ITEM_ADDED event per track.

ParamType
optionsAddAllItemOptions

removeItem(...)

removeItem(options: RemoveItemOptions) => Promise<void>

Remove a track by index (preferred) or id. If the removed track is currently playing, the next track starts automatically.

ParamType
optionsRemoveItemOptions

removeItems(...)

removeItems(options: RemoveItemsOptions) => Promise<void>

Remove multiple tracks in a single batch. If the currently playing track is removed, the next available track starts automatically.

ParamType
optionsRemoveItemsOptions

clearAllItems()

clearAllItems() => Promise<void>

Remove all tracks from the playlist. Raises RMXSTATUS_PLAYLIST_CLEARED and RMXSTATUS_STOPPED.


getPlaylist()

getPlaylist() => Promise<GetPlaylistResult>

Return a snapshot of the current playlist items.

Returns: Promise<GetPlaylistResult>


play()

play() => Promise<void>

Start or resume playback of the current track. No-op if the playlist is empty.


pause()

pause() => Promise<void>

Pause playback of the current track.


skipForward()

skipForward() => Promise<void>

Skip to the next track. At the end of the playlist, wraps to the beginning when loop is enabled.


skipBack()

skipBack() => Promise<void>

Skip to the previous track. No-op when already at the first track.


seekTo(...)

seekTo(options: SeekToOptions) => Promise<void>

Seek to a position (seconds) in the currently playing track. If the position exceeds track length, playback advances to the next track.

ParamType
optionsSeekToOptions

playTrackByIndex(...)

playTrackByIndex(options: PlayByIndexOptions) => Promise<void>

Jump to the track at the given 0-based index and start playback.

ParamType
optionsPlayByIndexOptions

playTrackById(...)

playTrackById(options: PlayByIdOptions) => Promise<void>

Jump to the track with the given id and start playback.

ParamType
optionsPlayByIdOptions

selectTrackByIndex(...)

selectTrackByIndex(options: SelectByIndexOptions) => Promise<void>

Select the track at the given index without necessarily starting playback.

ParamType
optionsSelectByIndexOptions

selectTrackById(...)

selectTrackById(options: SelectByIdOptions) => Promise<void>

Select the track with the given id without necessarily starting playback.

ParamType
optionsSelectByIdOptions

setPlaybackVolume(...)

setPlaybackVolume(options: SetPlaybackVolumeOptions) => Promise<void>

Set media stream volume. Float in range [0, 1]. Hardware volume controls still apply on top of this value.

ParamType
optionsSetPlaybackVolumeOptions

setLoop(...)

setLoop(options: SetLoopOptions) => Promise<void>

When true, the playlist loops back to the first track after the last track completes.

ParamType
optionsSetLoopOptions

setPlaybackRate(...)

setPlaybackRate(options: SetPlaybackRateOptions) => Promise<void>

Set playback speed. Float value; 0 pauses, 1 is normal speed.

ParamType
optionsSetPlaybackRateOptions

prepareForVideoHandoff()

prepareForVideoHandoff() => Promise<void>

Release native audio session / focus so a video player can own playback.

Android: pauses current track, abandons audio focus, stores head position. Does not stop the foreground media service. iOS: pauses, captures head position, deactivates AVAudioSession with notifyOthersOnDeactivation. Web: pauses HTMLAudioElement and stores currentTime.

Call immediately before native video starts (e.g. your video plugin's init method).


resumeAfterVideoHandoff(...)

resumeAfterVideoHandoff(options: ResumeAfterVideoHandoffOptions) => Promise<ResumeAfterVideoHandoffResult>

Re-arm native audio after video ends or, on Android, prewarm the media service before video starts.

Without prewarm (typical exit path):

  • Android: when play is true (default), re-acquires focus and resumes at position. When resumed is true, JS should skip redundant seekTo/play. When play is false, clears handoff retain and returns { resumed: false } so JS can seek without playing.
  • iOS: restores pinned track, reactivates AVAudioSession, seeks to position, and when play is true starts playback (seek-then-play). Returns { resumed: true } when native handled the handoff.
  • Web: stores position only (no native session); returns { resumed: false }.

With prewarm: true (Android, before video): starts MediaService in foreground at position but stays silent — no audio focus, no audible playback. Always returns { resumed: false }.

ParamType
optionsResumeAfterVideoHandoffOptions

Returns: Promise<ResumeAfterVideoHandoffResult>


getLastKnownPosition()

getLastKnownPosition() => Promise<GetLastKnownPositionResult>

Return the audio head position (seconds) captured during the most recent prepareForVideoHandoff or passed to resumeAfterVideoHandoff.

Returns: Promise<GetLastKnownPositionResult>


Interfaces

PluginListenerHandle

PropType
remove() => Promise<void>

PlaylistStatusChangeCallbackArg

PropType
actionstring
statusOnStatusCallbackData

OnStatusCallbackData

Encapsulates the data received by an onStatus callback

PropTypeDescription
trackIdstringThe ID of this track. If the track is null or has completed, this value is "NONE" If the playlist is completed, this value is "INVALID"
msgTypeRmxAudioStatusMessageThe type of status update
valueOnStatusCallbackUpdateData | OnStatusTrackChangedData | OnStatusErrorCallbackDataThe status payload. For all updates except ERROR, the data package is described by OnStatusCallbackUpdateData. For Errors, the data is shaped as OnStatusErrorCallbackData

OnStatusCallbackUpdateData

Contains the current track status as of the moment an onStatus update event is emitted.

PropTypeDescription
trackIdstringThe ID of this track corresponding to this event. If the track is null or has completed, this value is "NONE". This will happen when skipping to the beginning or end of the playlist. If the playlist is completed, this value is "INVALID"
isStreambooleanBoolean indicating whether this is a streaming track.
currentIndexnumberThe current index of the track in the playlist.
status'error' | 'unknown' | 'ready' | 'playing' | 'loading' | 'paused'The current status of the track, as a string. This is used to summarize the various event states that a track can be in; e.g. "playing" is true for any number of track statuses. The Javascript interface takes care of this for you; this field is here only for reference.
currentPositionnumberCurrent playback position of the reported track.
durationnumberThe known duration of the reported track. For streams or malformed MP3's, this value will be 0.
playbackPercentnumberProgress of track playback, as a percent, in the range 0 - 100
bufferPercentnumberBuffering progress of the track, as a percent, in the range 0 - 100
bufferStartnumberThe starting position of the buffering progress. For now, this is always reported as 0.
bufferEndnumberThe maximum position, in seconds, of the track buffer. For now, only the buffer with the maximum playback position is reported, even if there are other segments (due to seeking, for example). Practically speaking you don't need to worry about that, as in both implementations the minor gaps are automatically filled in by the underlying players.

OnStatusTrackChangedData

Reports information about the playlist state when a track changes. Includes the new track, its index, and the state of the playlist.

PropTypeDescription
currentItemAudioTrackThe new track that has been selected. May be null if you are at the end of the playlist, or the playlist has been emptied.
currentIndexnumberThe 0-based index of the new track. If the playlist has ended or been cleared, this will be -1.
isAtEndbooleanIndicates whether the playlist is now currently at the last item in the list.
isAtBeginningbooleanIndicates whether the playlist is now at the first item in the list
hasNextbooleanIndicates if there are additional playlist items after the current item.
hasPreviousbooleanIndicates if there are any items before this one in the playlist.

AudioTrack

An audio track for playback by the playlist.

PropTypeDescription
isStreambooleanThis item is a streaming asset. Make sure this is set to true for stream URLs, otherwise you will get odd behavior when the asset is paused.
trackIdstringtrackId is optional and if not passed in, an auto-generated UUID will be used.
assetUrlstringURL of the asset; can be local, a URL, or a streaming URL. If the asset is a stream, make sure that isStream is set to true, otherwise the plugin can't properly handle the item's buffer.
albumArtstringThe local or remote URL to an image asset to be shown for this track. If this is null, the plugin's default image is used.
artiststringThe track's artist
albumstringAlbum the track belongs to
titlestringTitle of the track

OnStatusErrorCallbackData

Represents an error reported by the onStatus callback.

PropTypeDescription
codeRmxAudioErrorTypeError code
messagestringThe error, as a message

AudioPlayerOptions

Options governing the overall behavior of the audio player plugin

PropTypeDescription
verbosebooleanShould the plugin's javascript dump the status message stream to the javascript console?
resetStreamOnPausebooleanIf true, when pausing a live stream, play will continue from the LIVE POSITION (e.g. the stream jumps forward to the current point in time, rather than picking up where it left off when you paused). If false, the stream will continue where you paused. The drawback of doing this is that when the audio buffer fills, it will jump forward to the current point in time, cause a disjoint in playback. Default is true.
optionsNotificationOptionsFurther options for notifications

NotificationOptions

PropType
iconstring

PlaylistOptions

PropType
itemsArray<AudioTrack>
optionsPlaylistItemOptions

Array

PropTypeDescription
lengthnumberGets or sets the length of the array. This is a number one higher than the highest index in the array.
MethodSignatureDescription
toString() => stringReturns a string representation of an array.
toLocaleString() => stringReturns a string representation of an array. The elements are converted to string using their toLocalString methods.
pop() => T | undefinedRemoves the last element from an array and returns it. If the array is empty, undefined is returned and the array is not modified.
push(...items: T[]) => numberAppends new elements to the end of an array, and returns the new length of the array.
concat(...items: ConcatArray<T>[]) => T[]Combines two or more arrays. This method returns a new array without modifying any existing arrays.
concat(...items: (T | ConcatArray<T>)[]) => T[]Combines two or more arrays. This method returns a new array without modifying any existing arrays.
join(separator?: string | undefined) => stringAdds all the elements of an array into a string, separated by the specified separator string.
reverse() => T[]Reverses the elements in an array in place. This method mutates the array and returns a reference to the same array.
shift() => T | undefinedRemoves the first element from an array and returns it. If the array is empty, undefined is returned and the array is not modified.
slice(start?: number | undefined, end?: number | undefined) => T[]Returns a copy of a section of an array. For both start and end, a negative index can be used to indicate an offset from the end of the array. For example, -2 refers to the second to last element of the array.
sort(compareFn?: ((a: T, b: T) => number) | undefined) => thisSorts an array in place. This method mutates the array and returns a reference to the same array.
splice(start: number, deleteCount?: number | undefined) => T[]Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
splice(start: number, deleteCount: number, ...items: T[]) => T[]Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
unshift(...items: T[]) => numberInserts new elements at the start of an array, and returns the new length of the array.
indexOf(searchElement: T, fromIndex?: number | undefined) => numberReturns the index of the first occurrence of a value in an array, or -1 if it is not present.
lastIndexOf(searchElement: T, fromIndex?: number | undefined) => numberReturns the index of the last occurrence of a specified value in an array, or -1 if it is not present.
every<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any) => this is S[]Determines whether all the members of an array satisfy the specified test.
every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any) => booleanDetermines whether all the members of an array satisfy the specified test.
some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any) => booleanDetermines whether the specified callback function returns true for any element of an array.
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any) => voidPerforms the specified action for each element in an array.
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[]Calls a defined callback function on each element of an array, and returns an array that contains the results.
filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any) => S[]Returns the elements of an array that meet the condition specified in a callback function.
filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any) => T[]Returns the elements of an array that meet the condition specified in a callback function.
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T) => TCalls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T) => T
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U) => UCalls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T) => TCalls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T) => T
reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U) => UCalls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.

ConcatArray

PropType
lengthnumber
MethodSignature
join(separator?: string | undefined) => string
slice(start?: number | undefined, end?: number | undefined) => T[]

PlaylistItemOptions

Options governing how the items are managed when using setPlaylistItems to update the playlist. This is typically useful if you are retaining items that were in the previous list.

PropTypeDescription
retainPositionbooleanIf true, the plugin will continue playback from the current playback position after setting the items to the playlist.
playFromPositionnumberIf retainPosition is true, this value will tell the plugin the exact time to start from, rather than letting the plugin decide based on current playback.
playFromIdstringIf retainPosition is true, this value will tell the plugin the uid of the "current" item to start from, rather than letting the plugin decide based on current playback.
startPausedbooleanIf playback should immediately begin when calling setPlaylistItems on the plugin. Default is false;

AddItemOptions

PropTypeDescription
itemAudioTrack
indexnumber0-based index to insert at. Omit to append.

MoveItemOptions

PropTypeDescription
fromnumberSource index (0-based).
tonumberDestination index (0-based) after removal.

ReplaceItemOptions

PropTypeDescription
itemAudioTrackReplacement track data. When trackId is omitted the existing id is kept.
indexnumberIndex of the track to replace (preferred over id).
idstringId of the track to replace.

AddAllItemOptions

PropType
itemsArray<AudioTrack>

RemoveItemOptions

PropType
idstring
indexnumber

RemoveItemsOptions

PropType
itemsArray<RemoveItemOptions>

GetPlaylistResult

PropType
itemsArray<AudioTrack>

SeekToOptions

PropType
positionnumber

PlayByIndexOptions

PropType
indexnumber
positionnumber

PlayByIdOptions

PropType
idstring
positionnumber

SelectByIndexOptions

PropType
indexnumber
positionnumber

SelectByIdOptions

PropType
idstring
positionnumber

SetPlaybackVolumeOptions

PropType
volumenumber

SetLoopOptions

PropType
loopboolean

SetPlaybackRateOptions

PropType
ratenumber

ResumeAfterVideoHandoffResult

PropTypeDescription
resumedbooleantrue when native already handled seek (and play when requested) in place. When true, JS should skip redundant seekTo / play to avoid a stutter. false on web, prewarm, paused Android handoff, and Android last-resort beginPlayback.

ResumeAfterVideoHandoffOptions

PropTypeDescription
positionnumberResume position in seconds (video exit head or saved audio position).
prewarmbooleanAndroid only. When true, promote MediaService to foreground and prepare at position without requesting audio focus or playing audio. Use immediately after prepareForVideoHandoff and before native video starts, while the app is still foregrounded. Ignored on iOS (no-op). Not applicable on web.
playbooleanWhen true, native starts audible playback after seeking to position. When false (paused video exit), native must not start playback. iOS defaults to false when omitted; Android defaults to true for legacy callers.

GetLastKnownPositionResult

PropType
positionnumber

Type Aliases

PlaylistStatusChangeCallback

(data: PlaylistStatusChangeCallbackArg): void

Enums

RmxAudioStatusMessage

MembersValueDescription
RMXSTATUS_NONE0The starting state of the plugin. You will never see this value; it changes before the callbacks are even registered to report changes to this value.
RMXSTATUS_REGISTER1Raised when the plugin registers the callback handler for onStatus callbacks. You will probably not be able to see this (nor do you need to).
RMXSTATUS_INIT2Reserved for future use
RMXSTATUS_ERROR5Indicates an error is reported in the 'value' field.
RMXSTATUS_LOADING10The reported track is being loaded by the player
RMXSTATUS_CANPLAY11The reported track is able to begin playback
RMXSTATUS_LOADED15The reported track has loaded 100% of the file (either from disc or network)
RMXSTATUS_STALLED20(iOS only): Playback has stalled due to insufficient network
RMXSTATUS_BUFFERING25Reports an update in the reported track's buffering status
RMXSTATUS_PLAYING30The reported track has started (or resumed) playing
RMXSTATUS_PAUSE35The reported track has been paused, either by the user or by the system. (iOS only): This value is raised when MP3's are malformed (but still playable). These require the user to explicitly press play again. This can be worked around and is on the TODO list.
RMXSTATUS_PLAYBACK_POSITION40Reports a change in the reported track's playback position.
RMXSTATUS_SEEK45The reported track has seeked. On Android, only the plugin consumer can generate this (Notification controls on Android do not include a seek bar). On iOS, the Command Center includes a seek bar so this will be reported when the user has seeked via Command Center.
RMXSTATUS_COMPLETED50The reported track has completed playback.
RMXSTATUS_DURATION55The reported track's duration has changed. This is raised once, when duration is updated for the first time. For streams, this value is never reported.
RMXSTATUS_STOPPED60All playback has stopped, probably because the plugin is shutting down.
RMX_STATUS_SKIP_FORWARD90The playlist has skipped forward to the next track. On both Android and iOS, this will be raised if the notification controls/Command Center were used to skip. It is unlikely you need to consume this event: RMXSTATUS_TRACK_CHANGED is also reported when this occurs, so you can generalize your track change handling in one place.
RMX_STATUS_SKIP_BACK95The playlist has skipped back to the previous track. On both Android and iOS, this will be raised if the notification controls/Command Center were used to skip. It is unlikely you need to consume this event: RMXSTATUS_TRACK_CHANGED is also reported when this occurs, so you can generalize your track change handling in one place.
RMXSTATUS_TRACK_CHANGED100Reported when the current track has changed in the native player. This event contains full data about the new track, including the index and the actual track itself. The type of the 'value' field in this case is OnStatusTrackChangedData.
RMXSTATUS_PLAYLIST_COMPLETED105The entire playlist has completed playback. After this event has been raised, the current item is set to null and the current index to -1.
RMXSTATUS_ITEM_ADDED110An item has been added to the playlist. For the setPlaylistItems and addAllItems methods, this status is raised once for every track in the collection.
RMXSTATUS_ITEM_REMOVED115An item has been removed from the playlist. For the removeItems and clearAllItems methods, this status is raised once for every track that was removed.
RMXSTATUS_ITEM_MOVED112An item has been moved within the playlist.
RMXSTATUS_ITEM_REPLACED113An item in the playlist has been replaced in place.
RMXSTATUS_PLAYLIST_CLEARED120All items have been removed from the playlist
RMXSTATUS_VIEWDISAPPEAR200Just for testing.. you don't need this and in fact can never receive it, the plugin is destroyed before it can be raised.

RmxAudioErrorType

MembersValue
RMXERR_NONE_ACTIVE0
RMXERR_ABORTED1
RMXERR_NETWORK2
RMXERR_DECODE3
RMXERR_NONE_SUPPORTED4

Migrating from cordova-plugin-playlist

Use the shipped RmxAudioPlayer class — in the best case you only change your import:

// before
import { RmxAudioPlayer } from 'cordova-plugin-playlist';

// after
import { RmxAudioPlayer } from 'capacitor-plugin-playlist';

For new code or video handoff, prefer the Playlist plugin object directly.

Changes

See CHANGELOG.md for version history.

Credits

Inspired by:

License

The MIT License (MIT)