Files
shaka-player/docs/tutorials/queue-manager.md
T
2026-05-06 21:30:40 +02:00

262 lines
7.5 KiB
Markdown

# Queue Manager
The `QueueManager` allows you to manage a playlist of media items in Shaka Player,
handling automatic progression, repeat modes, and preloading of adjacent items to
minimize transition latency.
It is automatically created and associated with a `shaka.Player` instance — you
do not need to instantiate it directly.
#### Basic Usage
Retrieve the `QueueManager` from a player instance and insert items to play:
```js
async function initPlayer() {
const video = document.getElementById('video');
const player = new shaka.Player();
await player.attach(video);
const queueManager = player.getQueueManager();
// Insert one or more items into the queue
queueManager.insertItems([
{ manifestUri: 'https://example.com/video1/dash.mpd' },
{ manifestUri: 'https://example.com/video2/dash.mpd' },
{ manifestUri: 'https://example.com/video3/dash.mpd' },
]);
// Start playback from the first item
await queueManager.playItem(0);
}
```
Each item in the queue is a `QueueItem` object. At minimum it requires a
`manifestUri`, but it also accepts optional fields:
```js
{
manifestUri: 'https://example.com/video.mpd', // Required
startTime: 30, // Optional: start offset in seconds
mimeType: 'application/dash+xml', // Optional: hint for the player
config: { /* shaka.extern.PlayerConfiguration */ }, // Optional: per-item config
preloadManager: null, // Optional: pre-built PreloadManager
extraText: [...], // Optional: additional text tracks
extraThumbnail: [...], // Optional: additional thumbnail tracks
extraChapter: [...], // Optional: additional chapter tracks
metadata: { /* shaka.extern.QueueItemMetadata */ }, // Optional: display metadata
}
```
#### Navigating the Queue
You can jump to any item by index, and inspect the current state of the queue
at any time:
```js
// Play the third item (zero-based index)
await queueManager.playItem(2);
// Get the currently playing item
const currentItem = queueManager.getCurrentItem();
console.log('Now playing:', currentItem.manifestUri);
// Get the current index
const index = queueManager.getCurrentItemIndex();
// Get a snapshot of all items in the queue
const allItems = queueManager.getItems();
console.log(`Queue has ${allItems.length} items`);
```
`playItem` throws a `shaka.util.Error` with code `QUEUE_INDEX_OUT_OF_BOUNDS`
if the provided index is out of range.
#### Repeat Modes
The `QueueManager` supports three repeat modes, configured via
`queueManager.configure()`:
```js
queueManager.configure({
repeatMode: shaka.config.RepeatMode.ALL, // Repeat the whole queue
});
```
| Mode | Behaviour |
|---|---|
| `shaka.config.RepeatMode.OFF` | Playback stops after the last item. |
| `shaka.config.RepeatMode.SINGLE` | The current item loops indefinitely. |
| `shaka.config.RepeatMode.ALL` | The queue loops back to the first item after the last. |
The default mode is `OFF`.
#### Preloading Adjacent Items
To reduce the transition delay between items, the `QueueManager` can
automatically preload the next item as the current one approaches its end, and
optionally preserve a preload of the previous item in case the user seeks back.
```js
queueManager.configure({
repeatMode: shaka.config.RepeatMode.ALL,
// Start preloading the next item when this many seconds remain in the current one
preloadNextUrlWindow: 30,
// Save a preload of the previous item when advancing forward
preloadPrevItem: true,
});
```
When `preloadNextUrlWindow` is set to a positive value, the manager listens to
the playback position and triggers a `player.preload()` call automatically.
You do not need to manage this yourself.
If `preloadPrevItem` is `true`, navigating to the next item will internally
call `player.unloadAndSavePreload()` on the current one, so going back is
faster. This only works when the player is in `MEDIA_SOURCE` load mode.
#### Listening to Queue Events
The `QueueManager` extends `FakeEventTarget` and dispatches events you can
subscribe to:
```js
queueManager.addEventListener('currentitemchanged', () => {
const item = queueManager.getCurrentItem();
console.log('Now playing:', item.manifestUri);
});
queueManager.addEventListener('itemsinserted', () => {
console.log('Items added. Queue length:', queueManager.getItems().length);
});
queueManager.addEventListener('itemsremoved', () => {
console.log('Queue cleared.');
});
```
| Event | Fired when |
|---|---|
| `currentitemchanged` | `playItem()` is called with a different index than the current one. |
| `itemsinserted` | `insertItems()` is called. |
| `itemsremoved` | `removeAllItems()` is called. |
#### Adding Extra Tracks per Item
Each `QueueItem` can carry additional text, thumbnail, or chapter tracks that
are added to the player automatically once streaming begins:
```js
queueManager.insertItems([
{
manifestUri: 'https://example.com/video.mpd',
extraText: [
{
uri: 'https://example.com/subtitles-en.vtt',
language: 'en',
kind: 'subtitle',
mime: 'text/vtt',
},
],
extraThumbnail: [
'https://example.com/thumbnails.vtt',
],
extraChapter: [
{
uri: 'https://example.com/chapters-en.vtt',
language: 'en',
mime: 'text/vtt',
},
],
},
]);
```
All extra tracks for a given item are added in parallel after the `streaming`
event fires, so they do not block initial playback.
#### Item Metadata
Each `QueueItem` accepts an optional `metadata` field of type
`shaka.extern.QueueItemMetadata`. It has two well-known properties —
`title` and `poster` — and supports any additional arbitrary properties
your application needs (they are not type-checked by Shaka).
```js
queueManager.insertItems([
{
manifestUri: 'https://example.com/video.mpd',
metadata: {
title: 'My Awesome Video',
poster: 'https://example.com/poster.jpg',
// Any extra application-level data is allowed:
description: 'An optional description for your UI',
durationSeconds: 3600,
},
},
]);
```
You can read the metadata back from `getCurrentItem()` to drive your own UI
(e.g. update a title bar or thumbnail while the item changes):
```js
queueManager.addEventListener('currentitemchanged', () => {
const item = queueManager.getCurrentItem();
if (item?.metadata) {
document.getElementById('title').textContent = item.metadata.title ?? '';
document.getElementById('poster').src = item.metadata.poster ?? '';
}
});
```
Note: `metadata` is purely application-side data. Shaka Player does not read
or use it internally.
#### Per-item Player Configuration
If different items in your queue require different player settings (e.g.
different DRM configurations or ABR constraints), you can attach a `config`
object to each `QueueItem`. The manager will call `player.resetConfiguration()`
followed by `player.configure(item.config)` before loading that item:
```js
queueManager.insertItems([
{
manifestUri: 'https://example.com/clear.mpd',
},
{
manifestUri: 'https://example.com/protected.mpd',
config: {
drm: {
servers: {
'com.widevine.alpha': 'https://example.com/license',
},
},
},
},
]);
```
#### Clearing the Queue
To stop playback and remove all items from the queue:
```js
await queueManager.removeAllItems();
```
This unloads the player, destroys any active or pending `PreloadManager`
instances, and resets the current index to `-1`.