mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-17 01:33:43 +08:00
400 lines
12 KiB
Markdown
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
|