diff --git a/src/js/plugins/captions-autoscroll.js b/src/js/plugins/captions-autoscroll.js new file mode 100644 index 000000000..589f21b2b --- /dev/null +++ b/src/js/plugins/captions-autoscroll.js @@ -0,0 +1,45 @@ +// src/js/plugins/captions-autoscroll.js + +/** + * Captions Auto-scroll Plugin + * + * This plugin keeps the active transcript/caption line + * in view while the media is playing. + * + * NOTE: + * - Opt-in only + * - Does NOT modify existing captions rendering + */ + +export default function captionsAutoscroll(player, options = {}) { + if (!player) { + return; + } + + const config = { + enabled: false, + smooth: true, + offset: 0, + transcriptContainer: null, + ...options, + }; + + function enable() { + config.enabled = true; + } + + function disable() { + config.enabled = false; + } + + function destroy() { + disable(); + } + + // Public API (attached to player) + player.autoscrollCaptions = { + enable, + disable, + destroy, + }; +} diff --git a/src/js/plyr.js b/src/js/plyr.js index 15d21386e..bc3aa3393 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -16,6 +16,7 @@ import html5 from './html5'; import Listeners from './listeners'; import media from './media'; import Ads from './plugins/ads'; +import captionsAutoscroll from './plugins/captions-autoscroll'; import PreviewThumbnails from './plugins/preview-thumbnails'; import source from './source'; import Storage from './storage'; @@ -101,6 +102,11 @@ class Plyr { currentTrack: -1, meta: new WeakMap(), }; + // Captions autoscroll plugin (keeps active cue in view) + + if (this.config.captions?.enabled !== false) { + this.captionsAutoscroll = captionsAutoscroll(this); + } // Fullscreen this.fullscreen = {