From 1605d5251e173ff3e4c81072fc25af684cc4692c Mon Sep 17 00:00:00 2001 From: tapframe Date: Sat, 21 Jun 2025 15:49:43 +0530 Subject: [PATCH] Enhance AndroidVideoPlayer component with dynamic resize mode support This update introduces a new optional prop for resize mode in the AndroidVideoPlayer component, allowing users to specify how the video should be displayed. The default resize mode is set to 'contain', and the component now supports cycling through various resize modes. Additionally, the PlayerControls component has been updated to reflect the current resize mode, improving user interaction and experience. --- components/AndroidVideoPlayer.tsx | 6 ++++-- src/components/player/AndroidVideoPlayer.tsx | 18 ++++++++++-------- src/components/player/VideoPlayer.tsx | 6 +++--- .../player/controls/PlayerControls.tsx | 8 +++++++- src/hooks/useTraktIntegration.ts | 16 ++++++++-------- src/services/storageService.ts | 16 ++++++++-------- 6 files changed, 40 insertions(+), 30 deletions(-) diff --git a/components/AndroidVideoPlayer.tsx b/components/AndroidVideoPlayer.tsx index 8865071..73fe56f 100644 --- a/components/AndroidVideoPlayer.tsx +++ b/components/AndroidVideoPlayer.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; import { Platform } from 'react-native'; -import Video, { VideoRef, SelectedTrack, BufferingStrategyType } from 'react-native-video'; +import Video, { VideoRef, SelectedTrack, BufferingStrategyType, ResizeMode } from 'react-native-video'; interface VideoPlayerProps { src: string; @@ -9,6 +9,7 @@ interface VideoPlayerProps { currentTime: number; selectedAudioTrack?: SelectedTrack; selectedTextTrack?: SelectedTrack; + resizeMode?: ResizeMode; onProgress?: (data: { currentTime: number; playableDuration: number }) => void; onLoad?: (data: { duration: number }) => void; onError?: (error: any) => void; @@ -24,6 +25,7 @@ export const AndroidVideoPlayer: React.FC = ({ currentTime, selectedAudioTrack, selectedTextTrack, + resizeMode = 'contain' as ResizeMode, onProgress, onLoad, onError, @@ -93,7 +95,7 @@ export const AndroidVideoPlayer: React.FC = ({ onBuffer={handleBuffer} onError={handleError} onEnd={handleEnd} - resizeMode="contain" + resizeMode={resizeMode} controls={false} playInBackground={false} playWhenInactive={false} diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index 65f837c..06f4419 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -95,7 +95,7 @@ const AndroidVideoPlayer: React.FC = () => { const [selectedAudioTrack, setSelectedAudioTrack] = useState(null); const [textTracks, setTextTracks] = useState([]); const [selectedTextTrack, setSelectedTextTrack] = useState(-1); - const [resizeMode, setResizeMode] = useState('stretch'); + const [resizeMode, setResizeMode] = useState('contain'); const [buffered, setBuffered] = useState(0); const [seekTime, setSeekTime] = useState(null); const videoRef = useRef(null); @@ -526,13 +526,14 @@ const AndroidVideoPlayer: React.FC = () => { }; const cycleAspectRatio = () => { - const newZoom = zoomScale === 1.1 ? 1 : 1.1; - setZoomScale(newZoom); - setZoomTranslateX(0); - setZoomTranslateY(0); - setLastZoomScale(newZoom); - setLastTranslateX(0); - setLastTranslateY(0); + // Android: cycle through native resize modes + const resizeModes: ResizeModeType[] = ['contain', 'cover', 'stretch', 'none']; + const currentIndex = resizeModes.indexOf(resizeMode); + const nextIndex = (currentIndex + 1) % resizeModes.length; + setResizeMode(resizeModes[nextIndex]); + if (DEBUG_MODE) { + logger.log(`[AndroidVideoPlayer] Resize mode changed to: ${resizeModes[nextIndex]}`); + } }; const enableImmersiveMode = () => { @@ -1081,6 +1082,7 @@ const AndroidVideoPlayer: React.FC = () => { currentTime={currentTime} duration={duration} zoomScale={zoomScale} + currentResizeMode={resizeMode} vlcAudioTracks={rnVideoAudioTracks} selectedAudioTrack={selectedAudioTrack} availableStreams={availableStreams} diff --git a/src/components/player/VideoPlayer.tsx b/src/components/player/VideoPlayer.tsx index e62d453..7cdc442 100644 --- a/src/components/player/VideoPlayer.tsx +++ b/src/components/player/VideoPlayer.tsx @@ -388,7 +388,7 @@ const VideoPlayer: React.FC = () => { isSeeking.current = false; if (DEBUG_MODE) { logger.log(`[VideoPlayer] Android seek completed to ${timeInSeconds.toFixed(2)}s`); - } + } } }, 500); } else { @@ -659,11 +659,11 @@ const VideoPlayer: React.FC = () => { // If video is already loaded and ready, seek immediately if (isPlayerReady && duration > 0 && vlcRef.current) { - seekToTime(resumePosition); + seekToTime(resumePosition); } else { // Otherwise, set initial position for when video loads setInitialPosition(resumePosition); - } + } } }; diff --git a/src/components/player/controls/PlayerControls.tsx b/src/components/player/controls/PlayerControls.tsx index 3cc6054..12c26d0 100644 --- a/src/components/player/controls/PlayerControls.tsx +++ b/src/components/player/controls/PlayerControls.tsx @@ -20,6 +20,7 @@ interface PlayerControlsProps { currentTime: number; duration: number; zoomScale: number; + currentResizeMode?: string; vlcAudioTracks: Array<{id: number, name: string, language?: string}>; selectedAudioTrack: number | null; availableStreams?: { [providerId: string]: { streams: any[]; addonName: string } }; @@ -55,6 +56,7 @@ export const PlayerControls: React.FC = ({ currentTime, duration, zoomScale, + currentResizeMode, vlcAudioTracks, selectedAudioTrack, availableStreams, @@ -178,7 +180,11 @@ export const PlayerControls: React.FC = ({ - {zoomScale === 1.1 ? 'Fill' : 'Cover'} + {currentResizeMode ? + (currentResizeMode === 'none' ? 'Original' : + currentResizeMode.charAt(0).toUpperCase() + currentResizeMode.slice(1)) : + (zoomScale === 1.1 ? 'Fill' : 'Cover') + } diff --git a/src/hooks/useTraktIntegration.ts b/src/hooks/useTraktIntegration.ts index 2c1c506..1e818a0 100644 --- a/src/hooks/useTraktIntegration.ts +++ b/src/hooks/useTraktIntegration.ts @@ -369,10 +369,10 @@ export function useTraktIntegration() { updatePromises.push( storageService.mergeWithTraktProgress( - id, - type, - item.progress, - item.paused_at, + id, + type, + item.progress, + item.paused_at, episodeId, exactTime ) @@ -391,10 +391,10 @@ export function useTraktIntegration() { updatePromises.push( storageService.mergeWithTraktProgress( - id, - 'movie', - 100, // 100% progress for watched items - watchedAt + id, + 'movie', + 100, // 100% progress for watched items + watchedAt ) ); } diff --git a/src/services/storageService.ts b/src/services/storageService.ts index fc3b4f0..61d4982 100644 --- a/src/services/storageService.ts +++ b/src/services/storageService.ts @@ -147,7 +147,7 @@ class StorageService { // Only notify if we have subscribers if (this.watchProgressSubscribers.length > 0) { - this.watchProgressSubscribers.forEach(callback => callback()); + this.watchProgressSubscribers.forEach(callback => callback()); } } @@ -394,16 +394,16 @@ class StorageService { } } - const updatedProgress: WatchProgress = { + const updatedProgress: WatchProgress = { ...localProgress, currentTime, duration, - lastUpdated: traktTimestamp, - traktSynced: true, - traktLastSynced: Date.now(), - traktProgress - }; - await this.setWatchProgress(id, type, updatedProgress, episodeId); + lastUpdated: traktTimestamp, + traktSynced: true, + traktLastSynced: Date.now(), + traktProgress + }; + await this.setWatchProgress(id, type, updatedProgress, episodeId); // Only log significant changes if (progressDiff > 10 || traktProgress === 100) {