This commit is contained in:
tapframe 2025-12-22 21:40:11 +05:30
parent 19438ff1d5
commit 9504d48607
7 changed files with 64 additions and 49 deletions

View file

@ -145,7 +145,9 @@ class MPVView @JvmOverloads constructor(
}
fun seekTo(positionSeconds: Double) {
Log.d(TAG, "seekTo called: positionSeconds=$positionSeconds, isMpvInitialized=$isMpvInitialized")
if (isMpvInitialized) {
Log.d(TAG, "Executing MPV seek command: seek $positionSeconds absolute")
MPVLib.command(arrayOf("seek", positionSeconds.toString(), "absolute"))
}
}

View file

@ -84,9 +84,12 @@ class MpvPlayerViewManager(
}
override fun receiveCommand(view: MPVView, commandId: String?, args: ReadableArray?) {
android.util.Log.d("MpvPlayerViewManager", "receiveCommand: $commandId, args: $args")
when (commandId) {
"seek" -> {
args?.getDouble(0)?.let { view.seekTo(it) }
val position = args?.getDouble(0)
android.util.Log.d("MpvPlayerViewManager", "Seek command received: position=$position")
position?.let { view.seekTo(it) }
}
"setAudioTrack" -> {
args?.getInt(0)?.let { view.setAudioTrack(it) }

View file

@ -40,6 +40,7 @@ import { ErrorModal } from './modals/ErrorModal';
// Android-specific components
import { VideoSurface } from './android/components/VideoSurface';
import { MpvPlayerRef } from './android/MpvPlayer';
// Utils
import { logger } from '../../utils/logger';
@ -75,6 +76,7 @@ const AndroidVideoPlayer: React.FC = () => {
const useVLC = (Platform.OS === 'android' && forceVlc);
const videoRef = useRef<any>(null);
const mpvPlayerRef = useRef<MpvPlayerRef>(null);
const vlcHook = useVlcPlayer(useVLC, playerState.paused, playerState.currentTime);
const tracksHook = usePlayerTracks(
useVLC,
@ -103,7 +105,7 @@ const AndroidVideoPlayer: React.FC = () => {
const setupHook = usePlayerSetup(playerState.setScreenDimensions, setVolume, setBrightness, playerState.paused);
const controlsHook = usePlayerControls(
videoRef,
mpvPlayerRef, // Use mpvPlayerRef for MPV player
vlcHook.vlcPlayerRef,
useVLC,
playerState.paused,
@ -168,6 +170,13 @@ const AndroidVideoPlayer: React.FC = () => {
if (!playerState.isMounted.current) return;
const videoDuration = data.duration;
console.log('[AndroidVideoPlayer] handleLoad called:', {
duration: videoDuration,
initialPosition: watchProgress.initialPosition,
showResumeOverlay: watchProgress.showResumeOverlay,
initialSeekTarget: watchProgress.initialSeekTargetRef?.current
});
if (videoDuration > 0) {
playerState.setDuration(videoDuration);
if (id && type) {
@ -204,9 +213,17 @@ const AndroidVideoPlayer: React.FC = () => {
playerState.setIsVideoLoaded(true);
openingAnimation.completeOpeningAnimation();
// Handle Resume
if (watchProgress.initialPosition && !watchProgress.showResumeOverlay) {
controlsHook.seekToTime(watchProgress.initialPosition);
// Handle Resume - check both initialPosition and initialSeekTargetRef
const resumeTarget = watchProgress.initialPosition || watchProgress.initialSeekTargetRef?.current;
if (resumeTarget && resumeTarget > 0 && !watchProgress.showResumeOverlay && videoDuration > 0) {
console.log('[AndroidVideoPlayer] Seeking to resume position:', resumeTarget, 'duration:', videoDuration);
// Use a small delay to ensure the player is ready, then seek directly
setTimeout(() => {
if (mpvPlayerRef.current) {
console.log('[AndroidVideoPlayer] Calling mpvPlayerRef.current.seek directly');
mpvPlayerRef.current.seek(Math.min(resumeTarget, videoDuration - 0.5));
}
}, 200);
}
}, [id, type, episodeId, useVLC, playerState.isMounted, watchProgress.initialPosition]);
@ -385,6 +402,7 @@ const AndroidVideoPlayer: React.FC = () => {
onBuffer={(buf) => playerState.setIsBuffering(buf.isBuffering)}
onTracksUpdate={vlcHook.handleVlcTracksUpdate}
vlcPlayerRef={vlcHook.vlcPlayerRef}
mpvPlayerRef={mpvPlayerRef}
videoRef={videoRef}
pinchRef={useRef(null)}
onPinchGestureEvent={() => { }}

View file

@ -59,12 +59,7 @@ const MpvPlayer = forwardRef<MpvPlayerRef, MpvPlayerProps>((props, ref) => {
);
}
console.log('[MpvPlayer] Rendering native component with:', {
source: props.source?.substring(0, 50) + '...',
paused: props.paused ?? true,
volume: props.volume ?? 1.0,
rate: props.rate ?? 1.0,
});
// Debug logging removed to prevent console spam
const handleLoad = (event: any) => {
console.log('[MpvPlayer] Native onLoad event:', event?.nativeEvent);
@ -72,11 +67,7 @@ const MpvPlayer = forwardRef<MpvPlayerRef, MpvPlayerProps>((props, ref) => {
};
const handleProgress = (event: any) => {
const data = event?.nativeEvent;
if (data && Math.floor(data.currentTime) % 5 === 0) {
console.log('[MpvPlayer] Native onProgress event:', data);
}
props.onProgress?.(data);
props.onProgress?.(event?.nativeEvent);
};
const handleEnd = (event: any) => {

View file

@ -1,10 +1,9 @@
import React from 'react';
import React, { useCallback, memo } from 'react';
import { View, TouchableWithoutFeedback, StyleSheet } from 'react-native';
import { PinchGestureHandler } from 'react-native-gesture-handler';
import MpvPlayer, { MpvPlayerRef } from '../MpvPlayer';
import { styles } from '../../utils/playerStyles';
import { ResizeModeType } from '../../utils/playerTypes';
import { logger } from '../../../../utils/logger';
interface VideoSurfaceProps {
processedStreamUrl: string;
@ -77,13 +76,7 @@ export const VideoSurface: React.FC<VideoSurfaceProps> = ({
// Use the actual stream URL
const streamUrl = currentStreamUrl || processedStreamUrl;
console.log('[VideoSurface] Rendering with:', {
streamUrl: streamUrl?.substring(0, 50) + '...',
paused,
volume,
playbackSpeed,
screenDimensions,
});
// Debug logging removed to prevent console spam
const handleLoad = (data: { duration: number; width: number; height: number }) => {
console.log('[VideoSurface] onLoad received:', data);
@ -97,10 +90,6 @@ export const VideoSurface: React.FC<VideoSurfaceProps> = ({
};
const handleProgress = (data: { currentTime: number; duration: number }) => {
// Log every 5 seconds to avoid spam
if (Math.floor(data.currentTime) % 5 === 0) {
console.log('[VideoSurface] onProgress:', data);
}
onProgress({
currentTime: data.currentTime,
playableDuration: data.currentTime,

View file

@ -2,11 +2,11 @@ import { useRef, useCallback } from 'react';
import { Platform } from 'react-native';
import { logger } from '../../../../utils/logger';
const DEBUG_MODE = false;
const DEBUG_MODE = true; // Temporarily enable for debugging seek
const END_EPSILON = 0.3;
export const usePlayerControls = (
videoRef: any,
mpvPlayerRef: any,
vlcPlayerRef: any,
useVLC: boolean,
paused: boolean,
@ -26,39 +26,46 @@ export const usePlayerControls = (
const seekToTime = useCallback((rawSeconds: number) => {
const timeInSeconds = Math.max(0, Math.min(rawSeconds, duration > 0 ? duration - END_EPSILON : rawSeconds));
console.log('[usePlayerControls] seekToTime called:', {
rawSeconds,
timeInSeconds,
useVLC,
hasMpvRef: !!mpvPlayerRef?.current,
hasVlcRef: !!vlcPlayerRef?.current,
duration,
isSeeking: isSeeking.current
});
if (useVLC) {
if (vlcPlayerRef.current && duration > 0) {
if (DEBUG_MODE) logger.log(`[usePlayerControls][VLC] Seeking to ${timeInSeconds}`);
logger.log(`[usePlayerControls][VLC] Seeking to ${timeInSeconds}`);
vlcPlayerRef.current.seek(timeInSeconds);
}
} else {
if (videoRef.current && duration > 0 && !isSeeking.current) {
if (DEBUG_MODE) logger.log(`[usePlayerControls] Seeking to ${timeInSeconds}`);
// MPV Player
if (mpvPlayerRef.current && duration > 0) {
console.log(`[usePlayerControls][MPV] Seeking to ${timeInSeconds}`);
isSeeking.current = true;
mpvPlayerRef.current.seek(timeInSeconds);
if (Platform.OS === 'ios') {
iosWasPausedDuringSeekRef.current = paused;
if (!paused) setPaused(true);
}
// Actually perform the seek
videoRef.current.seek(timeInSeconds);
// Reset seeking flag after a delay
setTimeout(() => {
if (isMounted.current && isSeeking.current) {
if (isMounted.current) {
isSeeking.current = false;
if (Platform.OS === 'ios' && iosWasPausedDuringSeekRef.current === false) {
setPaused(false);
iosWasPausedDuringSeekRef.current = null;
}
}
}, 500);
} else {
console.log('[usePlayerControls][MPV] Cannot seek - ref or duration invalid:', {
hasRef: !!mpvPlayerRef?.current,
duration
});
}
}
}, [useVLC, duration, paused, setPaused, videoRef, vlcPlayerRef, isSeeking, isMounted]);
}, [useVLC, duration, paused, setPaused, mpvPlayerRef, vlcPlayerRef, isSeeking, isMounted]);
const skip = useCallback((seconds: number) => {
console.log('[usePlayerControls] skip called:', { seconds, currentTime, newTime: currentTime + seconds });
seekToTime(currentTime + seconds);
}, [currentTime, seekToTime]);

View file

@ -40,17 +40,22 @@ export const useWatchProgress = (
if (id && type) {
try {
const savedProgress = await storageService.getWatchProgress(id, type, episodeId);
console.log('[useWatchProgress] Loaded saved progress:', savedProgress);
if (savedProgress) {
const progressPercent = (savedProgress.currentTime / savedProgress.duration) * 100;
console.log('[useWatchProgress] Progress percent:', progressPercent);
if (progressPercent < 85) {
setResumePosition(savedProgress.currentTime);
setSavedDuration(savedProgress.duration);
if (appSettings.alwaysResume) {
console.log('[useWatchProgress] Always resume enabled, setting initial position:', savedProgress.currentTime);
setInitialPosition(savedProgress.currentTime);
initialSeekTargetRef.current = savedProgress.currentTime;
seekToTime(savedProgress.currentTime);
// Don't call seekToTime here - duration is 0
// The seek will be handled in handleLoad callback
} else {
setShowResumeOverlay(true);
}