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.
This commit is contained in:
tapframe 2025-06-21 15:49:43 +05:30
parent 0ab9ce19c0
commit 1605d5251e
6 changed files with 40 additions and 30 deletions

View file

@ -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<VideoPlayerProps> = ({
currentTime,
selectedAudioTrack,
selectedTextTrack,
resizeMode = 'contain' as ResizeMode,
onProgress,
onLoad,
onError,
@ -93,7 +95,7 @@ export const AndroidVideoPlayer: React.FC<VideoPlayerProps> = ({
onBuffer={handleBuffer}
onError={handleError}
onEnd={handleEnd}
resizeMode="contain"
resizeMode={resizeMode}
controls={false}
playInBackground={false}
playWhenInactive={false}

View file

@ -95,7 +95,7 @@ const AndroidVideoPlayer: React.FC = () => {
const [selectedAudioTrack, setSelectedAudioTrack] = useState<number | null>(null);
const [textTracks, setTextTracks] = useState<TextTrack[]>([]);
const [selectedTextTrack, setSelectedTextTrack] = useState<number>(-1);
const [resizeMode, setResizeMode] = useState<ResizeModeType>('stretch');
const [resizeMode, setResizeMode] = useState<ResizeModeType>('contain');
const [buffered, setBuffered] = useState(0);
const [seekTime, setSeekTime] = useState<number | null>(null);
const videoRef = useRef<VideoRef>(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}

View file

@ -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<PlayerControlsProps> = ({
currentTime,
duration,
zoomScale,
currentResizeMode,
vlcAudioTracks,
selectedAudioTrack,
availableStreams,
@ -178,7 +180,11 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
<TouchableOpacity style={styles.bottomButton} onPress={cycleAspectRatio}>
<Ionicons name="resize" size={20} color="white" />
<Text style={[styles.bottomButtonText, { fontSize: 14, textAlign: 'center' }]}>
{zoomScale === 1.1 ? 'Fill' : 'Cover'}
{currentResizeMode ?
(currentResizeMode === 'none' ? 'Original' :
currentResizeMode.charAt(0).toUpperCase() + currentResizeMode.slice(1)) :
(zoomScale === 1.1 ? 'Fill' : 'Cover')
}
</Text>
</TouchableOpacity>