Skip to content

Add a shaka.extern.QueueConfiguration.autoPlayNext config to control automatic advancement in the QueueManager #10502

Description

@loicraux

FAQ

  • I have read the FAQ and checked for duplicate open issues

Is your feature request related to a problem? Please describe.

When using the QueueManager, advancing to the next item on playback completion is unconditional. In setupRepeatOnComplete_() in lib/queue/queue_manager.js the next index is played as soon as it exists, with no configuration gate:

const nextIndex = this.currentItemIndex_ + 1;
if (nextIndex < this.items_.length) {
  targetIndex = nextIndex; // no config check
} else if (repeatMode === shaka.config.RepeatMode.ALL) {
  targetIndex = (this.items_.length > 1) ? 0 : this.currentItemIndex_;
}

queue.repeatMode looks like the relevant knob but is not: OFF still advances from item 1 to 2 to 3, it only stops at the end of the queue. SINGLE loops the current item. So there is currently no way to say "play this item, then stop and let me show an end screen", while still keeping the queue populated.

This is the behaviour behind YouTube's "Autoplay" toggle, and it is a common product requirement: users expect to be able to turn off automatic playback of the next item, and the preference is usually persisted across sessions. It also matters for data usage on metered connections, and for accessibility (unexpected playback starting on its own).

Describe the solution you'd like

A boolean in shaka.extern.QueueConfiguration:

queueManager.configure({ autoPlayNext: false });
// or, equivalently:
player.configure('queue.autoPlayNext', false);

Default true, so existing behaviour is unchanged. Two places would read it:

  1. setupRepeatOnComplete_(): skip the "advance to next index" branch when it is false. RepeatMode.SINGLE and RepeatMode.ALL semantics would stay untouched, since they are about repeating rather than advancing.
  2. setupPreloadNext_(): skip preloading the next item when it is false, so a disabled toggle also avoids the wasted manifest request, segment fetch and DRM licence request.

Because it lives in the player configuration, it can be flipped at any time during playback, which is what a UI toggle needs. An optional UI element could follow later, but the config alone is enough to build one.

Describe alternatives you've considered

  • Managing progression in application code: keep the playlist in app state, listen for complete and call player.load()/player.preload() manually. This works, but means giving up the QueueManager entirely (per-item config, extra tracks, preloading, loadFromM3uPlaylist(), the UI queue buttons).

  • Implementing shaka.extern.IQueueManager and registering it with shaka.Player.setQueueManagerFactory(). This is a supported extension point, but it requires reimplementing the manager rather than extending it, since the relevant logic sits in private methods (setupRepeatOnComplete_, setupPreloadNext_) that are renamed by the compiler in compiled builds.

  • Shrinking the queue so no next item exists: not possible without side effects. insertItems() only appends, and the only removal method, removeAllItems(), calls player.unload().

  • Letting the manager advance and then pausing on currentitemchanged: by that point the next item has already been loaded, so bandwidth and a DRM licence request have been spent, and the "end of item" state is lost.

Additional context

Is there a recommended workaround in the meantime to implement this, for applications that want to keep using the QueueManager but need to suppress automatic advancement? If a custom IQueueManager is the intended answer for now, is subclassing shaka.queue.QueueManager and overriding playItem() considered viable, or is a full reimplementation of the interface the expected approach?

Are you planning to send a PR to add it?

No

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions