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

400 lines
12 KiB
Markdown

# 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**:
```json
{
"query": "search term",
"sources": ["source_1", "source_2"],
"page": 1
}
```
**Response Format**:
```json
{
"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**:
```typescript
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
```typescript
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
```typescript
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
```json
{
"code": 1,
"list": [
{
"vod_id": 123,
"vod_name": "Video Title",
"vod_pic": "https://...",
"type_name": "Movie",
"vod_remarks": "HD",
"vod_year": "2024"
}
]
}
```
### Detail Response
```json
{
"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**:
```bash
npm install zustand hls.js artplayer
```
2. **Configure API Sources**: Edit `lib/api/video-sources.ts` with real API endpoints
3. **Build UI Components**: Create React components using the logic layers
4. **Add Player Component**: Integrate HLS.js and Artplayer with the stores
5. **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