From ea7caa20d91e8e38bce3481cce2a225451992b1f Mon Sep 17 00:00:00 2001 From: Pas <74743263+Pasithea0@users.noreply.github.com> Date: Tue, 11 Nov 2025 11:46:46 -0700 Subject: [PATCH] Refactor Native Subtitles feature. Fix playback on ios --- src/assets/locales/en.json | 4 ++-- src/components/player/base/SubtitleView.tsx | 10 +++++++-- .../player/internals/VideoContainer.tsx | 21 ++++++++++++++----- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json index df981271..f0a680a5 100644 --- a/src/assets/locales/en.json +++ b/src/assets/locales/en.json @@ -777,8 +777,8 @@ "refreshing": "Refreshing...", "empty": "There are no provided subtitles for this.", "notFound": "None of the available options match your query", - "useNativeSubtitles": "Use native video subtitles", - "useNativeSubtitlesDescription": "May fix subtitles when casting and in PiP", + "useNativeSubtitles": "Native video subtitles", + "useNativeSubtitlesDescription": "Broadcast subtitles for native fullscreen and PiP", "delayLate": "Heard audio", "delayEarly": "Saw caption" }, diff --git a/src/components/player/base/SubtitleView.tsx b/src/components/player/base/SubtitleView.tsx index aadc31bb..b526806a 100644 --- a/src/components/player/base/SubtitleView.tsx +++ b/src/components/player/base/SubtitleView.tsx @@ -8,6 +8,7 @@ import { } from "@/components/player/utils/captions"; import { Transition } from "@/components/utils/Transition"; import { usePlayerStore } from "@/stores/player/store"; +import { usePreferencesStore } from "@/stores/preferences"; import { SubtitleStyling, useSubtitleStore } from "@/stores/subtitles"; const wordOverrides: Record = { @@ -151,12 +152,17 @@ export function SubtitleRenderer() { export function SubtitleView(props: { controlsShown: boolean }) { const caption = usePlayerStore((s) => s.caption.selected); - const captionAsTrack = usePlayerStore((s) => s.caption.asTrack); + const source = usePlayerStore((s) => s.source); const display = usePlayerStore((s) => s.display); const isCasting = display?.getType() === "casting"; const styling = useSubtitleStore((s) => s.styling); + const enableNativeSubtitles = usePreferencesStore( + (s) => s.enableNativeSubtitles, + ); - if (captionAsTrack || !caption || isCasting) return null; + // Hide custom captions when native subtitles are enabled + const shouldUseNativeTrack = enableNativeSubtitles && source !== null; + if (shouldUseNativeTrack || !caption || isCasting) return null; return ( diff --git a/src/components/player/internals/VideoContainer.tsx b/src/components/player/internals/VideoContainer.tsx index 89d34433..87dec420 100644 --- a/src/components/player/internals/VideoContainer.tsx +++ b/src/components/player/internals/VideoContainer.tsx @@ -4,6 +4,7 @@ import { makeVideoElementDisplayInterface } from "@/components/player/display/ba import { convertSubtitlesToObjectUrl } from "@/components/player/utils/captions"; import { playerStatus } from "@/stores/player/slices/source"; import { usePlayerStore } from "@/stores/player/store"; +import { usePreferencesStore } from "@/stores/preferences"; import { useInitializeSource } from "../hooks/useInitializePlayer"; @@ -66,13 +67,19 @@ function VideoElement() { const trackEl = useRef(null); const display = usePlayerStore((s) => s.display); const srtData = usePlayerStore((s) => s.caption.selected?.srtData); - const captionAsTrack = usePlayerStore((s) => s.caption.asTrack); const language = usePlayerStore((s) => s.caption.selected?.language); + const source = usePlayerStore((s) => s.source); + const enableNativeSubtitles = usePreferencesStore( + (s) => s.enableNativeSubtitles, + ); const trackObjectUrl = useObjectUrl( () => (srtData ? convertSubtitlesToObjectUrl(srtData) : null), [srtData], ); + // Use native tracks when the setting is enabled + const shouldUseNativeTrack = enableNativeSubtitles && source !== null; + // report video element to display interface useEffect(() => { if (display && videoEl.current) { @@ -80,17 +87,20 @@ function VideoElement() { } }, [display, videoEl]); - // select track as showing if it exists + // Control track visibility based on setting useEffect(() => { if (trackEl.current) { - trackEl.current.track.mode = "showing"; + trackEl.current.track.mode = shouldUseNativeTrack ? "showing" : "hidden"; } - }, [trackEl]); + }, [shouldUseNativeTrack, trackEl]); + // Attach track when native subtitles are enabled + // SubtitleView handles showing custom captions when native subtitles are disabled let subtitleTrack: ReactNode = null; - if (captionAsTrack && trackObjectUrl && language) + if (shouldUseNativeTrack && trackObjectUrl && language) { subtitleTrack = ( ); + } return (