elearning/docs/api-docs/api_video_progress.md

3.8 KiB

Video Progress Tracking - API Usage Examples

Save Video Progress

POST /students/lessons/:lessonId/progress

Purpose: บันทึกตำแหน่งการดูวีดีโอ (เรียกทุก 5 วินาที)

Request:

POST /api/students/lessons/5/progress
Authorization: Bearer <token>
Content-Type: application/json

{
  "progress_seconds": 450,
  "duration_seconds": 900
}

Response 200:

{
  "lesson_id": 5,
  "video_progress_seconds": 450,
  "video_duration_seconds": 900,
  "video_progress_percentage": 50.00,
  "is_completed": false,
  "last_watched_at": "2024-12-24T14:00:00Z"
}

Auto-Complete (90%+):

{
  "progress_seconds": 810,
  "duration_seconds": 900
}

Response:

{
  "lesson_id": 5,
  "video_progress_seconds": 810,
  "video_duration_seconds": 900,
  "video_progress_percentage": 90.00,
  "is_completed": true,
  "completed_at": "2024-12-24T14:05:00Z"
}

Get Video Progress

GET /students/lessons/:lessonId/progress

Purpose: ดึงตำแหน่งการดูวีดีโอเพื่อเล่นต่อ

Request:

GET /api/students/lessons/5/progress
Authorization: Bearer <token>

Response 200 (Has Progress):

{
  "lesson_id": 5,
  "video_progress_seconds": 450,
  "video_duration_seconds": 900,
  "video_progress_percentage": 50.00,
  "is_completed": false,
  "last_watched_at": "2024-12-24T13:30:00Z"
}

Response 200 (No Progress):

{
  "lesson_id": 5,
  "video_progress_seconds": 0,
  "video_duration_seconds": null,
  "video_progress_percentage": 0,
  "is_completed": false,
  "last_watched_at": null
}

Frontend Integration

const VideoPlayer = ({ lessonId, videoUrl }) => {
  const videoRef = useRef(null);
  
  // Load saved progress
  useEffect(() => {
    async function loadProgress() {
      const res = await fetch(`/api/students/lessons/${lessonId}/progress`);
      const data = await res.json();
      
      if (data.video_progress_seconds > 0) {
        videoRef.current.currentTime = data.video_progress_seconds;
      }
    }
    loadProgress();
  }, [lessonId]);
  
  // Save progress every 5 seconds
  useEffect(() => {
    const interval = setInterval(() => {
      if (videoRef.current && !videoRef.current.paused) {
        saveProgress(
          Math.floor(videoRef.current.currentTime),
          Math.floor(videoRef.current.duration)
        );
      }
    }, 5000);
    
    return () => clearInterval(interval);
  }, []);
  
  async function saveProgress(currentTime, duration) {
    await fetch(`/api/students/lessons/${lessonId}/progress`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        progress_seconds: currentTime,
        duration_seconds: duration
      })
    });
  }
  
  return <video ref={videoRef} src={videoUrl} controls />;
};

Modified Endpoints

GET /students/courses/:courseId/learn

Added: video_progress_percentage และ resume_from ในแต่ละ lesson

{
  "lessons": [
    {
      "id": 1,
      "title": "Lesson 1",
      "type": "video",
      "is_completed": true,
      "video_progress_percentage": 100
    },
    {
      "id": 2,
      "title": "Lesson 2",
      "type": "video",
      "is_completed": false,
      "video_progress_percentage": 50,
      "resume_from": 450
    }
  ]
}

GET /students/courses/:courseId/progress

Added: recently_watched section

{
  "course_id": 1,
  "progress_percentage": 30,
  "recently_watched": [
    {
      "lesson_id": 2,
      "title": "Lesson 2",
      "video_progress_percentage": 50,
      "last_watched_at": "2024-12-24T14:00:00Z"
    }
  ]
}