---
updatedAt: 2026-09-16T17:12:17.000Z
agentTools:
  siteIndex: https://docs.jwplayer.com/llms.txt
  projectIndex: https://docs.jwplayer.com/players/llms.txt
---

# Add captions (Android)

Add embedded or sidecar captions to your Android app

<img src="https://img.shields.io/badge/%20-ENTERPRISE-%23B10031" style="float:left"/><br />

If you have captions or subtitles for your video content, you can use the following sections to add embedded or sidecar captions to your app.

Although there are differences between the intended purposes of captions and subtitles, you use the same processes to add or to customize either type of synchronized text to your app. For simplicity, both captions and subtitles are referred to as captions in our documentation.

<br />

<Callout icon="📘" theme="info">
  The JWX SDKs respect the Caption Styling accessibility preferences of a viewer. This enables your viewers to maintain their customizations while still enjoying the video experience you have created.
</Callout>

<br />
<hr />

## Add captions to your app

### Embedded captions

To add videos or streams with embedded captions to your app, follow the steps to create a playlist. Replace step 2 of the process with the two steps below:

1. Copy the URL of your video. **The video must contain CEA-608, CEA-708, or in-manifest WebVTT captions.**
2. Define the `file` property of the `PlaylisItem` object with the URL of your video.

<br />

### Sidecar captions

1. Create a `List<Caption>` object and name it, for example, `captionTracks`.
2. Use `Caption.Builder()` to create and name a `Caption` object for each caption track.
3. Add the caption track URL (`file`) and a language label (`label`).
4. (Optional) If you have multiple tracks, set `isDefault(true)` for the default caption track.
5. Add each caption track to `captionTracks`.
6. Add `captionTracks` to a playlist item.

<br />

```java Sidecar Caption Example
List<Caption> captionTracks = new ArrayList<>();

Caption captionEn = new Caption.Builder()
    .file("https://www.yourdomain.com/caption-file_en.vtt")
    .label("English")
    .kind(CaptionType.CAPTIONS)
    .isDefault(true)
    .build();
captionTracks.add(captionEn);

Caption captionSp = new Caption.Builder()
    .file("https://www.yourdomain.com/caption-file_sp.vtt")
    .label("Español")
    .kind(CaptionType.CAPTIONS)
    .build();
captionTracks.add(captionSp);

PlaylistItem playlistItem = new PlaylistItem.Builder()
    .file("https://cdn.jwplayer.com/manifests/{MEDIA_ID}.m3u8")
    .image("https://www.mydomain.com/poster.jpg")
    .title("The Title")
    .description("The description")
    .tracks(captionTracks)
    .build();

List<PlaylistItem> playlist = new ArrayList<>();
playlist.add(playlistItem);
PlayerConfig config = new PlayerConfig.Builder()
    .playlist(playlist)
    .build();
mPlayer.setup(config);
```

<br />

### Customize caption appearance

Starting with Android SDK 4.27.0, you can use `CaptionsConfig` to customize WebVTT, SRT, and TTML captions rendered by the player. Use `CaptionPosition` to control caption width, alignment, and placement.

By default, viewer accessibility preferences and styles defined in the caption track take precedence over `CaptionsConfig`. To make the configured styling take precedence, use `overrideStrategy(CaptionsConfig.OVERRIDE_STRATEGY_ALWAYS)`. CEA-608/708 captions continue to use styling provided by the caption data and the viewer's device settings.

<br />

Use the following steps to configure caption appearance:

1. (Optional) Use `CaptionPosition.Builder()` to define the default width, alignment, and position of captions within the rendered video.
2. Use `CaptionsConfig.Builder()` to define the caption appearance.
3. Add the `CaptionsConfig` object to the `PlayerConfig`.

