# Playlists

`PlaylistAPI` provides playlist loading, navigation, and item management for a `PlayerAPI` instance. Playlist implementations are exposed by plugins.

## Playlist modes

`HLSPlugin` currently provides two modes.

### Native Queue

Uses `AVQueuePlayer` internally. The queue keeps upcoming items prepared and handles transitions between items.

### Item Replace

Uses a single player item pipeline. When the active index changes, the current item is replaced with the selected item.

## Basic usage

Enable `HLSPlugin` during SDK setup:

    import PRESTOplay
    import CastlabsApple

    let setupError = PRESTOplaySDK.shared.setup("LICENSE", [HLSPlugin()])

Create a player, create a playlist, and load items:

    let player = PRESTOplaySDK.shared.player()
    let playlist = PRESTOplaySDK.shared.playlist(for: player, mode: .nativeQueue)!

    let items = [
        PlayerConfiguration(with: URL(string: "https://example.com/stream-1.m3u8")!),
        PlayerConfiguration(with: URL(string: "https://example.com/stream-2.m3u8")!)
    ]

    playlist.load(items: items)

    playlist.onItemChange = {
        print("Current index: \(playlist.getCurrentItemIndex())")
    }

    playlist.onPlaylistEnded = {
        print("Playlist ended")
    }

    playlist.nextItem()
    playlist.previousItem()
    playlist.playItem(at: 1)

    let item3 = PlayerConfiguration(with: URL(string: "https://example.com/stream-3.m3u8")!)
    playlist.addItem(item3)
    playlist.removeItem(at: 0)

Create a playlist without passing `mode` to use the default `PlaylistMode.playerRecreate`:

    let defaultPlaylist = PRESTOplaySDK.shared.playlist(for: player)

For `PlaylistMode.nativeQueue`, configure loop behavior with `loopList`:

    let loopingPlaylist = PRESTOplaySDK.shared.playlist(
        for: player,
        mode: .nativeQueue,
        loopList: true
    )

`loopList` defaults to `true`. When `false`, navigation stops at the queue boundaries. `playItem(at:)` keeps the current item unchanged when the index is out of bounds.