Files
KVideo/IMPLEMENTATION.md
T
2025-11-16 10:49:55 +08:00

12 KiB

KVideo Platform - Implementation Guide

Overview

KVideo is a Next.js-based video aggregation platform that fetches content from multiple third-party APIs, provides intelligent source switching, and implements advanced M3U8 ad filtering for seamless video playback.

Architecture

1. Core Type System (lib/types/)

Purpose: Centralized TypeScript type definitions for the entire application.

Key Types:

  • VideoSource: Configuration for third-party API sources
  • VideoItem: Search result structure
  • VideoDetail: Full video information with episodes
  • PlayerState: Current playback state
  • VideoHistoryItem: Viewing history with progress
  • ApiResponse: Standardized API response formats

2. API Layer

lib/api/video-sources.ts

Manages video source configuration:

  • Stores multiple API endpoints with headers
  • Validates source configurations
  • Health checks for source availability
  • Custom source management via localStorage
  • Priority-based source ordering

Key Functions:

  • getAllSources(): Get all available sources
  • getEnabledSources(): Get enabled sources sorted by priority
  • healthCheckSource(source): Test source availability and response time
  • addCustomSource(source): Add user-defined API sources

lib/api/client.ts

HTTP client for video data fetching:

  • Parallel requests to multiple sources
  • 15-second timeout with abort controller
  • 3-attempt retry mechanism with exponential backoff
  • Response normalization across different API formats
  • M3U8 URL extraction from various formats

Key Functions:

  • searchVideos(query, sources, page): Search across multiple sources
  • getVideoDetail(id, source): Fetch video details with episodes
  • testVideoUrl(url): Check video URL accessibility
  • normalizeVideoData(data, sourceId): Standardize API responses

3. Server API Routes

app/api/search/route.ts

Handles video search requests:

  • POST and GET endpoints
  • Validates query and source parameters
  • Aggregates results from multiple sources
  • Returns merged results with source attribution

Request Format:

{
  "query": "search term",
  "sources": ["source_1", "source_2"],
  "page": 1
}

Response Format:

{
  "success": true,
  "query": "search term",
  "page": 1,
  "sources": [
    {
      "results": [...],
      "source": "source_1",
      "responseTime": 234
    }
  ],
  "totalResults": 42
}

app/api/detail/route.ts

Fetches video details:

  • GET and POST endpoints
  • Extracts episode lists and M3U8 URLs
  • Supports custom API URLs
  • Returns structured video data with episodes

Query Parameters:

  • id: Video ID
  • source: Source identifier
  • customApi: (Optional) Custom API URL

4. State Management

lib/store/player-store.ts (Zustand)

Manages video playback state:

State: {
  currentVideo: { id, title, url, source, episodeIndex }
  episodes: Episode[]
  playbackPosition: number
  duration: number
  isPlaying: boolean
  autoplayNext: boolean
  volume: number (0-1)
  playbackRate: number
}

Actions: {
  setVideo(video)
  updatePosition(position)
  nextEpisode() // Returns next episode or null
  prevEpisode() // Returns previous episode or null
  toggleAutoplay()
  setVolume(volume)
  setPlaybackRate(rate)
}

Persistence: Saves volume, playback rate, and autoplay settings to localStorage.

lib/store/history-store.ts (Zustand)

Manages viewing history:

  • Stores last 50 watched videos
  • Deduplicates by show identifier
  • Updates progress and timestamp
  • Moves recently watched to top
  • Persists to localStorage

Key Functions:

  • addToHistory(...): Add or update history entry
  • updateProgress(videoId, source, episodeIndex, position, duration)
  • getHistoryItem(videoId, source): Retrieve specific history entry
  • clearHistory(): Clear all history

5. Utility Modules

lib/utils/progress-tracker.ts

LocalStorage-based progress management:

  • Auto-saves progress every 5 seconds (throttled)
  • Skips if position < 10s or video almost finished (< 2min remaining)
  • Clears progress when video completes
  • Provides resume position on reload
  • Auto-cleans entries older than 30 days

