---
title: How to Play Audio in the Background in a Capacitor App
description: Learn how to play audio in the background in a Capacitor app, with native playback, lock screen media controls, and playlists that keep running.
date:
  created: 2026-08-24
  updated: 2026-08-24
authors:
  - robingenz
categories:
  - Capacitor
  - Guides
  - SDKs
links:
  - Capacitor Audio Player: sdks/capacitor/audio-player.md
faq: true
---

# How to Play Audio in the Background in a Capacitor App

Your app plays audio just fine until the user switches to another app or locks their phone. Then the sound cuts out, the lock screen shows no controls, or the next track simply never starts. If that sounds familiar, this guide is for you: you will set up background audio in a Capacitor app with the [Capacitor Audio Player plugin](../../sdks/capacitor/audio-player.md), including lock screen media controls, a playlist that advances on its own, and an in-app UI that stays in sync with what the system is doing. The result works on Android, iOS, and the Web.

<!-- more -->

<div class="capawesome-z29o10a">
  <a href="https://capawesome.io/" target="_blank">
    <img alt="Build and deploy your Capacitor app with Capawesome Cloud" src="https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
  </a>
</div>

## Key Takeaways

- Background audio in a Capacitor app requires native playback, because the operating system suspends the web view shortly after the app leaves the foreground.
- The Capacitor Audio Player plugin plays audio natively and, since version 8.4.0, handles the media session natively as well.
- On iOS, enable the `Background Modes` capability with `Audio, AirPlay, and Picture in Picture`; on Android, declare the plugin's service and two foreground service permissions.
- Providing the `metadata` option in `play(...)` activates lock screen and notification controls with title, artist, album, and artwork.
- The `playbackStateChanged` and `trackChange` events keep your in-app UI in sync when the user controls playback from the lock screen.
- Playlists advance from track to track natively, so multi-track playback continues in the background without any JavaScript involvement.

## Why Does Audio Stop in the Background?

Audio stops because the operating system suspends your app's web view shortly after it leaves the foreground. Everything that depends on JavaScript execution stops with it: HTML5 `<audio>` playback, the timer that was supposed to start the next track, and any media control handling that routes through your JavaScript code.

That last point is worth spelling out, because it explains why lock screen controls built with the [Capacitor Media Session plugin](../../sdks/capacitor/media-session.md) stop responding in the background. That plugin relays control events from the system into the web view, where your code reacts and calls back into the player. While the app is in the foreground, this round trip works. Once the web view is suspended, there is no code running on the other end. The plugin remains the right tool for playback that genuinely lives in the web view, such as HTML5 media elements or web-based calls, but it cannot prevent the web view itself from being suspended.

The way to keep audio playing in the background in a Capacitor app is to move playback out of the web view entirely. The Capacitor Audio Player plugin plays audio through native players (Media3 ExoPlayer on Android), and since [version 8.4.0](./capacitor-audio-player-8-4-0-release.md) it also handles the media session natively. Neither the sound nor the lock screen controls depend on your JavaScript being awake.

## Set Up Background Playback

