From b19b92cd32af5fcea889ff3a161acdebff30028a Mon Sep 17 00:00:00 2001 From: Mark Sergienko Date: Thu, 22 Jan 2026 11:16:44 +0000 Subject: [PATCH] fix: sync captions to native iOS fullscreen player When using iosNative: true, captions were not displayed in the native iOS fullscreen video player. This was because Plyr sets all track modes to hidden to handle its own caption rendering, but the native iOS player only shows captions when track mode is showing. This fix: - Listens for webkitbeginfullscreen/webkitendfullscreen events - Sets the active caption track mode to showing when entering native fullscreen so iOS can render captions - Restores track mode to hidden when exiting so Plyr can resume controlling caption rendering Also fixes a bug where exit() was calling webkitEnterFullscreen() instead of webkitExitFullscreen(). Fixes #2732 Co-Authored-By: Claude Opus 4.5 --- src/js/fullscreen.js | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/js/fullscreen.js b/src/js/fullscreen.js index e14b3df7c..fca29e1b7 100644 --- a/src/js/fullscreen.js +++ b/src/js/fullscreen.js @@ -55,6 +55,16 @@ class Fullscreen { // Tap focus when in fullscreen on.call(this, this.player.elements.container, 'keydown', event => this.trapFocus(event)); + // Handle iOS native fullscreen caption sync + if (browser.isIos && this.player.config.fullscreen.iosNative) { + on.call(this.player, this.player.media, 'webkitbeginfullscreen', () => { + this.syncCaptionsToNative(true); + }); + on.call(this.player, this.player.media, 'webkitendfullscreen', () => { + this.syncCaptionsToNative(false); + }); + } + // Update the UI this.update(); } @@ -245,6 +255,25 @@ class Fullscreen { toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.supported); }; + // Sync captions for iOS native fullscreen + // When entering native fullscreen, set track mode to 'showing' so iOS can render captions + // When exiting, set back to 'hidden' so Plyr can control caption rendering + syncCaptionsToNative = (enteringFullscreen) => { + const { currentTrackNode, toggled } = this.player.captions; + + // Only sync if captions are enabled and we have a valid track + if (!currentTrackNode) return; + + if (enteringFullscreen && toggled) { + // Enable native caption rendering for iOS fullscreen + currentTrackNode.mode = 'showing'; + } + else if (!enteringFullscreen) { + // Restore Plyr-controlled rendering + currentTrackNode.mode = 'hidden'; + } + }; + // Make an element fullscreen enter = () => { if (!this.supported) return; @@ -279,7 +308,7 @@ class Fullscreen { this.player.embed.exitFullscreen(); } else { - this.target.webkitEnterFullscreen(); + this.target.webkitExitFullscreen(); } silencePromise(this.player.play()); }