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 sourcesVideoItem: Search result structureVideoDetail: Full video information with episodesPlayerState: Current playback stateVideoHistoryItem: Viewing history with progressApiResponse: 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 sourcesgetEnabledSources(): Get enabled sources sorted by priorityhealthCheckSource(source): Test source availability and response timeaddCustomSource(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 sourcesgetVideoDetail(id, source): Fetch video details with episodestestVideoUrl(url): Check video URL accessibilitynormalizeVideoData(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 IDsource: Source identifiercustomApi: (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 entryupdateProgress(videoId, source, episodeIndex, position, duration)getHistoryItem(videoId, source): Retrieve specific history entryclearHistory(): 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 nullshouldResumeProgress(progress): Check if position is valid for resumecreateProgressSaver(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 withhls.startLoad()mediaError: Callhls.recoverMediaError()bufferAppendError: Ignore if playback startedfatal: Destroy and recreate player
- Exponential backoff retry logic
- User-friendly error messages
Key Functions:
handleHLSError(hls, errorData, retryCount): Returns recovery actionretryWithBackoff(fn, maxRetries, initialDelay)isRetryableError(error): Check if error can be retriedErrorRecovery.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 callsmergeSearchResults(results): Deduplicate and mergefilterResults(results, filters): Apply search filterssortResults(results, sortBy): Sort by criteriasaveSearchQuery(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 infoparsePlayerParams(searchParams): Extract episode params from URLgetNextEpisodeParams(currentParams, episodes): Get next episodegroupEpisodesIntoSections(episodes, sectionSize): Paginate episodestoggleEpisodeOrder(): 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 sourcesgetSpeedIndicator(speed): Return color-coded speed levelfindBestSource(results): Get fastest available sourceshouldSwitchSource(current, best): Check if switch is beneficialbuildSourceSwitchUrl(...): 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 classfilterM3U8Playlist(content, baseUrl): Remove ad segmentscreateAdFilteringConfig(hlsConfig): Create HLS config with filteringdetectAdsInM3U8(url): Analyze playlist for adsaddCustomAdPattern(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
- Auto-retry with exponential backoff (1s, 2s, 4s)
- Switch to alternative source if current fails
- Resume from last saved position after recovery
- 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
- Parallel API Requests: Fetch from all sources simultaneously
- Request Timeout: 15s timeout prevents hanging requests
- Result Caching: Speed test results cached for 5 minutes
- Throttled Progress Saving: Auto-save limited to every 5 seconds
- Lazy Loading: Episodes loaded only when needed
- Ad Filtering: Reduces bandwidth and loading time
- Source Priority: Faster sources prioritized automatically
Local Storage Keys
kvideo_custom_sources: Custom API sourceskvideo-player-store: Player settings (volume, rate, autoplay)kvideo-history-store: Viewing historykvideo_progress_{source}_{videoId}: Video progresskvideo_search_history: Search query historykvideo_speed_test_cache: Source speed test cachekvideo_episode_order: Episode order preferencekvideo_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
- Install Dependencies:
npm install zustand hls.js artplayer
-
Configure API Sources: Edit
lib/api/video-sources.tswith real API endpoints -
Build UI Components: Create React components using the logic layers
-
Add Player Component: Integrate HLS.js and Artplayer with the stores
-
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