Playlists

A playlist plays several sources one after another in a single playback session. The player transitions from one source to the next without unloading the session, can preload the upcoming sources, and lets you add, remove and switch sources while it is playing.

🚧

Experimental

The Playlist API is available since v1.31.0 and is experimental on React Native.

Loading a playlist

Create a Source for each entry and load them via Player.loadPlaylist. The first source becomes active immediately:

import { useCallback } from 'react';
import {
  PlayerView,
  ReplayMode,
  Source,
  SourceType,
  usePlayer,
} from 'bitmovin-player-react-native';

export default function PlaylistScreen() {
  const player = usePlayer();

  const onPlayerViewReady = useCallback(() => {
    player.loadPlaylist({
      sources: [
        new Source({
          url: 'https://cdn.bitmovin.com/content/assets/streams-sample-video/tos/m3u8/index.m3u8',
          type: SourceType.HLS,
          title: 'Tears of Steel',
        }),
        new Source({
          url: 'https://cdn.bitmovin.com/content/assets/streams-sample-video/sintel/m3u8/index.m3u8',
          type: SourceType.HLS,
          title: 'Sintel',
        }),
      ],
      options: {
        // Preload all sources right away instead of shortly before each transition.
        preloadAllSources: true,
        // Replay the whole playlist once it finished.
        replayMode: ReplayMode.Playlist,
      },
    });
  }, [player]);

  return (
    <PlayerView
      player={player}
      style={{ flex: 1 }}
      onPlayerViewReady={onPlayerViewReady}
    />
  );
}
OptionDescriptionDefault
preloadAllSourcesWhether all sources start preloading when the playlist is loaded. Progressive sources are not preloaded this way, but naturally before their transition.false
replayModeWhether a replay starts at the first source (ReplayMode.Playlist) or at the last source (ReplayMode.LastSource).ReplayMode.Playlist

Loading a playlist unloads the current playback session first, the same way as Player.loadSource does.

loadPlaylist throws synchronously for configurations that cannot be loaded:

  • an empty list of sources
  • a source listed more than once
  • a source that was destroyed
  • an unknown replayMode
  • on iOS and tvOS, a source type other than HLS, progressive or movpkg

How a playlist plays

Only one source of a playlist is active at a time. All player APIs, such as currentTime, duration or seek, act on the active source; there is no playlist-wide time.

When the active source ends and the next begins, or when you manually switch to another source, the player emits playlistTransition, and the next source becomes active.

Reading the playlist

// All sources of the playback session, in playback order.
const sources = await player.playlist.getSources();

// The source that is currently active.
const activeSource = await player.getSource();

Both return the Source instances you passed to the player.

Switching sources

To switch to another source of the playlist, seek to a position in that source:

// Start `nextSource` from the beginning.
await player.playlist.seek(nextSource, 0);

To seek within the active source, keep using player.seek.

Modifying the playlist

Sources can be added and removed while the playlist is playing:

// Append a source to the end of the playlist or at an index.
await player.playlist.add(source);
await player.playlist.add(otherSource, 2);

// Remove a source, or the source at an index.
await player.playlist.remove(source);
await player.playlist.removeAt(2);
  • add rejects if the source is already part of a player, was destroyed, or (on iOS and tvOS) has an unsupported type.
  • The active source cannot be removed. Calling remove on it has no effect.
  • On Android, operations that have no effect, e.g. removing the active source or adding a source while no playlist is loaded, emit a playerWarning event. On iOS and tvOS, the native SDK only logs a warning to the Xcode console.

Playlist events

EventPlayerView propEmitted when
sourceAddedonSourceAddeda source was added to the playback session, while loading the playlist (for every source) or via playlist.add
sourceRemovedonSourceRemoveda source was removed from the playback session, via playlist.remove / removeAt or while unloading
playlistTransitiononPlaylistTransitionthe player transitioned from one source to another; event.from and event.to describe the two sources

Events carry the source as EventSource. Its nativeId matches the nativeId of your Source instance:

useEffect(() => {
  const onPlaylistTransition = (event: PlaylistTransitionEvent) => {
    const nowPlaying = sources.find((s) => s.nativeId === event.to.nativeId);
    console.log('Now playing', nowPlaying?.config?.title);
  };
  player.on('playlistTransition', onPlaylistTransition);
  return () => player.off('playlistTransition', onPlaylistTransition);
}, [player, sources]);
📘

Events of inactive sources

The player, and with it Player.on and the PlayerView props, only emits the source events of the active source. For example, the sourceLoaded of a preloaded source is not emitted by the player. Use Source.on to receive the events of a specific source, including while it is inactive:

source.on('sourceLoaded', () => console.log('Preloaded', source.config?.title));

See Listening to events for details.

Source lifecycle

When the player is destroyed, it also destroys the sources it has loaded or added, including sources it no longer plays. A source that was loaded into another player since is not destroyed.

Sources removed via playlist.remove or playlist.removeAt are not destroyed with the player. Destroy them yourself once they are no longer needed:

await player.playlist.remove(source);
source.destroy();

A source can only be part of one player at a time.

Known limitations

  • Sources that left the player through Player.unload or a later load stay allocated until the player is destroyed.
  • Source.on listeners do not receive the final sourceUnloaded of a source that is destroyed together with its player (Player.destroy). Player.on listeners and the onSourceUnloaded prop receive it for the active source.
  • On Android, SourceUnloadedEvent.source is not set for events received via Player.on or the PlayerView props.

API reference

A complete example is available in the Playlist sample of the example app.


Did this page help you?