mirror of
https://gitlab.com/vyla-entertainment/documentation.git
synced 2026-11-14 22:47:26 -05:00
fixed syntax issues
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user