The Capacitor Audio Player plugin is available to [Capawesome Insiders](https://capawesome.io/insiders/){:target="_blank"}. To install it, please refer to the [Installation](../../sdks/capacitor/audio-player.md/#installation) section in the plugin documentation. After that, each platform needs a small amount of configuration.

### iOS

Enable the `Background Modes` capability in your Xcode project and check `Audio, AirPlay, and Picture in Picture`. Apple explains the steps in [Add a capability to a target](https://help.apple.com/xcode/mac/current/#/dev88ff319e7){:target="_blank"}. Without this capability, iOS pauses your audio the moment the app leaves the foreground.

### Android

Android runs background playback in a foreground service that the plugin provides. Declare it inside the `application` tag of your `AndroidManifest.xml`:

```xml
<service
    android:name="io.capawesome.capacitorjs.plugins.audioplayer.AudioPlayerService"
    android:exported="false"
    android:foregroundServiceType="mediaPlayback">
    <intent-filter>
        <action android:name="androidx.media3.session.MediaSessionService" />
    </intent-filter>
</service>
```

The service displays the media controls in a notification, which requires two permissions next to the `application` tag:

```xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
```

That is the entire platform setup. Everything else happens in TypeScript.

## Play a Playlist with Lock Screen Controls

To start playback, call [`play(...)`](../../sdks/capacitor/audio-player.md#play) with one or more tracks and give each track a `metadata` object. The metadata is what activates the media session: the system shows your playback in the notification and on the lock screen, with title, artist, album, and artwork. For a podcast app, an episode queue looks like this:

```typescript
import { AudioPlayer } from '@capawesome-team/capacitor-audio-player';

const startEpisodeQueue = async () => {
  await AudioPlayer.play({
    tracks: [
      {
        src: 'https://example.com/episodes/42.mp3',
        metadata: {
          title: 'Episode 42: Background Audio',
          artist: 'The Example Podcast',
          album: 'Season 3',
          artworkSource: '/assets/cover.png',
        },
      },
      {
        src: 'https://example.com/episodes/43.mp3',
        metadata: {
          title: 'Episode 43: Media Sessions',
          artist: 'The Example Podcast',
          album: 'Season 3',
          artworkSource: '/assets/cover.png',
        },
      },
    ],
  });
};
```

A few details to know: `artworkSource` accepts a web asset path or a remote URL. The `src` option covers web assets and remote URLs; tracks can also come from the device's file system via `uri` on Android and iOS. And on iOS, the next and previous track buttons appear once the queue contains more than one track.

From here, the user can lock the phone and everything keeps working: the current episode plays to the end, the next one starts automatically, and the skip buttons on the lock screen move through the queue. Inside your app, [`skipToNextTrack()`](../../sdks/capacitor/audio-player.md#skiptonexttrack), [`skipToPreviousTrack()`](../../sdks/capacitor/audio-player.md#skiptoprevioustrack), and [`setRepeatMode(...)`](../../sdks/capacitor/audio-player.md#setrepeatmode) give you the matching controls; the [Audio Player 8.4.0 release post](./capacitor-audio-player-8-4-0-release.md) walks through the full playlist API, including queue editing during playback.

## Keep Your App UI in Sync

Once the lock screen can control your playback, your app is no longer the only source of truth. If the user pauses from the notification, your in-app play button must not keep showing "pause". The plugin reports everything that happens through two events, so register listeners for both:

```typescript
import {
  AudioPlayer,
  PlaybackState,
} from '@capawesome-team/capacitor-audio-player';

const registerListeners = async () => {
  await AudioPlayer.addListener('playbackStateChanged', (event) => {
    const isPlaying = event.state === PlaybackState.Playing;
    // Update your play/pause button here.
  });
  await AudioPlayer.addListener('trackChange', (event) => {
    // Highlight the episode at this index in your queue view.
    console.log('Now playing track', event.index);
  });
};
```

The [`playbackStateChanged`](../../sdks/capacitor/audio-player.md#addlistenerplaybackstatechanged-) event fires on every transition between playing, paused, and stopped, regardless of where the change came from. The [`trackChange`](../../sdks/capacitor/audio-player.md#addlistenertrackchange-) event reports the index of each track that starts, including tracks that started through native auto-advance while your app was in the background. When the user returns to the app, [`getCurrentTrackIndex()`](../../sdks/capacitor/audio-player.md#getcurrenttrackindex) and [`getCurrentPosition()`](../../sdks/capacitor/audio-player.md#getcurrentposition) let you restore the UI to the current state.

## How to Test Background Audio

Test on a real device, since background behavior and lock screen controls are exactly the things an emulator or the browser will not reproduce faithfully. A quick checklist:

1. Start playback, then switch to another app. The audio should continue without interruption.
2. Lock the device. The lock screen should show the track's metadata and artwork with working play, pause, and skip controls.
3. Pause from the lock screen and reopen your app. Your UI should show the paused state, driven by the `playbackStateChanged` event.
4. Let a track play to its end while the app is in the background. The next track should start on its own, and `trackChange` should have fired when you return.

If the controls do not appear on Android, the manifest entries from the setup section are the first thing to double-check.

To get notified when we publish more guides like this one, subscribe to our newsletter:

[Subscribe to the Capawesome Newsletter](https://capawesome.io/newsletter/){ .md-button .md-button--primary }

## Conclusion

Background audio in a Capacitor app comes down to three ingredients: the platform configuration that allows audio to run in the background, native playback with `metadata` so the system presents your media controls, and event listeners so your UI follows along. With the Capacitor Audio Player plugin, none of it requires keeping your JavaScript alive, which is precisely what makes it reliable.

To see what else shipped alongside these capabilities, read [Audio Player 8.4.0: Playlists and Media Session Support](./capacitor-audio-player-8-4-0-release.md). If you run into questions, join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW){:target="_blank"}, and subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/){:target="_blank"} to stay up to date on the latest news.