Key Functions:

  • saveProgress(videoId, source, position, duration, episodeIndex)
  • getProgress(videoId, source): Returns stored progress or null
  • shouldResumeProgress(progress): Check if position is valid for resume
  • createProgressSaver(interval): Returns throttled save function

lib/utils/error-handler.ts

Comprehensive error handling:

  • Categorizes errors: NETWORK, MEDIA, HLS, API, TIMEOUT
  • HLS.js error recovery strategies:
    • networkError: Retry with hls.startLoad()
    • mediaError: Call hls.recoverMediaError()
    • bufferAppendError: Ignore if playback started
    • fatal: Destroy and recreate player
  • Exponential backoff retry logic
  • User-friendly error messages

Key Functions:

  • handleHLSError(hls, errorData, retryCount): Returns recovery action
  • retryWithBackoff(fn, maxRetries, initialDelay)
  • isRetryableError(error): Check if error can be retried
  • ErrorRecovery.recoverNetwork(retryFn, maxAttempts)

lib/utils/search.ts

Search optimization utilities:

  • Debounce search input (500ms default)
  • Merge and deduplicate results from multiple sources
  • Normalize titles for comparison
  • Filter by year, area, type, keyword
  • Sort by relevance, year, name, or update time
  • Search history management (max 20 entries)

Key Functions:

  • debounce(func, delay): Debounce function calls
  • mergeSearchResults(results): Deduplicate and merge
  • filterResults(results, filters): Apply search filters
  • sortResults(results, sortBy): Sort by criteria
  • saveSearchQuery(query): Save to history

lib/utils/episode-manager.ts

Episode navigation logic:

  • Builds player URLs with episode parameters
  • Parses URL query parameters
  • Validates episode indices
  • Groups episodes into sections (20 per section)
  • Supports episode order toggle (normal/reversed)
  • Formats episode names and tracks progress

Key Functions:

  • buildPlayerUrl(params): Create player URL with episode info
  • parsePlayerParams(searchParams): Extract episode params from URL
  • getNextEpisodeParams(currentParams, episodes): Get next episode
  • groupEpisodesIntoSections(episodes, sectionSize): Paginate episodes
  • toggleEpisodeOrder(): Switch between normal/reversed order

lib/utils/source-switcher.ts

Multi-source speed testing:

  • Tests all sources in parallel
  • Measures API response time + video URL accessibility
  • Sorts by: current source → speed (fast to slow) → errors
  • Speed indicators: <1000ms=Fast, <2000ms=Medium, >2000ms=Slow
  • Caches test results for 5 minutes
  • Recommends switch if alternative is 50%+ faster

Key Functions:

  • testAllSources(videoTitle, sources, currentSource): Test all sources
  • getSpeedIndicator(speed): Return color-coded speed level
  • findBestSource(results): Get fastest available source
  • shouldSwitchSource(current, best): Check if switch is beneficial
  • buildSourceSwitchUrl(...): Create URL with new source

lib/utils/m3u8-filter.ts

Ad filtering for M3U8 playlists:

  • Custom HLS loader extending HLS.js
  • Intercepts M3U8 manifest requests
  • Parses playlist line-by-line
  • Filters segments containing ad patterns:
    • /ad/, /ads/, /advertisement/, _ad_, -ad-
    • Keywords: 'commercial', 'sponsored', 'promo'
  • Removes discontinuity tags around filtered segments
  • Preserves valid video segments

Key Classes/Functions:

  • AdFilteringHLSLoader: Custom HLS loader class
  • filterM3U8Playlist(content, baseUrl): Remove ad segments
  • createAdFilteringConfig(hlsConfig): Create HLS config with filtering
  • detectAdsInM3U8(url): Analyze playlist for ads
  • addCustomAdPattern(pattern): Add user-defined ad patterns

Data Flow

1. Search Flow

User Input → Debounce (500ms) → API Route (/api/search)
  → Parallel requests to sources → Normalize responses
  → Merge & deduplicate → Display results

2. Video Selection Flow

