nextav/docs/archive/UI-IMPLEMENTATION-PLAN.md

2.9 KiB

UI Implementation Plan: Duration and Progress Bar Fixes

🎯 Goal

Fix two critical UI issues:

  1. Duration showing buffered duration instead of real video duration
  2. Progress bar jumping backwards during buffering

🔍 Root Cause

  • Duration Issue: Video metadata events fire before real duration is loaded
  • Progress Issue: Browser buffering reports backward timestamps

🏗️ Solution Strategy

1. Duration Protection Hook

// hooks/use-protected-duration.ts
export const useProtectedDuration = (videoId: string) => {
  const [duration, setDuration] = useState(0);
  const hasRealDuration = useRef(false);
  
  // Priority: Database > Headers > Video Metadata
  const fetchRealDuration = async () => {
    // 1. Try database first
    const dbDuration = await getStoredDuration(videoId);
    if (dbDuration > 0) {
      setDuration(dbDuration);
      hasRealDuration.current = true;
      return;
    }
    
    // 2. Try transcoding headers
    const headerDuration = await getHeaderDuration(videoId);
    if (headerDuration > 0) {
      setDuration(headerDuration);
      hasRealDuration.current = true;
    }
  };
  
  // Block metadata duration if we have real duration
  const handleDurationChange = (newDuration: number) => {
    if (hasRealDuration.current) {
      return; // Keep real duration
    }
    // Only accept significantly larger durations
    if (newDuration > duration * 2.0) {
      setDuration(newDuration);
    }
  };
  
  return { duration, handleDurationChange };
};

2. Stable Progress Hook

// hooks/use-stable-progress.ts
export const useStableProgress = (videoRef: RefObject<HTMLVideoElement>) => {
  const [currentTime, setCurrentTime] = useState(0);
  const lastStableTime = useRef(0);
  
  const handleTimeUpdate = () => {
    if (!videoRef.current) return;
    
    const newTime = videoRef.current.currentTime;
    
    // Prevent backward jumps
    if (newTime < lastStableTime.current - 0.1) {
      console.log(`[PROGRESS] Blocked backward jump: ${newTime}s -> ${lastStableTime.current}s`);
      return;
    }
    
    setCurrentTime(newTime);
    lastStableTime.current = newTime;
  };
  
  return { currentTime, handleTimeUpdate };
};

📋 Implementation Steps

Day 1: Create Hooks

  • Create use-protected-duration.ts
  • Create use-stable-progress.ts
  • Test hooks independently

Day 2: Update Video Viewer

  • Remove old duration/progress logic
  • Integrate new hooks
  • Test duration protection

Day 3: Test and Debug

  • Test with direct videos
  • Test with transcoded streams
  • Verify no backward jumps

🎯 Expected Results

  • Duration always shows real video length (9 min, not 6 sec)
  • Progress bar never jumps backward
  • Professional streaming experience
  • Simple, maintainable code

🚀 Next Steps

After UI fixes, implement FFmpeg process management for seek optimization.