From de576915d554da83578c6092631047b3be299202 Mon Sep 17 00:00:00 2001 From: tapframe <85391825+tapframe@users.noreply.github.com> Date: Tue, 27 Jan 2026 00:41:53 +0530 Subject: [PATCH] added buffer indicator --- src/components/player/AndroidVideoPlayer.tsx | 14 ++++++++++-- src/components/player/KSPlayerCore.tsx | 22 +++++++++++++++---- .../player/controls/PlayerControls.tsx | 20 +++++++++++------ src/components/player/utils/playerStyles.ts | 2 +- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index cd3bbd46..f260021c 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -1,5 +1,5 @@ import React, { useRef, useEffect, useMemo, useCallback, useState } from 'react'; -import { View, StyleSheet, Platform, Animated, ToastAndroid } from 'react-native'; +import { View, StyleSheet, Platform, Animated, ToastAndroid, ActivityIndicator } from 'react-native'; import { toast } from '@backpackapp-io/react-native-toast'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useNavigation, useRoute, RouteProp } from '@react-navigation/native'; @@ -787,7 +787,9 @@ const AndroidVideoPlayer: React.FC = () => { modals.setErrorDetails(displayError); modals.setShowErrorModal(true); }} - onBuffer={(buf) => playerState.setIsBuffering(buf.isBuffering)} + onBuffer={(buf) => { + playerState.setIsBuffering(buf.isBuffering); + }} onTracksChanged={(data) => { console.log('[AndroidVideoPlayer] onTracksChanged:', data); if (data?.audioTracks) { @@ -879,6 +881,13 @@ const AndroidVideoPlayer: React.FC = () => { formatTime={formatTime} /> + {/* Buffering Indicator (Visible when controls are hidden) */} + {playerState.isBuffering && !playerState.showControls && ( + + + + )} + { playerBackend={useExoPlayer ? 'ExoPlayer' : 'MPV'} onSwitchToMPV={handleManualSwitchToMPV} useExoPlayer={useExoPlayer} + isBuffering={playerState.isBuffering} /> { await traktAutosync.handlePlaybackEnd(duration, duration, 'ended'); }} onError={handleError} - onBuffer={setIsBuffering} + onBuffer={(b) => { + setIsBuffering(b); + }} onReadyForDisplay={() => setIsPlayerReady(true)} - onPlaybackStalled={() => setIsBuffering(true)} - onPlaybackResume={() => setIsBuffering(false)} + onPlaybackStalled={() => { + setIsBuffering(true); + }} + onPlaybackResume={() => { + setIsBuffering(false); + }} screenWidth={screenDimensions.width} screenHeight={screenDimensions.height} customVideoStyles={{ width: '100%', height: '100%' }} @@ -817,6 +823,13 @@ const KSPlayerCore: React.FC = () => { {/* UI Controls */} {isVideoLoaded && ( + {/* Buffering Indicator (Visible when controls are hidden) */} + {isBuffering && !showControls && ( + + + + )} + { isAirPlayActive={isAirPlayActive} allowsAirPlay={allowsAirPlay} onAirPlayPress={() => ksPlayerRef.current?.showAirPlayPicker()} + isBuffering={isBuffering} /> )} diff --git a/src/components/player/controls/PlayerControls.tsx b/src/components/player/controls/PlayerControls.tsx index eb7ad749..9ff3eb08 100644 --- a/src/components/player/controls/PlayerControls.tsx +++ b/src/components/player/controls/PlayerControls.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { View, Text, TouchableOpacity, Animated, StyleSheet, Platform, Dimensions } from 'react-native'; +import { View, Text, TouchableOpacity, Animated, StyleSheet, Platform, Dimensions, ActivityIndicator } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import Feather from 'react-native-vector-icons/Feather'; import { LinearGradient } from 'expo-linear-gradient'; @@ -54,6 +54,7 @@ interface PlayerControlsProps { // MPV Switch (Android only) onSwitchToMPV?: () => void; useExoPlayer?: boolean; + isBuffering?: boolean; } export const PlayerControls: React.FC = ({ @@ -98,6 +99,7 @@ export const PlayerControls: React.FC = ({ onAirPlayPress, onSwitchToMPV, useExoPlayer, + isBuffering = false, }) => { const { currentTheme } = useTheme(); const { t } = useTranslation(); @@ -463,7 +465,7 @@ export const PlayerControls: React.FC = ({ = ({ transform: [{ scale: playIconScale }], opacity: playIconOpacity }}> - + {isBuffering ? ( + + ) : ( + + )} diff --git a/src/components/player/utils/playerStyles.ts b/src/components/player/utils/playerStyles.ts index a4418e84..35dd6f7c 100644 --- a/src/components/player/utils/playerStyles.ts +++ b/src/components/player/utils/playerStyles.ts @@ -23,7 +23,7 @@ const qualityPadH = isTV ? 10 : isLargeTablet ? 9 : isTablet ? 8 : 8; const qualityPadV = isTV ? 4 : isLargeTablet ? 3 : isTablet ? 3 : 2; const qualityRadius = isTV ? 6 : isLargeTablet ? 5 : isTablet ? 4 : 4; const qualityTextFont = isTV ? 13 : isLargeTablet ? 12 : isTablet ? 11 : 11; -const controlsGap = isTV ? 56 : isLargeTablet ? 48 : isTablet ? 44 : 40; +const controlsGap = isTV ? 140 : isLargeTablet ? 110 : isTablet ? 90 : 70; const controlsTranslateY = isTV ? -48 : isLargeTablet ? -42 : isTablet ? -36 : -30; const skipTextFont = isTV ? 14 : isLargeTablet ? 13 : isTablet ? 12 : 12; const sliderBottom = isTV ? 60 : isLargeTablet ? 50 : isTablet ? 45 : 35;