User clicks video → Navigate to detail page → API Route (/api/detail)
  → Fetch video details → Extract episodes → Parse M3U8 URLs
  → Initialize player store → Navigate to player page

3. Playback Flow

Player page loads → Create HLS instance with AdFilteringLoader
  → Load M3U8 URL → Filter ads → Initialize Artplayer
  → Resume from saved position (if valid)
  → Auto-save progress every 5s
  → On video end: Clear progress, auto-play next if enabled

4. Source Switching Flow

User clicks "Switch Source" → Search video title across all sources
  → Test each source speed (parallel):
    - Fetch detail API
    - HEAD request to first episode URL
    - Calculate response time
  → Sort by speed → Display with color indicators
  → User selects source → Navigate to new URL with updated params

Error Handling

HLS Errors

  • Network Error: Retry with hls.startLoad() (max 3 attempts)
  • Media Error: Call hls.recoverMediaError() (max 3 attempts)
  • Buffer Stalled: Restart loading
  • Fatal Error: Destroy player and suggest alternative source

API Errors

  • Timeout: Retry with exponential backoff
  • 404/500: Mark source as unavailable
  • Network Failure: Show user-friendly message, suggest alternative

Recovery Strategies

  1. Auto-retry with exponential backoff (1s, 2s, 4s)
  2. Switch to alternative source if current fails
  3. Resume from last saved position after recovery
  4. Clear corrupted localStorage data and reset

Configuration

Adding Custom Sources

import { addCustomSource } from '@/lib/api/video-sources';

addCustomSource({
  id: 'custom_source',
  name: 'My Custom API',
  baseUrl: 'https://api.example.com',
  searchPath: '/api.php/provide/vod',
  detailPath: '/api.php/provide/vod',
  headers: { 'User-Agent': 'Mozilla/5.0' },
  enabled: true,
  priority: 3
});

Customizing Ad Filters

import { addCustomAdPattern } from '@/lib/utils/m3u8-filter';

addCustomAdPattern('/custom-ad-path/');

Performance Optimizations

  1. Parallel API Requests: Fetch from all sources simultaneously
  2. Request Timeout: 15s timeout prevents hanging requests
  3. Result Caching: Speed test results cached for 5 minutes
  4. Throttled Progress Saving: Auto-save limited to every 5 seconds
  5. Lazy Loading: Episodes loaded only when needed
  6. Ad Filtering: Reduces bandwidth and loading time
  7. Source Priority: Faster sources prioritized automatically

Local Storage Keys

  • kvideo_custom_sources: Custom API sources
  • kvideo-player-store: Player settings (volume, rate, autoplay)
  • kvideo-history-store: Viewing history
  • kvideo_progress_{source}_{videoId}: Video progress
  • kvideo_search_history: Search query history
  • kvideo_speed_test_cache: Source speed test cache
  • kvideo_episode_order: Episode order preference
  • kvideo_custom_ad_patterns: Custom ad filter patterns

API Compatibility

The platform expects third-party APIs to return JSON in this format:

Search Response

{
  "code": 1,
  "list": [
    {
      "vod_id": 123,
      "vod_name": "Video Title",
      "vod_pic": "https://...",
      "type_name": "Movie",
      "vod_remarks": "HD",
      "vod_year": "2024"
    }
  ]
}

Detail Response

{
  "code": 1,
  "list": [
    {
      "vod_id": 123,
      "vod_name": "Video Title",
      "vod_pic": "https://...",
      "vod_play_url": "Episode1$url1#Episode2$url2",
      "vod_play_from": "m3u8"
    }
  ]
}

Next Steps

  1. Install Dependencies:
npm install zustand hls.js artplayer
  1. Configure API Sources: Edit lib/api/video-sources.ts with real API endpoints

  2. Build UI Components: Create React components using the logic layers

  3. Add Player Component: Integrate HLS.js and Artplayer with the stores

  4. Test Error Recovery: Simulate network failures and verify recovery

Security Considerations

  • Never expose API keys in client-side code
  • Validate all user inputs before API requests
  • Sanitize video URLs before loading
  • Implement rate limiting on API routes
  • Use CORS properly for third-party API calls