Files
documentation/sdk/index.html

588 lines
36 KiB
HTML

<!doctype html>
<html lang="en" class="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SDK Reference — Vyla</title>
<meta name="description"
content="Scrape video streams, fetch subtitles, retrieve download links, and monitor provider health directly from your Node.js application." />
<meta name="keywords"
content="Vyla SDK, Node.js SDK, TypeScript SDK, video streaming, subtitle API, download API, health monitoring, server-side streaming" />
<link rel="canonical" href="https://vyla.cc/sdk.html" />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://vyla.cc/sdk.html" />
<meta property="og:title" content="SDK Reference — Vyla" />
<meta property="og:description"
content="Scrape video streams, fetch subtitles, retrieve download links, and monitor provider health directly from your Node.js application." />
<meta property="og:image" content="https://vyla.cc/assets/images/thumbnail.png" />
<meta property="og:site_name" content="Vyla" />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://vyla.cc/sdk.html" />
<meta property="twitter:title" content="SDK Reference — Vyla" />
<meta property="twitter:description"
content="Scrape video streams, fetch subtitles, retrieve download links, and monitor provider health directly from your Node.js application." />
<meta property="twitter:image" content="https://vyla.cc/assets/images/thumbnail.png" />
<meta property="twitter:site" content="@vylaentertainment" />
<!-- Additional SEO -->
<meta name="robots" content="index, follow" />
<meta name="author" content="Vyla" />
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="/assets/base.css" />
<link rel="stylesheet" href="/assets/highlight.css" />
<link rel="stylesheet" href="/assets/mintlify-overrides.css" />
<!-- JSON-LD Structured Data -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Vyla SDK",
"description": "Scrape video streams, fetch subtitles, retrieve download links, and monitor provider health directly from your Node.js application.",
"url": "https://vyla.cc/sdk.html",
"applicationCategory": "DeveloperApplication",
"operatingSystem": "Node.js",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
}
}
</script>
<script>
(function () {
var saved = localStorage.getItem('vyla-theme');
var isDark = saved ? saved === 'dark' : true;
document.documentElement.classList.toggle('dark', isDark);
})();
</script>
</head>
<body>
<div id="banner">
<span>Vyla is self-hosted. Run Vyla Home, embed the SDK, or deploy Stream API on infrastructure you control. Rights
holders can request source removal — <a href="/misc/dmca">DMCA policy</a>.</span>
<button id="banner-close" onclick="dismissBanner()" aria-label="Dismiss">✕</button>
</div>
<header id="navbar">
<div class="nav-top">
<a class="brand" href="/"><img src="/assets/images/logo.png" alt="Vyla" id="brand-logo"></a>
<button id="search-trigger" type="button" onclick="openSearch()" aria-label="Search"></button>
<div class="links">
<button id="theme-toggle" type="button" onclick="toggleThemeMenu(event)" aria-label="Theme"></button>
</div>
</div>
<nav class="tabs">
<a class="tab-link" href="/">Vyla</a>
<a class="tab-link" href="/sdk">SDK</a>
<a class="tab-link active" href="/stream-api/overview">Stream API</a>
<a class="tab-link" href="/guides/integrations">Resources</a>
<a class="tab-link" href="/misc/credit">Misc</a>
</nav>
</header>
<div id="layout">
<nav id="sidebar">
<div class="group">
<p class="group-title">Vyla SDK</p>
<ul>
<li><a class="active" href="/sdk">Sdk</a></li>
<li><a class="" href="/sdk-quickstart">Sdk Quickstart</a></li>
</ul>
</div>
</nav>
<div id="content-col">
<main class="prose">
<h1>SDK Reference</h1>
<p class="page-description">Scrape video streams, fetch subtitles, retrieve download links, and monitor provider
health directly from your Node.js application.</p>
<p>The <strong>Vyla SDK</strong> (<code>@vyla-entertainment/sdk</code>) is a server-side JavaScript/TypeScript
package that provides direct access to Vyla's stream resolvers, health probes, download resolvers, and
subtitle providers.</p>
<p>By embedding the SDK directly into your backend application, provider resolution executes in your own
environment. It is an alternative to operating the Stream API as a separate process: your application owns its
request boundary, caching, authorization, timeouts, and response shape.</p>
<div class="callout callout-note">
<div class="callout-content">
<p>The SDK can be used independently of the self-hosted Stream API. If you prefer to embed Vyla capabilities
in an existing Node.js application rather than run a separate HTTP service, begin with the <a
href="/sdk-quickstart">SDK quickstart</a>.</p>
</div>
</div>
<hr>
<h2 id="features">Features</h2>
<ul>
<li><strong>Direct-to-Client Playback</strong>: Scraped streams link directly to source CDNs. No proxy server
overhead required unless specified by provider headers.</li>
<li><strong>Built-In Health Probing</strong>: Monitor latency and uptime per provider with built-in health
check utilities.</li>
<li><strong>Automated Anime Sub/Dub Routing</strong>: Automatically configures audio track requirements
(<code>sub</code> vs <code>dub</code>) based on provider naming conventions.</li>
<li><strong>Multi-Source Subtitle Aggregation</strong>: Merges subtitle tracks from multiple redundant
subtitle mirrors into a unified VTT/SRT format.</li>
<li><strong>Metadata Fallbacks</strong>: Automatically maps TMDB IDs to external IDs (such as IMDB and
AniList) for smooth stream lookups.</li>
<li><strong>Self-Contained</strong>: No need to deploy a separate API server — all streaming functionality
runs within your existing Node.js application.</li>
</ul>
<hr>
<h2 id="installation">Installation</h2>
<p>Install the package into your Node.js backend using your package manager of choice:</p>
<div class="code-group">
<div class="code-group-tabs"><button class="code-group-tab active" data-tab-index="0" type="button"
onclick="cgSwitch(this)">npm</button><button class="code-group-tab" data-tab-index="1" type="button"
onclick="cgSwitch(this)">pnpm</button><button class="code-group-tab" data-tab-index="2" type="button"
onclick="cgSwitch(this)">yarn</button></div>
<div class="code-group-panels">
<div class="code-group-panel active">
<pre><code class="hljs language-bash">npm <span class="hljs-built_in">install</span> <span class="hljs-string">@vyla-entertainment/sdk</span></code></pre>
</div>
<div class="code-group-panel">
<pre><code class="hljs language-bash">pnpm <span class="hljs-built_in">install</span> <span class="hljs-string">@vyla-entertainment/sdk</span></code></pre>
</div>
<div class="code-group-panel">
<pre><code class="hljs language-bash">yarn <span class="hljs-built_in">add</span> <span class="hljs-string">@vyla-entertainment/sdk</span></code></pre>
</div>
</div>
</div>
<blockquote>
<p><strong>Note</strong>: Node.js <strong>v18+</strong> is required due to modern standard <code>fetch</code>
and <code>AbortSignal.timeout</code> usage.</p>
</blockquote>
<hr>
<h2 id="initialization">Initialization</h2>
<p>Initialize the <code>VylaSDK</code> client by supplying your <strong>TMDB API Key</strong>. The key resolves
media metadata, validates movie/TV show IDs, and translates TMDB IDs into AniList IDs for anime sources.</p>
<p>You may optionally provide a pengu.uk manifest URL to enable the Pengu source.</p>
<pre><code class="hljs language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">VylaSDK</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@vyla-entertainment/sdk"</span>;
<span class="hljs-keyword">const</span> sdk = <span class="hljs-keyword">new</span> <span class="hljs-title class_">VylaSDK</span>({
<span class="hljs-attr">tmdbApiKey</span>: process.<span class="hljs-property">env</span>.<span class="hljs-property">TMDB_API_KEY</span>,
<span class="hljs-attr">penguManifest</span>: <span class="hljs-string">""</span> <span class="hljs-comment">// Optional, get from pengu.uk</span>
});
</code></pre>
<hr>
<h2 id="core-methods">Core Methods</h2>
<h3 id="getstreamkey-id-s-e-clientip"><code>getStream(key, id, s?, e?, clientIP?)</code></h3>
<p>Scrapes video stream URLs and playability headers for a specified provider key.</p>
<pre><code class="hljs language-javascript"><span class="hljs-comment">// Fetch a movie stream (TMDB ID: 155 - The Dark Knight)</span>
<span class="hljs-keyword">const</span> movieStream = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getStream</span>(<span class="hljs-string">"sourcename"</span>, <span class="hljs-string">"155"</span>);
<span class="hljs-comment">// Fetch a TV show episode (TMDB ID: 1399, Season 1, Episode 1)</span>
<span class="hljs-keyword">const</span> tvStream = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getStream</span>(<span class="hljs-string">"sourcename"</span>, <span class="hljs-string">"1399"</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>);
<span class="hljs-comment">// Pass client IP for providers that use geo-verification</span>
<span class="hljs-keyword">const</span> geoStream = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getStream</span>(<span class="hljs-string">"sourcename"</span>, <span class="hljs-string">"155"</span>, <span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">"203.0.113.195"</span>);
</code></pre>
<h4 id="parameters">Parameters</h4>
<table>
<thead>
<tr>
<th align="left">Parameter</th>
<th align="left">Type</th>
<th align="left">Required</th>
<th align="left">Default</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>key</code></td>
<td align="left"><code>string</code></td>
<td align="left"><strong>Yes</strong></td>
<td align="left">—</td>
<td align="left">Unique key identifier for the provider (e.g. <code>"sourcename"</code>,
<code>"sourcename"</code>, <code>"sourcename"</code>).
</td>
</tr>
<tr>
<td align="left"><code>id</code></td>
<td align="left"><code>string</code></td>
<td align="left"><strong>Yes</strong></td>
<td align="left">—</td>
<td align="left">TMDB media ID (e.g., <code>"155"</code>).</td>
</tr>
<tr>
<td align="left"><code>s</code></td>
<td align="left"><code>string | number</code></td>
<td align="left"><strong>No</strong></td>
<td align="left"><code>null</code></td>
<td align="left">Season number (required for TV shows).</td>
</tr>
<tr>
<td align="left"><code>e</code></td>
<td align="left"><code>string | number</code></td>
<td align="left"><strong>No</strong></td>
<td align="left"><code>null</code></td>
<td align="left">Episode number (required for TV shows).</td>
</tr>
<tr>
<td align="left"><code>clientIP</code></td>
<td align="left"><code>string</code></td>
<td align="left"><strong>No</strong></td>
<td align="left"><code>null</code></td>
<td align="left">End-user IP address forwarded for geo-restricted scrapers.</td>
</tr>
</tbody>
</table>
<h4 id="example-response-format">Example Response Format</h4>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"url"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://example-cdn.com/hls/manifest.m3u8"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"quality"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"auto"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"isM3U8"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"headers"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"Referer"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://example.com/"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"Origin"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://example.com"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"allUrls"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"url"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://example-cdn.com/hls/manifest.m3u8"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"quality"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1080p"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"isM3U8"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
</code></pre>
<hr>
<h3 id="getsubtitlesid-s-e"><code>getSubtitles(id, s?, e?)</code></h3>
<p>Fetches subtitle files aggregated across multiple subtitle backend mirrors (<code>v1</code>, <code>v2</code>,
<code>febbox</code>). Returns clean VTT and SRT tracks.
</p>
<pre><code class="hljs language-javascript"><span class="hljs-comment">// Fetch movie subtitles</span>
<span class="hljs-keyword">const</span> movieSubs = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getSubtitles</span>(<span class="hljs-string">"155"</span>);
<span class="hljs-comment">// Fetch TV show episode subtitles</span>
<span class="hljs-keyword">const</span> tvSubs = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getSubtitles</span>(<span class="hljs-string">"1399"</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>);
</code></pre>
<h4 id="parameters-1">Parameters</h4>
<table>
<thead>
<tr>
<th align="left">Parameter</th>
<th align="left">Type</th>
<th align="left">Required</th>
<th align="left">Default</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>id</code></td>
<td align="left"><code>string</code></td>
<td align="left"><strong>Yes</strong></td>
<td align="left">—</td>
<td align="left">TMDB media ID.</td>
</tr>
<tr>
<td align="left"><code>s</code></td>
<td align="left"><code>string | number</code></td>
<td align="left"><strong>No</strong></td>
<td align="left"><code>null</code></td>
<td align="left">Season number (required for TV shows).</td>
</tr>
<tr>
<td align="left"><code>e</code></td>
<td align="left"><code>string | number</code></td>
<td align="left"><strong>No</strong></td>
<td align="left"><code>null</code></td>
<td align="left">Episode number (required for TV shows).</td>
</tr>
</tbody>
</table>
<h4 id="example-response-format-1">Example Response Format</h4>
<pre><code class="hljs language-json"><span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"label"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"English"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"file"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://sub.vdrk.site/v1/vtt/movie/155/English.vtt"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"vtt"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"source"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"v1"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"label"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"Spanish"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"file"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://fed-subs.pstream.mov/subtitles/spanish.srt"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"type"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"srt"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"source"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"febbox"</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span>
</code></pre>
<hr>
<h3 id="getdownloadsid-s-e"><code>getDownloads(id, s?, e?)</code></h3>
<p>Fetches direct downloadable media files (MP4/MKV) paired with resolution and file size descriptors.</p>
<pre><code class="hljs language-javascript"><span class="hljs-comment">// Movie downloads</span>
<span class="hljs-keyword">const</span> downloads = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getDownloads</span>(<span class="hljs-string">"155"</span>);
<span class="hljs-comment">// TV Episode downloads</span>
<span class="hljs-keyword">const</span> tvDownloads = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getDownloads</span>(<span class="hljs-string">"1399"</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>);
</code></pre>
<h4 id="example-response-format-2">Example Response Format</h4>
<pre><code class="hljs language-json"><span class="hljs-punctuation">[</span>
<span class="hljs-punctuation">{</span>
<span class="hljs-attr">"url"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://download-node.com/file/the-dark-knight-1080p.mp4"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"quality"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"1080p"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"size"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"2.14 GB"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"format"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"MP4"</span>
<span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">]</span>
</code></pre>
<hr>
<h2 id="provider--health-management">Provider &#x26; Health Management</h2>
<h3 id="getsourcesexcludedisabled"><code>getSources(excludeDisabled?)</code></h3>
<p>Retrieves provider configurations registered in the SDK.</p>
<pre><code class="hljs language-javascript"><span class="hljs-comment">// Get all sources including temporarily disabled ones</span>
<span class="hljs-keyword">const</span> allSources = sdk.<span class="hljs-title function_">getSources</span>(<span class="hljs-literal">false</span>);
<span class="hljs-comment">// Get only active/enabled sources</span>
<span class="hljs-keyword">const</span> activeSources = sdk.<span class="hljs-title function_">getSources</span>(<span class="hljs-literal">true</span>);
</code></pre>
<h4 id="parameters-2">Parameters</h4>
<table>
<thead>
<tr>
<th align="left">Parameter</th>
<th align="left">Type</th>
<th align="left">Required</th>
<th align="left">Default</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>excludeDisabled</code></td>
<td align="left"><code>boolean</code></td>
<td align="left"><strong>No</strong></td>
<td align="left"><code>false</code></td>
<td align="left">When <code>true</code>, filters out providers marked as disabled
(<code>disabled: true</code>).</td>
</tr>
</tbody>
</table>
<hr>
<h3 id="probesourcekey"><code>probeSource(key)</code></h3>
<p>Executes a health ping test against a single provider to determine current availability and latency using a
probe payload (<code>TMDB ID: 155</code>).</p>
<pre><code class="hljs language-javascript"><span class="hljs-keyword">const</span> health = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">probeSource</span>(<span class="hljs-string">"vidrock"</span>);
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(health);
<span class="hljs-comment">// Output: { ok: true, ms: 840 }</span>
</code></pre>
<hr>
<h3 id="probeallsources"><code>probeAllSources()</code></h3>
<p>Executes health tests in parallel across all non-disabled provider modules.</p>
<pre><code class="hljs language-javascript"><span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">probeAllSources</span>();
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(results);
</code></pre>
<h4 id="example-response-format-3">Example Response Format</h4>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"sourcename1"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"ok"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"ms"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">420</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"sourcename2"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"ok"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"ms"</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1150</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"sourcename3"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">"ok"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span> <span class="hljs-attr">"ms"</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">null</span></span> <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre>
<hr>
<h2 id="provider-metadata-properties">Provider Metadata Properties</h2>
<p>When calling <code>getSources()</code>, each provider entry returns metadata describing its features and
streaming behavior:</p>
<pre><code class="hljs language-javascript">{
<span class="hljs-attr">key</span>: <span class="hljs-string">'example'</span>,
<span class="hljs-attr">label</span>: <span class="hljs-string">'Example'</span>,
<span class="hljs-attr">sourceFile</span>: <span class="hljs-string">'example'</span>,
<span class="hljs-attr">proxyParam</span>: <span class="hljs-string">'ex'</span>,
<span class="hljs-attr">timeout</span>: <span class="hljs-number">20000</span>,
<span class="hljs-attr">jitter</span>: <span class="hljs-number">800</span>,
<span class="hljs-attr">retries</span>: <span class="hljs-number">3</span>,
<span class="hljs-attr">multiUrl</span>: <span class="hljs-literal">true</span>,
<span class="hljs-attr">skipProxy</span>: <span class="hljs-literal">false</span>,
<span class="hljs-attr">cdnHeaders</span>: [{
<span class="hljs-attr">pattern</span>: <span class="hljs-regexp">/./</span>,
<span class="hljs-attr">headers</span>: {
<span class="hljs-title class_">Referer</span>: <span class="hljs-string">'https://example.com/'</span>,
<span class="hljs-title class_">Origin</span>: <span class="hljs-string">'https://example.com'</span>
}
}]
}
</code></pre>
<h3 id="property-reference">Property Reference</h3>
<table>
<thead>
<tr>
<th align="left">Field</th>
<th align="left">Type</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><code>key</code></td>
<td align="left"><code>string</code></td>
<td align="left">Unique identifier used in <code>getStream()</code> and <code>probeSource()</code>.</td>
</tr>
<tr>
<td align="left"><code>label</code></td>
<td align="left"><code>string</code></td>
<td align="left">Human-readable name for UI display.</td>
</tr>
<tr>
<td align="left"><code>skipProxy</code></td>
<td align="left"><code>boolean</code></td>
<td align="left">When <code>true</code>, stream URLs can be fed directly to web video players (e.g.,
HLS.js, Video.js) without needing an intermediate backend proxy.</td>
</tr>
<tr>
<td align="left"><code>multiUrl</code></td>
<td align="left"><code>boolean</code></td>
<td align="left">Indicates whether the source returns multiple stream resolution choices.</td>
</tr>
<tr>
<td align="left"><code>timeout</code></td>
<td align="left"><code>number</code></td>
<td align="left">Internal request timeout threshold in milliseconds.</td>
</tr>
<tr>
<td align="left"><code>retries</code></td>
<td align="left"><code>number</code></td>
<td align="left">Max automatic retry attempts executed by health/stream scrapers.</td>
</tr>
<tr>
<td align="left"><code>cdnHeaders</code></td>
<td align="left"><code>Array</code></td>
<td align="left">Regex pattern matching rules detailing required request headers (<code>Referer</code>,
<code>Origin</code>) needed to playback stream segments without <code>403 Forbidden</code> errors.
</td>
</tr>
<tr>
<td align="left"><code>disabled</code></td>
<td align="left"><code>boolean</code></td>
<td align="left">Set to <code>true</code> if a source is down or undergoing maintenance.</td>
</tr>
</tbody>
</table>
<hr>
<h2 id="practical-expressjs-backend-example">Practical Express.js Backend Example</h2>
<p>Here is an example showing how to serve stream links to your client web application while handling custom CDN
playback headers and subtitle merging:</p>
<pre><code class="hljs language-javascript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-title class_">VylaSDK</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@vyla-entertainment/sdk"</span>;
<span class="hljs-keyword">const</span> app = <span class="hljs-title function_">express</span>();
<span class="hljs-keyword">const</span> sdk = <span class="hljs-keyword">new</span> <span class="hljs-title class_">VylaSDK</span>({ <span class="hljs-attr">tmdbApiKey</span>: process.<span class="hljs-property">env</span>.<span class="hljs-property">TMDB_API_KEY</span> });
<span class="hljs-comment">// Scrape stream route</span>
app.<span class="hljs-title function_">get</span>(<span class="hljs-string">"/api/stream"</span>, <span class="hljs-title function_">async</span> (req, res) => {
<span class="hljs-keyword">const</span> { provider, tmdbId, season, episode } = req.<span class="hljs-property">query</span>;
<span class="hljs-keyword">const</span> clientIP = req.<span class="hljs-property">headers</span>[<span class="hljs-string">"x-forwarded-for"</span>] || req.<span class="hljs-property">socket</span>.<span class="hljs-property">remoteAddress</span>;
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">const</span> streamData = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getStream</span>(
provider,
tmdbId,
season || <span class="hljs-literal">null</span>,
episode || <span class="hljs-literal">null</span>,
clientIP
);
<span class="hljs-keyword">if</span> (!streamData || !streamData.<span class="hljs-property">url</span>) {
<span class="hljs-keyword">return</span> res.<span class="hljs-title function_">status</span>(<span class="hljs-number">404</span>).<span class="hljs-title function_">json</span>({ <span class="hljs-attr">error</span>: <span class="hljs-string">"No stream found for this provider"</span> });
}
<span class="hljs-keyword">return</span> res.<span class="hljs-title function_">json</span>({
<span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
provider,
<span class="hljs-attr">stream</span>: streamData,
});
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-keyword">return</span> res.<span class="hljs-title function_">status</span>(<span class="hljs-number">500</span>).<span class="hljs-title function_">json</span>({ <span class="hljs-attr">error</span>: error.<span class="hljs-property">message</span> });
}
});
<span class="hljs-comment">// Fetch subtitles route</span>
app.<span class="hljs-title function_">get</span>(<span class="hljs-string">"/api/subtitles"</span>, <span class="hljs-title function_">async</span> (req, res) => {
<span class="hljs-keyword">const</span> { tmdbId, season, episode } = req.<span class="hljs-property">query</span>;
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">const</span> subtitles = <span class="hljs-keyword">await</span> sdk.<span class="hljs-title function_">getSubtitles</span>(
tmdbId,
season || <span class="hljs-literal">null</span>,
episode || <span class="hljs-literal">null</span>
);
<span class="hljs-keyword">return</span> res.<span class="hljs-title function_">json</span>({ subtitles });
} <span class="hljs-keyword">catch</span> (error) {
<span class="hljs-keyword">return</span> res.<span class="hljs-title function_">status</span>(<span class="hljs-number">500</span>).<span class="hljs-title function_">json</span>({ <span class="hljs-attr">subtitles</span>: [] });
}
});
app.<span class="hljs-title function_">listen</span>(<span class="hljs-number">3000</span>, <span class="hljs-function">() =></span> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"Vyla SDK Server running on port 3000"</span>));
</code></pre>
<h2 id="sdk-vs-self-hosted-api">SDK vs Self-Hosted API</h2>
<p>The SDK and the self-hosted API server provide the same streaming functionality but in different deployment
models:</p>
<table>
<thead>
<tr>
<th>Aspect</th>
<th>SDK</th>
<th>Self-Hosted API</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Deployment</strong></td>
<td>Embedded in your Node.js app</td>
<td>Separate server process</td>
</tr>
<tr>
<td><strong>Network</strong></td>
<td>Direct source CDN access</td>
<td>Built-in proxy for CORS</td>
</tr>
<tr>
<td><strong>Rate Limiting</strong></td>
<td>None (you control it)</td>
<td>Per-API-key limits</td>
</tr>
<tr>
<td><strong>Setup</strong></td>
<td>npm install + init</td>
<td>Clone repo + configure</td>
</tr>
<tr>
<td><strong>Use Case</strong></td>
<td>Existing Node.js apps</td>
<td>Standalone streaming service</td>
</tr>
</tbody>
</table>
<p>Choose the SDK if you want to integrate streaming directly into an existing Node.js application. Choose the
self-hosted API if you want a standalone streaming service that can be used by multiple clients.</p>
</main>
<aside id="toc">
<p class="toc-title">On this page</p>
<ul>
<li><a href="#features">Features</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#initialization">Initialization</a></li>
<li><a href="#core-methods">Core Methods</a></li>
<li><a href="#provider--health-management">Provider & Health Management</a></li>
<li><a href="#provider-metadata-properties">Provider Metadata Properties</a></li>
<li><a href="#practical-expressjs-backend-example">Practical Express.js Backend Example</a></li>
<li><a href="#sdk-vs-self-hosted-api">SDK vs Self-Hosted API</a></li>
</ul>
</aside>
</div>
</div>
<footer id="site-footer">
<a href="https://discord.gg/5eqRhKeywG" target="_blank" rel="noopener">Discord</a>
<a href="https://gitlab.com/vyla-entertainment/" target="_blank" rel="noopener">GitLab</a>
</footer>
<script src="/assets/app.js"></script>
</body>
</html>