fixed syntax issues

This commit is contained in:
2026-11-14 19:05:02 -08:00
parent 2cec85a8f3
commit 36b2b33ecc
29 changed files with 842 additions and 977 deletions

View File

@@ -4,44 +4,32 @@
## Overview
Streaming from distributed upstream web providers is inherently dynamic. Upstream CDN nodes rotate domains, regional ISPs implement traffic shaping, and token signatures expire.
Building a resilient client requires planning for failure at every step. This guide explains how Vyla handles errors internally and how client players should respond.
Upstream video providers can rotate domains, experience rate limits, or suffer transient outages. This guide explains how Vyla handles errors internally and how client players should respond.
---
## Error Classification Matrix
## Error Classification
| Error Type | Common Cause | Stream API / SDK Behavior | Recommended Player Action |
| :--- | :--- | :--- | :--- |
| **HTTP 400 Bad Request** | Missing or malformed TMDB ID, invalid season/episode | Returns immediate JSON error payload without querying providers. | Validate input parameters client-side before sending requests. |
| **HTTP 429 Too Many Requests** | Upstream host rate-limiting client IP | SDK provider applies backoff delay and retries up to `retries` limit. | If proxy returns 429, respect the `retry_after` header and back off. |
| **HTTP 502 Bad Gateway** | Upstream provider host is unreachable or timed out | Provider is discarded; other scrapers continue executing. | Fall back to the next available stream candidate in your queue. |
| **SSE Disconnect** | Network hiccup or client tab backgrounded | Connection drops; `EventSource.onerror` fires. | If video is already playing, do not interrupt. Otherwise, reconnect after 2 seconds. |
| **HLS Fatal Media Error** | Segment buffer stall, corrupt chunk, or missing decryption key | Player triggers `Hls.Events.ERROR` with `fatal: true`. | Call `hls.destroy()` and load the next candidate from your fallback queue. |
- **HTTP 400 Bad Request**: Missing or invalid TMDB ID or episode parameters. Validate input parameters on the client before requesting streams.
- **HTTP 429 Too Many Requests**: Upstream host rate limit triggered. The SDK applies backoff delays; clients should respect the `retry_after` header.
- **HTTP 502 Bad Gateway**: Upstream host unreachable or timed out. That provider is discarded while other scrapers continue running.
- **SSE Disconnect**: Network drop or backgrounded tab. If media is already buffering, do not interrupt. Otherwise, reconnect after a brief delay.
- **HLS Fatal Media Error**: Buffer stall or missing encryption key (`fatal: true`). Destroy the player instance and mount the next queued fallback stream.
---
## Client Fallback Queue Strategy
## Client Fallback Strategy
Always treat streaming candidate resolution as a prioritized queue rather than a single static link:
Treat stream candidates as a prioritized queue rather than a single static link:
### Queue Priority Assignment
1. **Mount First Candidate**: Mount the first verified source that arrives over SSE.
2. **Queue Subsequent Sources**: Push subsequent incoming `source` events into a fallback array.
3. **Capture Timestamp on Error**: If a fatal error occurs, record `video.currentTime`.
4. **Teardown & Reconnect**: Call `hls.destroy()`, dequeue the next candidate, mount it, and seek back to the saved timestamp once metadata loads.
| Candidate Stream | Player State | Fallback Precedence |
| :--- | :--- | :--- |
| **Candidate 1** (`vidlink`) | **Active Playback** | Mounted into HLS.js or ExoPlayer on arrival. |
| **Candidate 2** (`vixsrc`) | **Standby Backup** | Enqueued as Priority #1 fallback stream. |
| **Candidate 3** (`cinecat`) | **Standby Backup** | Enqueued as Priority #2 fallback stream. |
---
### Recovery Sequence on Stream Stall
1. **Error Interception**: Player detects a fatal network or decode event (`data.fatal === true`).
2. **Timestamp Preservation**: Record current playback offset (e.g. `currentTime = 142.5s`).
3. **Buffer Teardown**: Call `hls.destroy()` or `player.release()` to release media pipelines and decoders.
4. **Queue Advancement**: Dequeue the next available verified candidate from the standby queue.
5. **Seamless Seek**: Mount the fallback source and seek immediately to the preserved timestamp upon `loadedmetadata`.
### Implementing Fallback Recovery in JavaScript
## Implementation Example
```javascript
function attachHlsPlayer(videoElement, candidate, fallbackQueue) {
@@ -57,15 +45,11 @@ function attachHlsPlayer(videoElement, candidate, fallbackQueue) {
hls.on(Hls.Events.ERROR, (event, data) => {
if (!data.fatal) return;
console.warn(`Encountered fatal error on ${candidate.source}:`, data.type);
switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
console.log("Attempting network recovery...");
hls.startLoad();
break;
case Hls.ErrorTypes.MEDIA_ERROR:
console.log("Attempting media recovery...");
hls.recoverMediaError();
break;
default:
@@ -73,7 +57,6 @@ function attachHlsPlayer(videoElement, candidate, fallbackQueue) {
if (fallbackQueue.length > 0) {
const nextCandidate = fallbackQueue.shift();
const lastTime = videoElement.currentTime;
console.warn(`Switching to fallback candidate: ${nextCandidate.label}`);
attachHlsPlayer(videoElement, nextCandidate, fallbackQueue);
videoElement.addEventListener('loadedmetadata', () => {
@@ -81,7 +64,7 @@ function attachHlsPlayer(videoElement, candidate, fallbackQueue) {
videoElement.play();
}, { once: true });
} else {
showErrorOverlay("All available streaming providers have failed.");
showErrorOverlay("All available streaming providers failed.");
}
break;
}
@@ -93,20 +76,7 @@ function attachHlsPlayer(videoElement, candidate, fallbackQueue) {
---
## Client-Side Timeout Budgets
## Timeout Budgets
Never leave users hanging on an indefinite spinner. Implement a two-tiered timeout budget:
1. **Initial Candidate Timeout (8–10 seconds)**: If no `type: "source"` event has arrived within 8 seconds, update the UI to indicate extended searching.
2. **Hard Timeout (20 seconds)**: If the stream has not completed or emitted a viable candidate within 20 seconds:
- Call `eventSource.close()`.
- Render a helpful empty-state UI with a "Retry" button or an option to change the server URL.
---
## Decoupled Subtitle Fallback
Subtitles originate from independent subtitle repositories (e.g. OpenSubtitles, SubDL). If a subtitle track fails to load:
- The video playback must continue uninterrupted.
- Log a warning in the console.
- Offer the viewer an in-player menu to toggle alternative subtitle providers or upload a local `.srt`/`.vtt` file.
- **First Candidate Timeout (8–10s)**: If no source event arrives within 8 seconds, inform the user that extended search is underway.
- **Hard Abort Timeout (20–25s)**: If no viable source is verified before the watchdog timer expires, close the connection and display an empty state with a retry button.