```java
CaptionPosition captionPosition = new CaptionPosition.Builder()
    .width(80)
    .horizontalPosition(10)
    .alignment(CaptionPosition.ALIGNMENT_CENTER)
    .linePercentage(85)
    .build();

CaptionsConfig captionsConfig = new CaptionsConfig.Builder()
    .fontFamily("sans-serif")
    .fontSize(24)
    .color(Color.WHITE)
    .backgroundColor(Color.TRANSPARENT)
    .windowColor(0x80000000)
    .edgeStyle(CaptionsConfig.EDGE_STYLE_DROP_SHADOW)
    .position(captionPosition)
    .overrideStrategy(CaptionsConfig.OVERRIDE_STRATEGY_VIDEO_OVERRIDE_ONLY)
    .allowScaling(true)
    .build();

PlayerConfig config = new PlayerConfig.Builder()
    .playlist(playlist)
    .captionsConfig(captionsConfig)
    .build();

mPlayer.setup(config);
```

<br />

`backgroundColor` controls the background directly behind the caption text, while `windowColor` controls the caption region. `CaptionPosition` values are relative to the rendered video area. Track-defined positioning takes precedence over `CaptionPosition`, and the player does not automatically reposition captions to avoid the control bar.

For all properties and accepted values, see <a href="https://sdk.jwplayer.com/android/v4/reference/com/jwplayer/pub/api/configuration/CaptionsConfig.html" target="_blank">`CaptionsConfig`</a> and `CaptionPosition` in the Android SDK reference.

<br />

### Add captions to existing preview thumbnails

If you have existing [preview thumbnails](https://docs.jwplayer.com/players/docs/android-firetv-add-preview-thumbnails), you should add captions to that existing `tracks` list. Creating a new `tracks` list for captions will cause only the most recently added `track` to load.

The following code example illustrates how two caption `tracks` can be added to an existing preview thumbnail setup and associated with a playlist through `PlaylistItem.Builder()`.

<br />

```java Captions with thumbnails example
List < Caption > tracks = new ArrayList < > ();
Caption captionEn = new Caption.Builder()
    .file("https://www.yourdomain.com/caption-file_en.vtt")
    .label("English")
    .kind(CaptionType.CAPTIONS)
    .isDefault(true)
    .build();
tracks.add(captionEn);
Caption captionSp = new Caption.Builder()
    .file("https://www.yourdomain.com/caption-file_sp.vtt")
    .label("Español")
    .kind(CaptionType.CAPTIONS)
    .build();
tracks.add(captionSp);
Caption previewThumbnail = new Caption.Builder()
    .file("https://cdn.jwplayer.com/strips/{MEDIA_ID}-120.vtt")
    .kind(CaptionType.THUMBNAILS)
    .build();
tracks.add(previewThumbnail);
PlaylistItem playlistItem = new PlaylistItem.Builder()
    .file("https://cdn.jwplayer.com/manifests/{MEDIA_ID}.m3u8")
    .image("https://www.mydomain.com/poster.jpg")
    .title("Playlist-Item Title")
    .description("Some really great content")
    .tracks(tracks)
    .build();
```

<br />
<hr />

## Captions Methods and Callbacks

<br />

### Methods

<span class="manual-tbl-font">

| Method                            | Description                                                                                                                           |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `List<Caption> getCaptionsList()` | Returns a List with captions tracks from the player                                                                                   |
| `int getCurrentCaptions()`        | Returns the index of the currently active captions track<br /><br />The captions are off if the index is `0`                          |
| `setCurrentCaptions(int index)`   | Change the visible captions track to the provided index<br /><br />The index must be within the list provided by `getCaptionsList()`. |

</span>

<br />

### Callbacks

<span class="manual-tbl-font">

| Callback                                              | Description                                                 |
| ----------------------------------------------------- | ----------------------------------------------------------- |
| `onCaptionsList(CaptionsListEvent captionsListEvent)` | Fired when the list of available captions tracks is updated |
| `onCaptionsChanged(CaptionsChangedEvent)`             | Fired when the active captions track is changed             |

</span>

<style>
.rm-Pagination {
  display: none;
}
</style>

# Sibling pages

* [Add preview thumbnails (Android)](https://docs.jwplayer.com/players/docs/android-add-preview-thumbnails.md)
* [Customize the look-ahead buffer (Android)](https://docs.jwplayer.com/players/docs/android-customize-the-look-ahead-buffer.md)