@media-engine/providers 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -242
- package/README.ru.md +204 -0
- package/dist/aniliberty-streaming/client.d.ts +33 -0
- package/dist/aniliberty-streaming/client.js +188 -0
- package/dist/aniliberty-streaming/client.js.map +1 -0
- package/dist/aniliberty-streaming/config.d.ts +24 -0
- package/dist/aniliberty-streaming/config.js +61 -0
- package/dist/aniliberty-streaming/config.js.map +1 -0
- package/dist/aniliberty-streaming/index.d.ts +4 -0
- package/dist/aniliberty-streaming/index.js +45 -0
- package/dist/aniliberty-streaming/index.js.map +1 -0
- package/dist/aniliberty-streaming/mapping.d.ts +3 -0
- package/dist/aniliberty-streaming/mapping.js +87 -0
- package/dist/aniliberty-streaming/mapping.js.map +1 -0
- package/dist/aniliberty-streaming/matching.d.ts +4 -0
- package/dist/aniliberty-streaming/matching.js +44 -0
- package/dist/aniliberty-streaming/matching.js.map +1 -0
- package/dist/anilist/graphql.d.ts +2 -0
- package/dist/anilist/graphql.js +135 -0
- package/dist/anilist/graphql.js.map +1 -0
- package/dist/anilist/index.js +11 -6
- package/dist/anilist/index.js.map +1 -1
- package/dist/bitsearch-torrent/client.d.ts +19 -0
- package/dist/bitsearch-torrent/client.js +181 -0
- package/dist/bitsearch-torrent/client.js.map +1 -0
- package/dist/bitsearch-torrent/config.d.ts +26 -0
- package/dist/bitsearch-torrent/config.js +74 -0
- package/dist/bitsearch-torrent/config.js.map +1 -0
- package/dist/bitsearch-torrent/index.d.ts +4 -0
- package/dist/bitsearch-torrent/index.js +35 -0
- package/dist/bitsearch-torrent/index.js.map +1 -0
- package/dist/bitsearch-torrent/mapping.d.ts +3 -0
- package/dist/bitsearch-torrent/mapping.js +53 -0
- package/dist/bitsearch-torrent/mapping.js.map +1 -0
- package/dist/bitsearch-torrent/matching.d.ts +3 -0
- package/dist/bitsearch-torrent/matching.js +13 -0
- package/dist/bitsearch-torrent/matching.js.map +1 -0
- package/dist/bitsearch-torrent/quota.d.ts +9 -0
- package/dist/bitsearch-torrent/quota.js +53 -0
- package/dist/bitsearch-torrent/quota.js.map +1 -0
- package/dist/cinemeta/index.js +53 -35
- package/dist/cinemeta/index.js.map +1 -1
- package/dist/ddbb-streaming/client.d.ts +24 -0
- package/dist/ddbb-streaming/client.js +98 -0
- package/dist/ddbb-streaming/client.js.map +1 -0
- package/dist/ddbb-streaming/config.d.ts +31 -0
- package/dist/ddbb-streaming/config.js +67 -0
- package/dist/ddbb-streaming/config.js.map +1 -0
- package/dist/ddbb-streaming/index.d.ts +4 -0
- package/dist/ddbb-streaming/index.js +53 -0
- package/dist/ddbb-streaming/index.js.map +1 -0
- package/dist/ddbb-streaming/mapping.d.ts +8 -0
- package/dist/ddbb-streaming/mapping.js +164 -0
- package/dist/ddbb-streaming/mapping.js.map +1 -0
- package/dist/ddbb-streaming/validation.d.ts +3 -0
- package/dist/ddbb-streaming/validation.js +84 -0
- package/dist/ddbb-streaming/validation.js.map +1 -0
- package/dist/experimental-streaming/index.js +55 -0
- package/dist/experimental-streaming/index.js.map +1 -1
- package/dist/flixhq-streaming/client.d.ts +12 -0
- package/dist/flixhq-streaming/client.js +103 -0
- package/dist/flixhq-streaming/client.js.map +1 -0
- package/dist/flixhq-streaming/index.d.ts +2 -2
- package/dist/flixhq-streaming/index.js +67 -106
- package/dist/flixhq-streaming/index.js.map +1 -1
- package/dist/imdb-dataset/index.d.ts +20 -5
- package/dist/imdb-dataset/index.js +83 -197
- package/dist/imdb-dataset/index.js.map +1 -1
- package/dist/imdb-dataset/memory-storage.d.ts +7 -0
- package/dist/imdb-dataset/memory-storage.js +168 -0
- package/dist/imdb-dataset/memory-storage.js.map +1 -0
- package/dist/imdb-dataset/sqlite-import.d.ts +24 -0
- package/dist/imdb-dataset/sqlite-import.js +298 -0
- package/dist/imdb-dataset/sqlite-import.js.map +1 -0
- package/dist/imdb-dataset/sqlite-runtime.d.ts +3 -0
- package/dist/imdb-dataset/sqlite-runtime.js +11 -0
- package/dist/imdb-dataset/sqlite-runtime.js.map +1 -0
- package/dist/imdb-dataset/sqlite-schema.d.ts +6 -0
- package/dist/imdb-dataset/sqlite-schema.js +88 -0
- package/dist/imdb-dataset/sqlite-schema.js.map +1 -0
- package/dist/imdb-dataset/sqlite-storage.d.ts +12 -0
- package/dist/imdb-dataset/sqlite-storage.js +208 -0
- package/dist/imdb-dataset/sqlite-storage.js.map +1 -0
- package/dist/imdb-dataset/storage.d.ts +33 -0
- package/dist/imdb-dataset/storage.js +2 -0
- package/dist/imdb-dataset/storage.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/jacred-torrent/client.d.ts +24 -0
- package/dist/jacred-torrent/client.js +254 -0
- package/dist/jacred-torrent/client.js.map +1 -0
- package/dist/jacred-torrent/config.d.ts +24 -0
- package/dist/jacred-torrent/config.js +70 -0
- package/dist/jacred-torrent/config.js.map +1 -0
- package/dist/jacred-torrent/index.d.ts +4 -0
- package/dist/jacred-torrent/index.js +45 -0
- package/dist/jacred-torrent/index.js.map +1 -0
- package/dist/jacred-torrent/mapping.d.ts +3 -0
- package/dist/jacred-torrent/mapping.js +129 -0
- package/dist/jacred-torrent/mapping.js.map +1 -0
- package/dist/jacred-torrent/matching.d.ts +3 -0
- package/dist/jacred-torrent/matching.js +19 -0
- package/dist/jacred-torrent/matching.js.map +1 -0
- package/dist/kinobd/index.js +15 -33
- package/dist/kinobd/index.js.map +1 -1
- package/dist/kinobd-streaming/availability.d.ts +3 -0
- package/dist/kinobd-streaming/availability.js +179 -0
- package/dist/kinobd-streaming/availability.js.map +1 -0
- package/dist/kinobd-streaming/candidates.d.ts +32 -0
- package/dist/kinobd-streaming/candidates.js +282 -0
- package/dist/kinobd-streaming/candidates.js.map +1 -0
- package/dist/kinobd-streaming/config.d.ts +64 -0
- package/dist/kinobd-streaming/config.js +129 -0
- package/dist/kinobd-streaming/config.js.map +1 -0
- package/dist/kinobd-streaming/index.d.ts +3 -30
- package/dist/kinobd-streaming/index.js +2 -904
- package/dist/kinobd-streaming/index.js.map +1 -1
- package/dist/kinobd-streaming/players.d.ts +24 -0
- package/dist/kinobd-streaming/players.js +270 -0
- package/dist/kinobd-streaming/players.js.map +1 -0
- package/dist/kinobd-streaming/request-budget.d.ts +15 -0
- package/dist/kinobd-streaming/request-budget.js +61 -0
- package/dist/kinobd-streaming/request-budget.js.map +1 -0
- package/dist/kinobd-streaming/validation.d.ts +11 -0
- package/dist/kinobd-streaming/validation.js +170 -0
- package/dist/kinobd-streaming/validation.js.map +1 -0
- package/dist/magnetz-torrent/client.d.ts +16 -0
- package/dist/magnetz-torrent/client.js +235 -0
- package/dist/magnetz-torrent/client.js.map +1 -0
- package/dist/magnetz-torrent/config.d.ts +27 -0
- package/dist/magnetz-torrent/config.js +73 -0
- package/dist/magnetz-torrent/config.js.map +1 -0
- package/dist/magnetz-torrent/index.d.ts +4 -0
- package/dist/magnetz-torrent/index.js +35 -0
- package/dist/magnetz-torrent/index.js.map +1 -0
- package/dist/magnetz-torrent/mapping.d.ts +3 -0
- package/dist/magnetz-torrent/mapping.js +52 -0
- package/dist/magnetz-torrent/mapping.js.map +1 -0
- package/dist/magnetz-torrent/matching.d.ts +3 -0
- package/dist/magnetz-torrent/matching.js +5 -0
- package/dist/magnetz-torrent/matching.js.map +1 -0
- package/dist/magnetz-torrent/request-gate.d.ts +9 -0
- package/dist/magnetz-torrent/request-gate.js +48 -0
- package/dist/magnetz-torrent/request-gate.js.map +1 -0
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.js +5 -0
- package/dist/package-version.js.map +1 -0
- package/dist/shared/abort.d.ts +3 -0
- package/dist/shared/abort.js +30 -0
- package/dist/shared/abort.js.map +1 -0
- package/dist/shared/http.d.ts +13 -2
- package/dist/shared/http.js +77 -75
- package/dist/shared/http.js.map +1 -1
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.js +2 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/mapping.d.ts +5 -0
- package/dist/shared/mapping.js +32 -0
- package/dist/shared/mapping.js.map +1 -0
- package/dist/shared/options.d.ts +1 -0
- package/dist/shared/options.js +10 -0
- package/dist/shared/options.js.map +1 -0
- package/dist/shared/output-url.d.ts +2 -0
- package/dist/shared/output-url.js +50 -0
- package/dist/shared/output-url.js.map +1 -0
- package/dist/shared/rate-limit.d.ts +11 -0
- package/dist/shared/rate-limit.js +52 -0
- package/dist/shared/rate-limit.js.map +1 -0
- package/dist/shared/response-body.d.ts +6 -0
- package/dist/shared/response-body.js +109 -0
- package/dist/shared/response-body.js.map +1 -0
- package/dist/shared/retry.d.ts +10 -0
- package/dist/shared/retry.js +31 -0
- package/dist/shared/retry.js.map +1 -0
- package/dist/shared/safe-fetch.d.ts +14 -0
- package/dist/shared/safe-fetch.js +274 -0
- package/dist/shared/safe-fetch.js.map +1 -0
- package/dist/shared/torrent-release-matching.d.ts +7 -0
- package/dist/shared/torrent-release-matching.js +143 -0
- package/dist/shared/torrent-release-matching.js.map +1 -0
- package/dist/shared/torrent-release-metadata.d.ts +4 -0
- package/dist/shared/torrent-release-metadata.js +95 -0
- package/dist/shared/torrent-release-metadata.js.map +1 -0
- package/dist/shikimori/index.js +19 -11
- package/dist/shikimori/index.js.map +1 -1
- package/dist/tvmaze/index.d.ts +11 -0
- package/dist/tvmaze/index.js +274 -0
- package/dist/tvmaze/index.js.map +1 -0
- package/dist/wikidata/cache.d.ts +11 -0
- package/dist/wikidata/cache.js +30 -0
- package/dist/wikidata/cache.js.map +1 -0
- package/dist/wikidata/candidates.d.ts +12 -0
- package/dist/wikidata/candidates.js +67 -0
- package/dist/wikidata/candidates.js.map +1 -0
- package/dist/wikidata/client.d.ts +40 -0
- package/dist/wikidata/client.js +224 -0
- package/dist/wikidata/client.js.map +1 -0
- package/dist/wikidata/index.d.ts +3 -0
- package/dist/wikidata/index.js +34 -111
- package/dist/wikidata/index.js.map +1 -1
- package/dist/yts-torrent/client.d.ts +25 -0
- package/dist/yts-torrent/client.js +163 -0
- package/dist/yts-torrent/client.js.map +1 -0
- package/dist/yts-torrent/config.d.ts +22 -0
- package/dist/yts-torrent/config.js +57 -0
- package/dist/yts-torrent/config.js.map +1 -0
- package/dist/yts-torrent/index.d.ts +4 -0
- package/dist/yts-torrent/index.js +42 -0
- package/dist/yts-torrent/index.js.map +1 -0
- package/dist/yts-torrent/mapping.d.ts +4 -0
- package/dist/yts-torrent/mapping.js +107 -0
- package/dist/yts-torrent/mapping.js.map +1 -0
- package/package.json +23 -6
package/README.md
CHANGED
|
@@ -1,295 +1,202 @@
|
|
|
1
1
|
# @media-engine/providers
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**English** | [Русский](https://github.com/Yaneart/media-engine/blob/main/packages/providers/README.ru.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Ready-to-use data sources for Media Engine.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## Install
|
|
7
|
+
Install this package when you do not want to write your own provider adapters.
|
|
10
8
|
|
|
11
9
|
```bash
|
|
12
10
|
npm install @media-engine/core @media-engine/providers
|
|
13
11
|
```
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Current structure:
|
|
18
|
-
|
|
19
|
-
```txt
|
|
20
|
-
src/
|
|
21
|
-
shared/
|
|
22
|
-
kinobd/
|
|
23
|
-
cinemeta/
|
|
24
|
-
shikimori/
|
|
25
|
-
anilist/
|
|
26
|
-
wikidata/
|
|
27
|
-
imdb-dataset/
|
|
28
|
-
experimental-streaming/
|
|
29
|
-
kinobd-streaming/
|
|
30
|
-
flixhq-streaming/
|
|
31
|
-
index.ts
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
No API keys or environment reads are stored in this package. Applications pass provider secrets from the outside.
|
|
35
|
-
|
|
36
|
-
Streaming providers in this package return normalized embed/player access metadata. They do not make Media Engine a streaming service, do not host video, and do not extract direct video files by default. Review each upstream source's usage rules before enabling a provider in a product.
|
|
37
|
-
|
|
38
|
-
## KinoBD Provider
|
|
39
|
-
|
|
40
|
-
`kinobdProvider` creates a no-token metadata provider for movies and series through the public KinoBD API used by ReYohoho-style clients.
|
|
13
|
+
## A small setup
|
|
41
14
|
|
|
42
15
|
```ts
|
|
43
16
|
import { MediaEngine } from "@media-engine/core";
|
|
44
|
-
import {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
17
|
+
import {
|
|
18
|
+
aniListProvider,
|
|
19
|
+
ddbbStreamingProvider,
|
|
20
|
+
flixHqStreamingProvider,
|
|
21
|
+
kinobdProvider,
|
|
22
|
+
kinobdStreamingProvider,
|
|
23
|
+
shikimoriProvider,
|
|
24
|
+
tvMazeProvider,
|
|
25
|
+
} from "@media-engine/providers";
|
|
26
|
+
|
|
27
|
+
const media = new MediaEngine({
|
|
28
|
+
providers: [kinobdProvider(), shikimoriProvider(), aniListProvider(), tvMazeProvider()],
|
|
48
29
|
});
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Supported data:
|
|
52
30
|
|
|
53
|
-
|
|
54
|
-
- IMDb and Kinopoisk ID lookup;
|
|
55
|
-
- movie and series details;
|
|
56
|
-
- posters, Kinopoisk ratings, IMDb ratings, genres, countries, and persons when available;
|
|
57
|
-
- configurable `imageLimit` and `personLimit` for details payloads.
|
|
58
|
-
|
|
59
|
-
KinoBD is the first no-token movie and series provider for the local API stand because it returns practical Russian metadata, Kinopoisk IDs, IMDb IDs, ratings, and posters without requiring a user token.
|
|
60
|
-
|
|
61
|
-
## Cinemeta Provider
|
|
62
|
-
|
|
63
|
-
`cinemetaProvider` creates a no-token metadata provider for movies and series through the public Cinemeta/Stremio metadata API.
|
|
64
|
-
|
|
65
|
-
```ts
|
|
66
|
-
import { MediaEngine } from "@media-engine/core";
|
|
67
|
-
import { cinemetaProvider } from "@media-engine/providers";
|
|
68
|
-
|
|
69
|
-
const engine = new MediaEngine({
|
|
70
|
-
providers: [cinemetaProvider()],
|
|
71
|
-
});
|
|
31
|
+
const result = await media.search({ title: "One Piece" });
|
|
72
32
|
```
|
|
73
33
|
|
|
74
|
-
|
|
34
|
+
Add only the providers that make sense for your application. Media Engine will call compatible ones and merge matching answers.
|
|
75
35
|
|
|
76
|
-
|
|
77
|
-
- IMDb ID lookup;
|
|
78
|
-
- movie and series details;
|
|
79
|
-
- posters, backdrops, IMDb ratings, genres, cast, writers, and directors when available;
|
|
80
|
-
- configurable `imageLimit`, `personLimit`, and `enrichSearchLimit`.
|
|
36
|
+
## Available metadata sources
|
|
81
37
|
|
|
82
|
-
|
|
38
|
+
- `kinobdProvider()` — localized movie and series data;
|
|
39
|
+
- `cinemetaProvider()` — IMDb-linked movie and series data;
|
|
40
|
+
- `shikimoriProvider()` — anime search and details;
|
|
41
|
+
- `aniListProvider()` — international anime titles, popularity, and artwork;
|
|
42
|
+
- `tvMazeProvider()` — fallback IMDb-backed series identities and localized aliases;
|
|
43
|
+
- `wikidataProvider()` — fallback structured identity and metadata enrichment;
|
|
44
|
+
- `imdbDatasetProvider()` — local IMDb data supplied as small in-memory TSV fixtures or through an application-owned indexed storage adapter.
|
|
83
45
|
|
|
84
|
-
|
|
46
|
+
None of these built-in providers needs your API key. TMDB IDs may appear in results, but this package does not call the TMDB API.
|
|
85
47
|
|
|
86
|
-
|
|
48
|
+
TVmaze data is licensed under CC BY-SA. The provider keeps a TVmaze show URL in source attribution; applications using TVmaze data should preserve and render that link. See the [TVmaze API licensing terms](https://www.tvmaze.com/api#licensing).
|
|
87
49
|
|
|
88
|
-
|
|
89
|
-
import { MediaEngine } from "@media-engine/core";
|
|
90
|
-
import { shikimoriProvider } from "@media-engine/providers";
|
|
91
|
-
|
|
92
|
-
const engine = new MediaEngine({
|
|
93
|
-
providers: [
|
|
94
|
-
shikimoriProvider({
|
|
95
|
-
userAgent: "MyApp/1.0.0",
|
|
96
|
-
}),
|
|
97
|
-
],
|
|
98
|
-
});
|
|
99
|
-
```
|
|
50
|
+
Wikidata fallback discovery loads at most three title-relevant entities through a selected-property query and caches entity/IMDb mappings for six hours in a 256-entry process-local LRU by default. `entityLimit` is bounded to 1–10, `cacheTtlMs` to 0–7 days, and `cacheMaxEntries` to 2–2048; a zero TTL disables this provider-local cache.
|
|
100
51
|
|
|
101
|
-
|
|
52
|
+
The backward-compatible IMDb TSV adapter parses the complete input into memory and is intended for small datasets and fixtures. Full-dataset integrations can inject the exported synchronous/asynchronous `ImdbDatasetStorage` contract, including a direct ID lookup and bounded normalized title search, without adding a database dependency for other package users.
|
|
102
53
|
|
|
103
|
-
|
|
104
|
-
- Shikimori ID lookup;
|
|
105
|
-
- anime details;
|
|
106
|
-
- posters, screenshots, ratings, genres, persons, episodes, and alternative titles;
|
|
107
|
-
- Shikimori and MyAnimeList external IDs in normalized results.
|
|
54
|
+
An included persisted adapter can stream plain or gzip IMDb TSV files into a versioned, atomically replaced SQLite/FTS index. `buildImdbDatasetSqliteIndex()` creates it and `openImdbDatasetSqliteStorage()` opens it read-only for `imdbDatasetProvider({ storage })`. This optional path lazily uses built-in `node:sqlite` and requires Node.js 22.13 or newer; importing the package or using the small in-memory adapter keeps the Node.js 20 baseline.
|
|
108
55
|
|
|
109
|
-
|
|
56
|
+
Expected upstream failures are reported as typed `ProviderError` values, and shared HTTP errors expose their originating status through `getProviderHttpStatus`. An untyped Cinemeta IMDb lookup returns `null` only after both movie and series candidates confirm absence; a temporary branch outage remains retryable unless the other branch returned usable details. AniList similarly distinguishes GraphQL rate limits and server outages from validation errors or malformed payloads, allowing Media Engine to avoid caching incomplete metadata as a healthy response.
|
|
110
57
|
|
|
111
|
-
|
|
58
|
+
Shared `fetchJson` calls stream at most 4 MiB by default before parsing and accept a positive `maxResponseBytes` override for provider-specific limits. A declared or chunked oversized body is cancelled and reported as the non-retryable `PROVIDER_RESPONSE_TOO_LARGE`; malformed JSON within the limit remains `PROVIDER_INVALID_RESPONSE`.
|
|
112
59
|
|
|
113
|
-
|
|
60
|
+
Low-level adapters may supply a `ProviderHttpScheduler` through `FetchJsonOptions.scheduler` when
|
|
61
|
+
they need deterministic control of retry and total-timeout timers, especially in tests. Normal
|
|
62
|
+
provider calls omit it and use the platform timers.
|
|
114
63
|
|
|
115
|
-
|
|
116
|
-
import { aniListProvider } from "@media-engine/providers";
|
|
117
|
-
|
|
118
|
-
const engine = new MediaEngine({
|
|
119
|
-
providers: [aniListProvider()],
|
|
120
|
-
});
|
|
121
|
-
```
|
|
64
|
+
## Player sources
|
|
122
65
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
`
|
|
66
|
+
- `kinobdStreamingProvider()` — movie, series, and anime player options;
|
|
67
|
+
- `flixHqStreamingProvider()` — international movie and selected series-episode options;
|
|
68
|
+
- `ddbbStreamingProvider()` — opt-in Kinopoisk/IMDb lookup through an independent DDBB player route;
|
|
69
|
+
- `aniLibertyStreamingProvider()` — opt-in exact title/year anime lookup with direct HLS episodes;
|
|
70
|
+
- `experimentalStreamingProvider()` — data configured by your own application, useful in tests and UI work.
|
|
128
71
|
|
|
129
72
|
```ts
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
73
|
+
const media = new MediaEngine({
|
|
74
|
+
streamingProviders: [
|
|
75
|
+
kinobdStreamingProvider(),
|
|
76
|
+
flixHqStreamingProvider(),
|
|
77
|
+
],
|
|
135
78
|
});
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Supported data:
|
|
139
|
-
|
|
140
|
-
- title search for movies and series;
|
|
141
|
-
- IMDb ID lookup through Wikidata;
|
|
142
|
-
- basic details with title, description, release date, image, and IMDb ID when present.
|
|
143
79
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
```ts
|
|
151
|
-
import { imdbDatasetProvider } from "@media-engine/providers";
|
|
152
|
-
|
|
153
|
-
const provider = imdbDatasetProvider({
|
|
154
|
-
titleBasicsTsv: titleBasicsFileContent,
|
|
155
|
-
titleRatingsTsv: titleRatingsFileContent,
|
|
80
|
+
const result = await media.getAvailability({
|
|
81
|
+
type: "series",
|
|
82
|
+
title: "Game of Thrones",
|
|
83
|
+
seasonNumber: 1,
|
|
84
|
+
episodeNumber: 1,
|
|
156
85
|
});
|
|
157
86
|
```
|
|
158
87
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
- title search for movies and series;
|
|
162
|
-
- IMDb ID lookup;
|
|
163
|
-
- basic details from `title.basics.tsv`;
|
|
164
|
-
- IMDb ratings from `title.ratings.tsv` when provided.
|
|
165
|
-
|
|
166
|
-
Before using this provider, download the official IMDb datasets and verify that your use complies with IMDb's non-commercial dataset terms.
|
|
167
|
-
|
|
168
|
-
## Experimental Streaming Provider
|
|
88
|
+
These are third-party player targets, not videos hosted by Media Engine. Availability depends on the upstream source and the user's environment.
|
|
169
89
|
|
|
170
|
-
|
|
90
|
+
The repository API enables `ddbbStreamingProvider()` after its repeated reliability/diversity
|
|
91
|
+
checkpoint; direct package consumers still choose their own provider list explicitly. It accepts
|
|
92
|
+
only Kinopoisk or IMDb IDs, returns generic movie/series/anime embeds, and does not claim exact
|
|
93
|
+
season/episode mapping. Its diversity-first mapping keeps one main option per returned player before
|
|
94
|
+
adding unique translation URLs. Missing nullable players produce no result; confirmed 404/410 or
|
|
95
|
+
stable deletion markers are removed, while transient validation failures remain `unknown`.
|
|
171
96
|
|
|
172
97
|
```ts
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
type: "anime",
|
|
180
|
-
title: "Example Anime",
|
|
181
|
-
ids: {
|
|
182
|
-
shikimori: "20",
|
|
183
|
-
},
|
|
184
|
-
episodes: [
|
|
185
|
-
{
|
|
186
|
-
absoluteEpisodeNumber: 1,
|
|
187
|
-
options: [
|
|
188
|
-
{
|
|
189
|
-
id: "example-episode-1",
|
|
190
|
-
player: {
|
|
191
|
-
kind: "embed",
|
|
192
|
-
label: "Embed Player",
|
|
193
|
-
},
|
|
194
|
-
translation: {
|
|
195
|
-
title: "AniDUB",
|
|
196
|
-
type: "dub",
|
|
197
|
-
language: "ru",
|
|
198
|
-
},
|
|
199
|
-
quality: {
|
|
200
|
-
label: "720p",
|
|
201
|
-
height: 720,
|
|
202
|
-
},
|
|
203
|
-
access: {
|
|
204
|
-
url: "https://example.test/embed/episode-1",
|
|
205
|
-
},
|
|
206
|
-
availability: "available",
|
|
207
|
-
},
|
|
208
|
-
],
|
|
209
|
-
},
|
|
210
|
-
],
|
|
211
|
-
},
|
|
98
|
+
const media = new MediaEngine({
|
|
99
|
+
streamingProviders: [
|
|
100
|
+
kinobdStreamingProvider(),
|
|
101
|
+
flixHqStreamingProvider(),
|
|
102
|
+
ddbbStreamingProvider(), // explicit opt-in
|
|
103
|
+
aniLibertyStreamingProvider(), // explicit opt-in
|
|
212
104
|
],
|
|
213
105
|
});
|
|
214
106
|
```
|
|
215
107
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
108
|
+
The repository API also enables `aniLibertyStreamingProvider()` after that checkpoint. Because
|
|
109
|
+
AniLiberty does not publish MAL, AniList, or Shikimori IDs for releases, the adapter requires both
|
|
110
|
+
title and year, accepts only one exact normalized match, and revalidates the loaded release before
|
|
111
|
+
returning streams. It supports generic episode maps and exact `absoluteEpisodeNumber` queries, but
|
|
112
|
+
does not guess season/episode mappings. Each safe first-party 480p/720p/1080p URL is returned as
|
|
113
|
+
direct HLS; release geo and copyright blocks are preserved as normalized availability states.
|
|
114
|
+
|
|
115
|
+
Live player validation removes an option only after HTTP 404/410 or a stable deletion marker. Rate limits, server errors, network failures, and validation timeouts keep the discovered option with `availability: "unknown"`, allowing the engine to expose the degradation and retry it instead of caching a transiently reduced result.
|
|
116
|
+
|
|
117
|
+
KinoBD bounds one availability lookup to 24 child HTTP attempts by default and validates at most eight discovered players through three workers. Public tuning remains bounded (`childRequestLimit` up to 64, `playerValidationLimit` up to 16, and `playerValidationConcurrency` up to 4). Nested iframe validation starts only when the fixed provider deadline can still grant a full validation window. `onPlayerAudit` receives additive `metrics` for discovered and validated players, limit/budget skips, transient unknown results, confirmed removals, and consumed child requests.
|
|
118
|
+
|
|
119
|
+
FlixHQ site navigation cannot leave its configured origin, including through redirects. External player and subtitle checks resolve every A/AAAA answer, reject private, local, reserved, multicast, or mixed public/private destinations, validate every bounded redirect hop, and pin the connection to the approved address. A custom provider `fetch` is an explicit trusted transport injection intended for controlled tests or self-hosted environments; it is responsible for equivalent network policy.
|
|
120
|
+
|
|
121
|
+
DDBB caps its JSON response, output option count, live validation count, validation concurrency,
|
|
122
|
+
validation body size, and per-player timeout. Its default transport applies the same hardened DNS,
|
|
123
|
+
redirect, and connection-pinning policy to the DDBB endpoint and returned players. A custom `fetch`
|
|
124
|
+
is the same explicit trusted test/self-hosted boundary used by the other streaming providers. Options
|
|
125
|
+
beyond the bounded validation count remain visible with `availability: "unknown"`; they are never
|
|
126
|
+
presented as successfully checked. Alloha is represented by one main option because voiceovers can
|
|
127
|
+
be switched inside that player; if no main iframe exists, at most one safe translation URL becomes
|
|
128
|
+
the entry point. Other player families keep their distinct translation options.
|
|
129
|
+
|
|
130
|
+
AniLiberty bounds search candidates, release episodes, JSON bytes, retries, and total provider time
|
|
131
|
+
through the shared engine/provider controls. Its default transport uses the hardened DNS, redirect,
|
|
132
|
+
and connection-pinning policy for API calls. Direct HLS targets still pass the shared browser-facing
|
|
133
|
+
output URL policy; playback network policy remains the consuming application's responsibility.
|
|
134
|
+
|
|
135
|
+
Before built-in providers expose artwork, player, or subtitle URLs, one output policy accepts only HTTP(S) targets without credentials, raw control characters, or literal local/private/reserved addresses. Valid paths and CDN query parameters, including expiring signatures, are preserved. This browser-facing check does not replace DNS validation or an application-owned media proxy.
|
|
136
|
+
|
|
137
|
+
## Torrent discovery sources
|
|
138
|
+
|
|
139
|
+
`ytsTorrentProvider()` is an opt-in no-key movie source. It resolves an exact IMDb identity or one
|
|
140
|
+
exact title/year match and returns normalized 720p/1080p/2160p-style magnet candidates with size,
|
|
141
|
+
release metadata, and best-effort peer counts.
|
|
142
|
+
|
|
143
|
+
`jacRedTorrentProvider()` is an opt-in no-key Russian/multilingual source for exact title/year
|
|
144
|
+
movie, series, and anime lookup. It can filter a requested season, but intentionally returns no
|
|
145
|
+
result for exact ordinary or absolute episode queries. Returned title, year, category, season,
|
|
146
|
+
info hash, source URL, release metadata, and peer fields are bounded and revalidated. Each result
|
|
147
|
+
also retains the bounded JacRed tracker ID as `catalogSource`; known values receive labels such as
|
|
148
|
+
BitRu, RuTracker, RuTor, Kinozal, NNM-Club, and Knaben without implying a guaranteed audio
|
|
149
|
+
language. Its
|
|
150
|
+
`baseUrl` and `searchPath` are configurable because the live first-party route and published route
|
|
151
|
+
currently differ.
|
|
152
|
+
|
|
153
|
+
`bitsearchTorrentProvider()` is an opt-in no-key broad international source. It requires title and
|
|
154
|
+
year, pins movie/TV/anime categories, and revalidates the exact release title, explicit year, media
|
|
155
|
+
type, requested season, and requested ordinary or absolute episode before returning a candidate.
|
|
156
|
+
It consumes only the documented bounded search response, remembers an exhausted anonymous quota
|
|
157
|
+
from `X-RateLimit-*`, and emits one canonical magnet per validated info hash. The public anonymous
|
|
158
|
+
tier is currently limited to 200 requests/day per IP, so applications should keep engine caching
|
|
159
|
+
enabled and avoid speculative calls.
|
|
160
|
+
|
|
161
|
+
`magnetzTorrentProvider()` is an opt-in no-key international meta-search source. It performs one
|
|
162
|
+
bounded first-page search request, then revalidates exact title, year, season, and ordinary or
|
|
163
|
+
absolute episode markers locally. It never fans out into per-result detail calls. The adapter emits
|
|
164
|
+
one canonical magnet per validated info hash, preserves reported peer state and source attribution,
|
|
165
|
+
and spaces request starts by one second because the live service has returned short burst 429s even
|
|
166
|
+
while its rate-limit header still reported capacity.
|
|
229
167
|
|
|
230
168
|
```ts
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
169
|
+
const media = new MediaEngine({
|
|
170
|
+
torrentProviders: [
|
|
171
|
+
ytsTorrentProvider(),
|
|
172
|
+
jacRedTorrentProvider(),
|
|
173
|
+
bitsearchTorrentProvider(),
|
|
174
|
+
magnetzTorrentProvider(),
|
|
175
|
+
],
|
|
176
|
+
providerTimeouts: {
|
|
177
|
+
"yts-torrent": 15_000,
|
|
178
|
+
"jacred-torrent": 20_000,
|
|
179
|
+
"bitsearch-torrent": 15_000,
|
|
180
|
+
"magnetz-torrent": 15_000,
|
|
242
181
|
},
|
|
243
182
|
});
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
Supported behavior:
|
|
247
|
-
|
|
248
|
-
- movie and series lookup through `/api/player/search` and `/playerdata`;
|
|
249
|
-
- anime fallback lookup by resolving a Shikimori ID through Shikimori's public API and searching KinoBD players by title;
|
|
250
|
-
- optional anime cache lookup through a configured `animeCacheBaseUrl` with `/cache_shiki` when an application has an allowed backend for it;
|
|
251
|
-
- player aggregation for the known KinoBD/ReYohoho embeddable player list, including Collaps, Vibix, Alloha, Kodik, KinoTochka, FlixCDN, Ashdi, Turbo, VideoCDN, Bazon, UStore, Pleer, VideoSpider, Iframe, Moonwalk, HDVB, CDNMovies, Lookbase, Kholobok, VideoAPI, Voidboost, Videoseed, and VK keys when upstream returns them;
|
|
252
|
-
- fallback to player iframe candidates from `/api/player/search` when `/playerdata` is unavailable or returns no usable iframe options;
|
|
253
|
-
- normalized embed player options with translation and quality metadata;
|
|
254
|
-
- best-effort translation type and language inference for labels such as Russian dubbing, Ukrainian dubbing, English subtitles, and known Russian voiceover teams including AlexFilm, HDrezka Studio, LE-Production, Shachiburi, LostFilm, AniDUB, AniLibria, and 2x2;
|
|
255
|
-
- best-effort filtering of clearly broken player pages, including HTTP 404/410/5xx and known unavailable-player HTML markers; live player page validation is bounded through `playerValidationLimit` and `playerValidationTimeoutMs`;
|
|
256
|
-
- noisy external-only or non-playback keys such as `ia`, `ext`, `netflix`, `nf`, `torrent`, `trailer`, `trailer_local`, and `youtube` are excluded from requests and filtered from upstream responses;
|
|
257
|
-
- provider filtering through `StreamQuery.providers`.
|
|
258
|
-
|
|
259
|
-
This provider does not use a Kodik API token and does not extract direct video files. It returns player/embed URLs for the application UI to render.
|
|
260
|
-
|
|
261
|
-
For live source-filter audits, pass `onPlayerAudit`. The callback reports discovered and shown player labels plus filtered labels with stable reasons such as `provider_not_allowed`, `missing_iframe`, `known_broken_url`, and `player_validation_failed`. Callback failures are isolated from normal availability behavior.
|
|
262
|
-
|
|
263
|
-
## FlixHQ Streaming Provider
|
|
264
|
-
|
|
265
|
-
`flixHqStreamingProvider` discovers international movie embeds and explicitly requested series episodes without user credentials.
|
|
266
183
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
streamingProviders: [flixHqStreamingProvider()],
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
const availability = await engine.getAvailability({
|
|
276
|
-
type: "series",
|
|
277
|
-
title: "House of the Dragon",
|
|
278
|
-
year: 2022,
|
|
279
|
-
seasonNumber: 2,
|
|
280
|
-
episodeNumber: 3,
|
|
184
|
+
const torrents = await media.discoverTorrents({
|
|
185
|
+
type: "movie",
|
|
186
|
+
title: "Inception",
|
|
187
|
+
year: 2010,
|
|
188
|
+
ids: { imdb: "tt1375666" },
|
|
281
189
|
});
|
|
282
190
|
```
|
|
283
191
|
|
|
284
|
-
The provider
|
|
285
|
-
|
|
286
|
-
|
|
192
|
+
The provider does not download torrent metadata, contact trackers, join a swarm, or play video.
|
|
193
|
+
The completed multi-source checkpoint kept repository API defaults empty: Bitsearch has a small
|
|
194
|
+
anonymous daily quota, Magnetz exposes burst-sensitive limits, and JacRed still has an occasional
|
|
195
|
+
long timeout tail. Applications can opt into any subset explicitly and monitor it with
|
|
196
|
+
`pnpm smoke:torrents`; package consumers remain in control of their own request budget.
|
|
287
197
|
|
|
288
|
-
|
|
198
|
+
Provider options, limitations, and safety rules are summarized in the [provider guide](https://github.com/Yaneart/media-engine/blob/main/docs/providers.md).
|
|
289
199
|
|
|
290
|
-
|
|
291
|
-
- `parseJsonResponse`;
|
|
292
|
-
- `mapProviderHttpError`;
|
|
293
|
-
- `mapHttpStatusToProviderErrorCode`.
|
|
200
|
+
## License
|
|
294
201
|
|
|
295
|
-
|
|
202
|
+
MIT
|