Files
documentation/sdk/vyla-sdk/contributing.md

3.6 KiB
Raw Permalink Blame History

Contributing a Source Provider

Technical guide for authoring, testing, and contributing a new video scraping resolver to the Vyla SDK.

Overview

The Vyla SDK uses independent provider scrapers located in src/sources/. We welcome contributions that expand coverage for movies and television series.


Scraper Contract

Every provider module is an ES Module exporting a single function:

export async function getStream(args: StreamArgs): Promise<StreamResult | { allUrls: StreamResult[] }>

Context Arguments (args)

  • id (string | number) — TMDB numeric ID or string IMDb ID.
  • s (number | null) — Season number for television series (or null for movies).
  • e (number | null) — Episode number for television series (or null for movies).
  • clientIP (string | null) — Client IP address forwarded for geo-token generation.
  • fetch (Function) — Pre-configured fetch wrapper with timeout controls.
  • imdbId (string | null) — Auto-resolved IMDb ID.
  • title (string | null) — Verified title string.
  • year (number | null) — Media release year.

Implementation Steps

1. Create the Scraper Module

Create a new file in src/sources/<source_name>.js:

const BASE_URL = 'https://provider-domain.example.com';

const DEFAULT_HEADERS = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
  'Referer': `${BASE_URL}/`,
  'Origin': BASE_URL
};

export async function getStream({ id, s, e, imdbId }) {
  const isTv = s != null && e != null;
  const endpoint = isTv
    ? `${BASE_URL}/api/tv/${id}/${s}/${e}`
    : `${BASE_URL}/api/movie/${id}`;

  const response = await fetch(endpoint, {
    headers: DEFAULT_HEADERS
  });

  if (!response.ok) {
    throw new Error(`Upstream returned HTTP ${response.status}`);
  }

  const data = await response.json();
  if (!data.streamUrl) {
    throw new Error('No stream found in upstream response');
  }

  return {
    url: data.streamUrl,
    headers: {
      ...DEFAULT_HEADERS,
      'Referer': data.referer || DEFAULT_HEADERS.Referer
    },
    server: 'MySource-Primary',
    quality: data.quality || '1080p',
    type: data.streamUrl.includes('.m3u8') ? 'hls' : 'mp4'
  };
}

2. Register in src/config.js

Add the source configuration:

{
    key: 'mysource',
    label: 'My Source',
    sourceFile: 'mysource',
    proxyParam: 'ms',
    timeout: 12000,
    jitter: 400,
    retries: 1,
    multiUrl: false,
    skipProxy: false,
    skipVerify: false
}

Key Fields:

  • key: Lowercase identifier without spaces (e.g. mysource).
  • label: Clean display label for client UIs.
  • proxyParam: Unique 2-to-4 character query flag for the HLS proxy.
  • timeout: Maximum execution budget in ms (typically 8,000–15,000).
  • jitter: Random delay ceiling in ms (typically 300–500).

3. Local Testing

Run your scraper against known TMDB titles:

node test/index.js mysource 155
node test/index.js mysource 1396 1 1

Verify that:

  1. A valid URL is returned.
  2. The format is correctly identified as hls or mp4.
  3. Required upstream headers (Referer, Origin, User-Agent) are included.
  4. An invalid ID throws a clean error without crashing.

Contribution Checklist

  • Code is formatted with clean ES Module syntax.
  • No hardcoded personal API keys or credentials.
  • No untrusted eval() or un-sanitized script execution.
  • Upstream stream candidate URLs are verified for playback.
  • Descriptive errors are thrown with throw new Error(...).