Sensitivity adjustments for videoplayers

This commit is contained in:
tapframe 2025-09-18 14:47:20 +05:30
parent 73b56bad4b
commit 532d6fb8a0
2 changed files with 103 additions and 39 deletions

View file

@ -37,6 +37,7 @@ import PlayerControls from './controls/PlayerControls';
import CustomSubtitles from './subtitles/CustomSubtitles';
import { SourcesModal } from './modals/SourcesModal';
import { stremioService } from '../../services/stremioService';
import { isMkvStream } from '../../utils/mkvDetection';
import axios from 'axios';
import * as Brightness from 'expo-brightness';
@ -440,15 +441,14 @@ const AndroidVideoPlayer: React.FC = () => {
// Volume gesture handler (right side of screen)
const onVolumeGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
const { translationY, state } = event.nativeEvent;
const screenHeight = screenDimensions.height;
const sensitivity = 0.002; // Reduced for finer control
const sensitivity = 0.002; // Lower sensitivity for gradual volume control on Android
if (state === State.ACTIVE) {
const deltaY = -translationY; // Invert for natural feel (up = increase)
const volumeChange = deltaY * sensitivity;
const newVolume = Math.max(0, Math.min(1, volume + volumeChange));
if (Math.abs(newVolume - volume) > 0.005) { // Reduced threshold for smoother updates
if (Math.abs(newVolume - volume) > 0.01) { // Lower threshold for smoother Android volume control
setVolume(newVolume);
lastVolumeChange.current = Date.now();
@ -489,15 +489,14 @@ const AndroidVideoPlayer: React.FC = () => {
// Brightness gesture handler (left side of screen)
const onBrightnessGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
const { translationY, state } = event.nativeEvent;
const screenHeight = screenDimensions.height;
const sensitivity = 0.002; // Reduced for finer control
const sensitivity = 0.001; // Lower sensitivity for finer brightness control
if (state === State.ACTIVE) {
const deltaY = -translationY; // Invert for natural feel (up = increase)
const brightnessChange = deltaY * sensitivity;
const newBrightness = Math.max(0, Math.min(1, brightness + brightnessChange));
if (Math.abs(newBrightness - brightness) > 0.005) { // Reduced threshold for smoother updates
if (Math.abs(newBrightness - brightness) > 0.001) { // Much lower threshold for more responsive updates
setBrightness(newBrightness);
lastBrightnessChange.current = Date.now();
@ -2556,6 +2555,38 @@ const AndroidVideoPlayer: React.FC = () => {
return;
}
// On iOS: if the selected stream is MKV, switch to KSPlayer screen by replacing route
if (Platform.OS === 'ios') {
const targetIsMkv = isMkvStream(newStream.url, newStream.headers || {});
if (targetIsMkv) {
// Ensure current player stops immediately before switching screens
setPaused(true);
setShowSourcesModal(false);
// Small delay to guarantee audio halt before navigation switch
setTimeout(() => {
(navigation as any).replace('Player', {
uri: newStream.url,
title,
episodeTitle,
season,
episode,
quality: (newStream.title?.match(/(\d+)p/) || [])[1] || newStream.quality,
year,
streamProvider: newStream.addonName || newStream.name || newStream.addon || 'Unknown',
streamName: newStream.name || newStream.title || 'Unknown Stream',
headers: newStream.headers || undefined,
id,
type,
episodeId,
imdbId,
backdrop,
availableStreams,
});
}, 50);
return;
}
}
setIsChangingSource(true);
setShowSourcesModal(false);
@ -2768,10 +2799,11 @@ const AndroidVideoPlayer: React.FC = () => {
{/* Combined gesture handler for left side - brightness + tap */}
<PanGestureHandler
onGestureEvent={onBrightnessGestureEvent}
activeOffsetY={[-10, 10]}
failOffsetX={[-50, 50]}
shouldCancelWhenOutside={true}
activeOffsetY={[-5, 5]}
failOffsetX={[-20, 20]}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
maxPointers={1}
>
<TapGestureHandler
onActivated={toggleControls}
@ -2792,10 +2824,11 @@ const AndroidVideoPlayer: React.FC = () => {
{/* Combined gesture handler for right side - volume + tap */}
<PanGestureHandler
onGestureEvent={onVolumeGestureEvent}
activeOffsetY={[-10, 10]}
failOffsetX={[-50, 50]}
shouldCancelWhenOutside={true}
activeOffsetY={[-5, 5]}
failOffsetX={[-20, 20]}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
maxPointers={1}
>
<TapGestureHandler
onActivated={toggleControls}

View file

@ -413,18 +413,17 @@ const VideoPlayer: React.FC = () => {
// Volume gesture handler (right side of screen)
const onVolumeGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
const { translationY, state } = event.nativeEvent;
const screenHeight = screenDimensions.height;
const sensitivity = 0.002; // Reduced for finer control
const sensitivity = 0.050; // Higher sensitivity for volume (more responsive than brightness)
if (state === State.ACTIVE) {
const deltaY = -translationY; // Invert for natural feel (up = increase)
const volumeChange = deltaY * sensitivity;
const newVolume = Math.max(0, Math.min(100, volume + volumeChange));
if (Math.abs(newVolume - volume) > 0.5) { // Reduced threshold for smoother updates
if (Math.abs(newVolume - volume) > 0.05) { // Even lower threshold for volume responsiveness
setVolume(newVolume);
lastVolumeChange.current = Date.now();
// Show overlay with smoother animation
if (!showVolumeOverlay) {
setShowVolumeOverlay(true);
@ -435,12 +434,12 @@ const VideoPlayer: React.FC = () => {
useNativeDriver: true,
}).start();
}
// Clear existing timeout
if (volumeOverlayTimeout.current) {
clearTimeout(volumeOverlayTimeout.current);
}
// Hide overlay after 1.5 seconds
volumeOverlayTimeout.current = setTimeout(() => {
Animated.timing(volumeOverlayOpacity, {
@ -458,18 +457,17 @@ const VideoPlayer: React.FC = () => {
// Brightness gesture handler (left side of screen)
const onBrightnessGestureEvent = async (event: PanGestureHandlerGestureEvent) => {
const { translationY, state } = event.nativeEvent;
const screenHeight = screenDimensions.height;
const sensitivity = 0.002; // Reduced for finer control
const sensitivity = 0.001; // Lower sensitivity for finer brightness control
if (state === State.ACTIVE) {
const deltaY = -translationY; // Invert for natural feel (up = increase)
const brightnessChange = deltaY * sensitivity;
const newBrightness = Math.max(0, Math.min(1, brightness + brightnessChange));
if (Math.abs(newBrightness - brightness) > 0.005) { // Reduced threshold for smoother updates
if (Math.abs(newBrightness - brightness) > 0.001) { // Much lower threshold for more responsive updates
setBrightness(newBrightness);
lastBrightnessChange.current = Date.now();
// Set device brightness using Expo Brightness
try {
await Brightness.setBrightnessAsync(newBrightness);
@ -479,7 +477,7 @@ const VideoPlayer: React.FC = () => {
} catch (error) {
logger.warn('[VideoPlayer] Error setting device brightness:', error);
}
// Show overlay with smoother animation
if (!showBrightnessOverlay) {
setShowBrightnessOverlay(true);
@ -490,12 +488,12 @@ const VideoPlayer: React.FC = () => {
useNativeDriver: true,
}).start();
}
// Clear existing timeout
if (brightnessOverlayTimeout.current) {
clearTimeout(brightnessOverlayTimeout.current);
}
// Hide overlay after 1.5 seconds (reduced from 2 seconds)
brightnessOverlayTimeout.current = setTimeout(() => {
Animated.timing(brightnessOverlayOpacity, {
@ -2224,6 +2222,37 @@ const VideoPlayer: React.FC = () => {
return;
}
// On iOS: if the selected stream is NOT MKV, switch to AndroidVideoPlayer screen by replacing route
if (Platform.OS === 'ios') {
const targetIsMkv = isMkvStream(newStream.url, newStream.headers || {});
if (!targetIsMkv) {
// Ensure KSPlayer stops immediately before switching screens
setPaused(true);
setShowSourcesModal(false);
setTimeout(() => {
navigation.replace('Player', {
uri: newStream.url,
title,
episodeTitle,
season,
episode,
quality: (newStream.title?.match(/(\d+)p/) || [])[1] || newStream.quality,
year,
streamProvider: newStream.addonName || newStream.name || newStream.addon || 'Unknown',
streamName: newStream.name || newStream.title || 'Unknown Stream',
headers: newStream.headers || undefined,
id,
type,
episodeId,
imdbId,
backdrop,
availableStreams,
} as any);
}, 50);
return;
}
}
setIsChangingSource(true);
setShowSourcesModal(false);
@ -2449,10 +2478,11 @@ const VideoPlayer: React.FC = () => {
{/* Combined gesture handler for left side - brightness + tap */}
<PanGestureHandler
onGestureEvent={onBrightnessGestureEvent}
activeOffsetY={[-10, 10]}
failOffsetX={[-50, 50]}
shouldCancelWhenOutside={true}
activeOffsetY={[-5, 5]}
failOffsetX={[-20, 20]}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
maxPointers={1}
>
<TapGestureHandler
onActivated={toggleControls}
@ -2473,10 +2503,11 @@ const VideoPlayer: React.FC = () => {
{/* Combined gesture handler for right side - volume + tap */}
<PanGestureHandler
onGestureEvent={onVolumeGestureEvent}
activeOffsetY={[-10, 10]}
failOffsetX={[-50, 50]}
shouldCancelWhenOutside={true}
activeOffsetY={[-5, 5]}
failOffsetX={[-20, 20]}
shouldCancelWhenOutside={false}
simultaneousHandlers={[]}
maxPointers={1}
>
<TapGestureHandler
onActivated={toggleControls}