Files
documentation/sdk/vyla-sdk/contributing.md
2026-11-14 18:21:12 -08:00

4.4 KiB
Raw Blame History

Contributing a Source Provider

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

Overview

The Vyla SDK maintains its high reliability through a distributed collection of independent provider scrapers located in src/sources/. We welcome contributions of new sources that expand coverage for movies, television, and international content.


Scraper Architecture

Every provider module is a self-contained ES Module adhering to a single exported contract:

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

The args Object

When your scraper's getStream() is invoked, the SDK passes a normalized args context containing:

Field Type Description
id string | number The TMDB numeric media ID or string IMDb ID.
s number | null Season number for television episodes (or null for movies).
e number | null Episode number for television episodes (or null for movies).
clientIP string | null The viewer's client IP address (if passed from an upstream proxy).
fetch Function Node.js fetch wrapper pre-configured with timeout controls.
imdbId string | null Automatically resolved IMDb ID (if TMDB API key is configured).
title string | null Verified media title string.
year number | null Media release year.

Step-by-Step Implementation Guide

Step 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'
  };
}

Step 2: Register in src/config.js

Add your provider configuration to the SOURCES array in src/config.js:

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

Configuration Field Guidelines:

  • key: Lowercase alphanumeric identifier without spaces (e.g. vidlink, cinecat).
  • label: Clean display title shown in UI menus.
  • proxyParam: Unique 2-to-4 character query flag used by the Stream API HLS proxy (must not collide with existing flags).
  • timeout: Maximum execution budget before aborting (typically 8,000ms–15,000ms).
  • jitter: Random delay ceiling (typically 300ms–500ms) to avoid server burst locks.

Step 3: Local Testing

Run your scraper against known TMDB titles using the test runner:

# Test a known movie (The Dark Knight - TMDB 155)
node test/index.js mysource 155

# Test a known TV episode (Breaking Bad S01E01 - TMDB 1396)
node test/index.js mysource 1396 1 1

Verify that:

  1. A valid URL is printed.
  2. The type is correctly identified as 'hls' or 'mp4'.
  3. Required upstream headers (Referer, Origin, User-Agent) are included.
  4. Testing an invalid ID throws a clean error without crashing the process.

Contribution Rules & Checklist

Before submitting a Pull Request to the GitLab repository:

  • Code is formatted with clean ES Module syntax.
  • No hardcoded personal API keys or credentials.
  • Provider does not execute external untrusted eval() or un-sanitized script execution.
  • Upstream stream candidate URLs must be verified for playback.
  • Errors are thrown with informative messages (throw new Error(...)).