mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +00:00
fix re render subs
This commit is contained in:
parent
7a439fa814
commit
ff1f1b2669
5 changed files with 46 additions and 8 deletions
|
|
@ -68,6 +68,8 @@
|
|||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
<string>airplay</string>
|
||||
<string>picture-in-picture</string>
|
||||
</array>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
|
|
|
|||
|
|
@ -149,9 +149,12 @@ const KSPlayerCore: React.FC = () => {
|
|||
|
||||
// Track auto-selection refs to prevent duplicate selections
|
||||
const hasAutoSelectedTracks = useRef(false);
|
||||
// Guard to prevent auto-select useEffect from running during manual subtitle loading
|
||||
const isManuallyLoadingSubtitle = useRef(false);
|
||||
|
||||
// Track previous video session to reset subtitle offset only when video actually changes
|
||||
const previousVideoRef = useRef<{ uri?: string; episodeId?: string }>({});
|
||||
|
||||
|
||||
// Reset subtitle offset when starting a new video session
|
||||
useEffect(() => {
|
||||
|
|
@ -315,6 +318,14 @@ const KSPlayerCore: React.FC = () => {
|
|||
};
|
||||
|
||||
const loadWyzieSubtitle = async (subtitle: WyzieSubtitle) => {
|
||||
// Prevent concurrent calls - return early if already loading
|
||||
if (isManuallyLoadingSubtitle.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set guard to prevent auto-select useEffect and concurrent calls from interfering
|
||||
isManuallyLoadingSubtitle.current = true;
|
||||
|
||||
modals.setShowSubtitleLanguageModal(false);
|
||||
customSubs.setIsLoadingSubtitles(true);
|
||||
try {
|
||||
|
|
@ -327,9 +338,11 @@ const KSPlayerCore: React.FC = () => {
|
|||
srtContent = await resp.text();
|
||||
}
|
||||
const parsedCues = parseSRT(srtContent);
|
||||
|
||||
// Update all state together - the guards prevent interference from other effects
|
||||
customSubs.setCustomSubtitles(parsedCues);
|
||||
customSubs.setUseCustomSubtitles(true);
|
||||
customSubs.setSelectedExternalSubtitleId(subtitle.id); // Track the selected external subtitle
|
||||
customSubs.setSelectedExternalSubtitleId(subtitle.id);
|
||||
tracks.selectTextTrack(-1);
|
||||
|
||||
const adjustedTime = currentTime + (customSubs.subtitleOffsetSec || 0);
|
||||
|
|
@ -340,6 +353,10 @@ const KSPlayerCore: React.FC = () => {
|
|||
logger.error('[VideoPlayer] Error loading wyzie', e);
|
||||
} finally {
|
||||
customSubs.setIsLoadingSubtitles(false);
|
||||
// Clear guard after a short delay to allow state to settle
|
||||
setTimeout(() => {
|
||||
isManuallyLoadingSubtitle.current = false;
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -353,7 +370,7 @@ const KSPlayerCore: React.FC = () => {
|
|||
// Auto-select subtitles when both internal tracks and video are loaded
|
||||
// This ensures we wait for internal tracks before falling back to external
|
||||
useEffect(() => {
|
||||
if (!isVideoLoaded || hasAutoSelectedTracks.current || !settings?.enableSubtitleAutoSelect) {
|
||||
if (!isVideoLoaded || hasAutoSelectedTracks.current || !settings?.enableSubtitleAutoSelect || isManuallyLoadingSubtitle.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -523,7 +540,10 @@ const KSPlayerCore: React.FC = () => {
|
|||
|
||||
// Track selection handlers - update state, prop change triggers native update
|
||||
const handleSelectTextTrack = useCallback((trackId: number) => {
|
||||
console.log('[KSPlayerCore] handleSelectTextTrack called with trackId:', trackId);
|
||||
// Prevent interference during manual subtitle loading
|
||||
if (isManuallyLoadingSubtitle.current && trackId === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable custom subtitles when selecting a built-in track
|
||||
// This ensures the textTrack prop is actually passed to the native player
|
||||
|
|
@ -655,7 +675,13 @@ const KSPlayerCore: React.FC = () => {
|
|||
audioTrack={tracks.selectedAudioTrack ?? undefined}
|
||||
textTrack={customSubs.useCustomSubtitles ? -1 : tracks.selectedTextTrack}
|
||||
onAudioTracks={(d) => tracks.setKsAudioTracks(d.audioTracks || [])}
|
||||
onTextTracks={(d) => tracks.setKsTextTracks(d.textTracks || [])}
|
||||
onTextTracks={(d) => {
|
||||
// Prevent textTracks updates during manual subtitle loading to avoid infinite loops
|
||||
if (isManuallyLoadingSubtitle.current) {
|
||||
return;
|
||||
}
|
||||
tracks.setKsTextTracks(d.textTracks || []);
|
||||
}}
|
||||
onLoad={(d) => {
|
||||
onLoad(d);
|
||||
// If we fell back from AVPlayer, continue from last time once MPV is ready.
|
||||
|
|
|
|||
|
|
@ -103,6 +103,9 @@ export const AVPlayerSurface: React.FC<AVPlayerSurfaceProps> = ({
|
|||
rate={playbackSpeed}
|
||||
resizeMode={resizeMode as any}
|
||||
allowsExternalPlayback={true}
|
||||
// iOS PiP: enter PiP automatically when user leaves the app (home/app switcher)
|
||||
// Docs: https://docs.thewidlarzgroup.com/react-native-video/docs/v6/component/props/#enterpictureinpictureonleave
|
||||
enterPictureInPictureOnLeave={true}
|
||||
selectedAudioTrack={selectedAudioTrack}
|
||||
selectedTextTrack={selectedTextTrack}
|
||||
onLoad={handleLoad}
|
||||
|
|
@ -113,7 +116,7 @@ export const AVPlayerSurface: React.FC<AVPlayerSurfaceProps> = ({
|
|||
progressUpdateInterval={250}
|
||||
// Keep background behavior consistent with the rest of the player logic
|
||||
playInBackground={false}
|
||||
playWhenInactive={false}
|
||||
playWhenInactive={true}
|
||||
ignoreSilentSwitch="ignore"
|
||||
/>
|
||||
</Animated.View>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useRef } from 'react';
|
||||
import React, { useMemo, useRef } from 'react';
|
||||
import { Animated } from 'react-native';
|
||||
import { PinchGestureHandler, State, PinchGestureHandlerGestureEvent } from 'react-native-gesture-handler';
|
||||
import MPVPlayerComponent from '../../MPVPlayerComponent';
|
||||
|
|
@ -78,6 +78,11 @@ export const KSPlayerSurface: React.FC<KSPlayerSurfaceProps> = ({
|
|||
subtitleBottomOffset
|
||||
}) => {
|
||||
const pinchRef = useRef<PinchGestureHandler>(null);
|
||||
const memoSource = useMemo(() => {
|
||||
const h = headers ?? undefined;
|
||||
return h ? { uri, headers: h } : { uri };
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [uri, headers ? JSON.stringify(headers) : '']);
|
||||
|
||||
const onPinchGestureEvent = (event: PinchGestureHandlerGestureEvent) => {
|
||||
const { scale } = event.nativeEvent;
|
||||
|
|
@ -130,7 +135,7 @@ export const KSPlayerSurface: React.FC<KSPlayerSurfaceProps> = ({
|
|||
}}>
|
||||
<MPVPlayerComponent
|
||||
ref={ksPlayerRef as any}
|
||||
source={{ uri, headers }}
|
||||
source={memoSource as any}
|
||||
paused={paused}
|
||||
volume={volume}
|
||||
rate={playbackSpeed}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,9 @@ export const SubtitleModals: React.FC<SubtitleModalsProps> = ({
|
|||
const menuMaxHeight = height * 0.95;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (showSubtitleModal && !isLoadingSubtitleList && availableSubtitles.length === 0) fetchAvailableSubtitles();
|
||||
if (showSubtitleModal && !isLoadingSubtitleList && availableSubtitles.length === 0) {
|
||||
fetchAvailableSubtitles();
|
||||
}
|
||||
}, [showSubtitleModal]);
|
||||
|
||||
const handleClose = () => setShowSubtitleModal(false);
|
||||
|
|
|
|||
Loading…
Reference in a new issue