diff --git a/src/components/metadata/HeroSection.tsx b/src/components/metadata/HeroSection.tsx index 3d0ddc1f..83311428 100644 --- a/src/components/metadata/HeroSection.tsx +++ b/src/components/metadata/HeroSection.tsx @@ -27,6 +27,7 @@ import Animated, { withRepeat, FadeIn, runOnUI, + useDerivedValue, } from 'react-native-reanimated'; import { useTheme } from '../../contexts/ThemeContext'; import { useTraktContext } from '../../contexts/TraktContext'; @@ -1041,14 +1042,25 @@ const HeroSection: React.FC = memo(({ // The trailer should only resume if the user explicitly wants it to play return () => { - // Don't automatically stop trailer when component unmounts - // Let the new hero section (if any) take control of trailer state - // This prevents the trailer from stopping when navigating between screens - logger.info('HeroSection', 'Screen unfocused - not stopping trailer automatically'); + // Stop trailer when leaving this screen to prevent background playback/heat + logger.info('HeroSection', 'Screen unfocused - stopping trailer playback'); + setTrailerPlaying(false); }; - }, []) + }, [setTrailerPlaying]) ); + // Pause trailer when the hero is scrolled substantially off-screen + useDerivedValue(() => { + try { + const threshold = heroHeight.value * 0.6; + if (scrollY.value > threshold) { + runOnJS(setTrailerPlaying)(false); + } + } catch (e) { + // no-op + } + }); + // Memory management and cleanup useEffect(() => { return () => { diff --git a/src/components/video/TrailerPlayer.tsx b/src/components/video/TrailerPlayer.tsx index 261f967e..59714f72 100644 --- a/src/components/video/TrailerPlayer.tsx +++ b/src/components/video/TrailerPlayer.tsx @@ -338,7 +338,7 @@ const TrailerPlayer = React.forwardRef(({ style={styles.video} resizeMode={isFullscreen ? 'contain' : 'cover'} paused={!isPlaying} - repeat={isPlaying} + repeat={false} muted={isMuted} volume={isMuted ? 0 : 1} mixWithOthers="duck" @@ -347,6 +347,12 @@ const TrailerPlayer = React.forwardRef(({ useTextureView={Platform.OS === 'android' ? false : undefined} playInBackground={false} playWhenInactive={false} + onEnd={() => { + // Stop playback when trailer finishes to avoid continuous GPU/decoder use + if (isComponentMounted) { + setIsPlaying(false); + } + }} onFullscreenPlayerWillPresent={() => setIsFullscreen(true)} onFullscreenPlayerDidDismiss={() => setIsFullscreen(false)} onLoadStart={handleLoadStart} @@ -354,12 +360,6 @@ const TrailerPlayer = React.forwardRef(({ onError={(error: any) => handleError(error)} onProgress={handleProgress} controls={Platform.OS === 'android' ? isFullscreen : false} - onEnd={() => { - // Only loop if still considered playing and component is mounted - if (isPlaying && isComponentMounted) { - videoRef.current?.seek(0); - } - }} /> {/* Loading indicator - hidden during smooth transitions */}