File size: 2,703 Bytes
3e8e34c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Standard contract every source in this folder implements. Drop a new file
// that exports a `SourceModule`, register it in ./index.ts, and it shows up in
// the player automatically — no route or UI changes needed.

export interface SourceStream {
  file: string;
  /** Quality label, e.g. "1080", "720", or "auto". */
  label: string;
  type: "hls" | "dash" | "mp4";
}

export interface SourceSubtitle {
  url: string;
  display: string;
  language: string;
  hi?: boolean;
  source?: string;
}

export interface SourceResult {
  streams: SourceStream[];
  /** The source's OWN built-in subtitles. Wyzie is added as a default on top

   *  by the route, so most sources can leave this empty. */
  subtitles?: SourceSubtitle[];
}

export interface SourceContext {
  tmdbId: number;
  /** 0 for movies. */
  season: number;
  /** 0 for movies. */
  episode: number;
  /** This deployment's origin, e.g. "https://host" — for sources that need to

   *  point at their own custom proxy route. */
  origin: string;
  /** Wrap an upstream stream URL so it's fetched via our /api/stream proxy

   *  (use when the CDN needs a Referer or hides behind hotlink protection). */
  proxyStream(url: string, referer?: string): string;
  /** Wrap an upstream subtitle URL so it's served WebVTT via our /api/sub proxy. */
  proxySub(url: string, referer?: string): string;
}

// A sub-provider inside a parent source (e.g. one of VidNest's upstreams).
export interface SubSource {
  /** Stable id within the parent, e.g. "klikxxi". */
  id: string;
  name: string;
  fetch(ctx: SourceContext): Promise<SourceResult | null>;
}

export interface SourceModule {
  /** Stable id used in URLs + persistence, e.g. "oneroom". */
  id: string;
  /** Display name shown in the player, e.g. "MovieBox". */
  name: string;
  /** Short line under the name in the server list. */
  label: string;
  /** Flip to false to hide a source without deleting the file. */
  active: boolean;
  /** Lower = listed first and tried first during failover. Defaults to 100. */
  rank?: number;
  /** Resolve playable streams (+ optional built-in subs) for a title. For a

   *  parent source this aggregates/tries its children. */
  fetch(ctx: SourceContext): Promise<SourceResult | null>;
  /** Present on "parent" sources — selectable sub-providers. The parent's own

   *  fetch tries them all; children can also be picked individually. */
  children?: SubSource[];
}

// Lightweight metadata sent to the client to build the server list.
export interface SourceMeta {
  id: string;
  name: string;
  label: string;
  children?: { id: string; name: string }[];
}