@media-engine/providers 1.0.0 → 1.1.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/LICENSE +21 -21
- package/README.md +66 -135
- package/README.ru.md +72 -139
- package/dist/filmix-streaming/client.d.ts +36 -0
- package/dist/filmix-streaming/client.js +241 -0
- package/dist/filmix-streaming/client.js.map +1 -0
- package/dist/filmix-streaming/config.d.ts +42 -0
- package/dist/filmix-streaming/config.js +93 -0
- package/dist/filmix-streaming/config.js.map +1 -0
- package/dist/filmix-streaming/index.d.ts +4 -0
- package/dist/filmix-streaming/index.js +48 -0
- package/dist/filmix-streaming/index.js.map +1 -0
- package/dist/filmix-streaming/mapping.d.ts +3 -0
- package/dist/filmix-streaming/mapping.js +109 -0
- package/dist/filmix-streaming/mapping.js.map +1 -0
- package/dist/filmix-streaming/matching.d.ts +4 -0
- package/dist/filmix-streaming/matching.js +41 -0
- package/dist/filmix-streaming/matching.js.map +1 -0
- package/dist/imdb-dataset/sqlite-import.js +5 -2
- package/dist/imdb-dataset/sqlite-import.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/package-version.d.ts +2 -2
- package/dist/package-version.js +1 -1
- package/dist/rutube-streaming/client.d.ts +18 -0
- package/dist/rutube-streaming/client.js +106 -0
- package/dist/rutube-streaming/client.js.map +1 -0
- package/dist/rutube-streaming/config.d.ts +26 -0
- package/dist/rutube-streaming/config.js +57 -0
- package/dist/rutube-streaming/config.js.map +1 -0
- package/dist/rutube-streaming/index.d.ts +4 -0
- package/dist/rutube-streaming/index.js +38 -0
- package/dist/rutube-streaming/index.js.map +1 -0
- package/dist/rutube-streaming/mapping.d.ts +4 -0
- package/dist/rutube-streaming/mapping.js +32 -0
- package/dist/rutube-streaming/mapping.js.map +1 -0
- package/dist/rutube-streaming/matching.d.ts +2 -0
- package/dist/rutube-streaming/matching.js +37 -0
- package/dist/rutube-streaming/matching.js.map +1 -0
- package/dist/shared/safe-fetch.d.ts +2 -0
- package/dist/shared/safe-fetch.js +29 -3
- package/dist/shared/safe-fetch.js.map +1 -1
- package/dist/veoveo-streaming/client.d.ts +28 -0
- package/dist/veoveo-streaming/client.js +212 -0
- package/dist/veoveo-streaming/client.js.map +1 -0
- package/dist/veoveo-streaming/config.d.ts +32 -0
- package/dist/veoveo-streaming/config.js +67 -0
- package/dist/veoveo-streaming/config.js.map +1 -0
- package/dist/veoveo-streaming/index.d.ts +4 -0
- package/dist/veoveo-streaming/index.js +46 -0
- package/dist/veoveo-streaming/index.js.map +1 -0
- package/dist/veoveo-streaming/mapping.d.ts +3 -0
- package/dist/veoveo-streaming/mapping.js +121 -0
- package/dist/veoveo-streaming/mapping.js.map +1 -0
- package/dist/videohub-streaming/client.d.ts +33 -0
- package/dist/videohub-streaming/client.js +208 -0
- package/dist/videohub-streaming/client.js.map +1 -0
- package/dist/videohub-streaming/config.d.ts +34 -0
- package/dist/videohub-streaming/config.js +73 -0
- package/dist/videohub-streaming/config.js.map +1 -0
- package/dist/videohub-streaming/index.d.ts +4 -0
- package/dist/videohub-streaming/index.js +53 -0
- package/dist/videohub-streaming/index.js.map +1 -0
- package/dist/videohub-streaming/mapping.d.ts +3 -0
- package/dist/videohub-streaming/mapping.js +84 -0
- package/dist/videohub-streaming/mapping.js.map +1 -0
- package/package.json +7 -2
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Media Engine contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Media Engine contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,79 +2,66 @@
|
|
|
2
2
|
|
|
3
3
|
**English** | [Русский](https://github.com/Yaneart/media-engine/blob/main/packages/providers/README.ru.md)
|
|
4
4
|
|
|
5
|
-
Ready-to-use data sources for Media Engine.
|
|
5
|
+
Ready-to-use data sources for Media Engine. Install this package when you want to search real public
|
|
6
|
+
catalogs without writing provider adapters yourself.
|
|
6
7
|
|
|
7
|
-
Install
|
|
8
|
+
## Install
|
|
8
9
|
|
|
9
10
|
```bash
|
|
10
11
|
npm install @media-engine/core @media-engine/providers
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
The built-in providers do not need your API keys.
|
|
15
|
+
|
|
16
|
+
## Search metadata
|
|
14
17
|
|
|
15
18
|
```ts
|
|
16
19
|
import { MediaEngine } from "@media-engine/core";
|
|
17
20
|
import {
|
|
18
21
|
aniListProvider,
|
|
19
|
-
|
|
20
|
-
flixHqStreamingProvider,
|
|
22
|
+
cinemetaProvider,
|
|
21
23
|
kinobdProvider,
|
|
22
|
-
kinobdStreamingProvider,
|
|
23
24
|
shikimoriProvider,
|
|
24
|
-
tvMazeProvider,
|
|
25
25
|
} from "@media-engine/providers";
|
|
26
26
|
|
|
27
27
|
const media = new MediaEngine({
|
|
28
|
-
providers: [
|
|
28
|
+
providers: [
|
|
29
|
+
kinobdProvider(),
|
|
30
|
+
cinemetaProvider(),
|
|
31
|
+
shikimoriProvider(),
|
|
32
|
+
aniListProvider(),
|
|
33
|
+
],
|
|
29
34
|
});
|
|
30
35
|
|
|
31
36
|
const result = await media.search({ title: "One Piece" });
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
## Available metadata sources
|
|
37
|
-
|
|
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.
|
|
45
|
-
|
|
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.
|
|
39
|
+
Connect only the sources your application needs. The engine calls suitable providers and merges
|
|
40
|
+
matching results for you.
|
|
47
41
|
|
|
48
|
-
|
|
42
|
+
Available metadata providers:
|
|
49
43
|
|
|
50
|
-
|
|
44
|
+
- `kinobdProvider()` and `cinemetaProvider()` for movies and series;
|
|
45
|
+
- `shikimoriProvider()` and `aniListProvider()` for anime;
|
|
46
|
+
- `tvMazeProvider()` and `wikidataProvider()` as additional identity sources;
|
|
47
|
+
- `imdbDatasetProvider()` for an IMDb dataset managed by your application.
|
|
51
48
|
|
|
52
|
-
|
|
49
|
+
TVmaze data requires attribution. Keep and display the TVmaze source link included in a result. See
|
|
50
|
+
the [TVmaze API license](https://www.tvmaze.com/api#licensing).
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
The optional SQLite-backed IMDb dataset tools need Node.js 22.13 or newer. Everything else in the
|
|
53
|
+
package keeps the normal Node.js 20 baseline.
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
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`.
|
|
59
|
-
|
|
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.
|
|
63
|
-
|
|
64
|
-
## Player sources
|
|
65
|
-
|
|
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.
|
|
55
|
+
## Find player options
|
|
71
56
|
|
|
72
57
|
```ts
|
|
58
|
+
import {
|
|
59
|
+
flixHqStreamingProvider,
|
|
60
|
+
kinobdStreamingProvider,
|
|
61
|
+
} from "@media-engine/providers";
|
|
62
|
+
|
|
73
63
|
const media = new MediaEngine({
|
|
74
|
-
streamingProviders: [
|
|
75
|
-
kinobdStreamingProvider(),
|
|
76
|
-
flixHqStreamingProvider(),
|
|
77
|
-
],
|
|
64
|
+
streamingProviders: [kinobdStreamingProvider(), flixHqStreamingProvider()],
|
|
78
65
|
});
|
|
79
66
|
|
|
80
67
|
const result = await media.getAvailability({
|
|
@@ -85,87 +72,38 @@ const result = await media.getAvailability({
|
|
|
85
72
|
});
|
|
86
73
|
```
|
|
87
74
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
75
|
+
The package also exports `ddbbStreamingProvider()`, `aniLibertyStreamingProvider()`,
|
|
76
|
+
`filmixStreamingProvider()`, `veoVeoStreamingProvider()`, `videoHubStreamingProvider()`,
|
|
77
|
+
`rutubeStreamingProvider()`, and
|
|
78
|
+
`experimentalStreamingProvider()`.
|
|
79
|
+
Add them explicitly when they fit your application. Filmix guest mode is capped at 480p and filters
|
|
80
|
+
known copyright/service placeholder videos. A user-owned device token raises the cap to 720p.
|
|
81
|
+
Authenticated mode requires an HTTPS `baseUrl` unless the application explicitly enables
|
|
82
|
+
`allowInsecureHttpToken` for a local compatibility test. That override sends the token without TLS
|
|
83
|
+
and must not be used in a public deployment. Returned CDN video URLs use HTTPS. VeoVeo uses DDBB only to resolve its
|
|
84
|
+
public content ID, discards the iframe token, and returns direct signed HTTPS HLS. VideoHUB uses a Kinopoisk ID and returns
|
|
85
|
+
short-lived direct MP4 qualities for movies or one exact series episode. Its links are bound to the
|
|
86
|
+
playback User-Agent and may also be bound to the requesting public IP. Pass the playback client's
|
|
87
|
+
exact User-Agent as `MediaEngineOperationOptions.playbackUserAgent`; the required value is retained
|
|
88
|
+
in each option's `access.headers` for non-browser clients.
|
|
89
|
+
Rutube performs a bounded exact title/year movie search and returns only Rutube's documented public
|
|
90
|
+
embed player. It does not expose or proxy Rutube media URLs and intentionally skips series.
|
|
91
|
+
|
|
92
|
+
These providers return third-party links or streams. Media Engine does not host the video, and an
|
|
93
|
+
external player may be unavailable in some countries, networks, or browsers.
|
|
94
|
+
|
|
95
|
+
## Discover torrent releases
|
|
96
|
+
|
|
97
|
+
Torrent providers are always opt-in:
|
|
96
98
|
|
|
97
99
|
```ts
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
],
|
|
105
|
-
});
|
|
106
|
-
```
|
|
107
|
-
|
|
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.
|
|
100
|
+
import {
|
|
101
|
+
bitsearchTorrentProvider,
|
|
102
|
+
jacRedTorrentProvider,
|
|
103
|
+
magnetzTorrentProvider,
|
|
104
|
+
ytsTorrentProvider,
|
|
105
|
+
} from "@media-engine/providers";
|
|
167
106
|
|
|
168
|
-
```ts
|
|
169
107
|
const media = new MediaEngine({
|
|
170
108
|
torrentProviders: [
|
|
171
109
|
ytsTorrentProvider(),
|
|
@@ -173,15 +111,9 @@ const media = new MediaEngine({
|
|
|
173
111
|
bitsearchTorrentProvider(),
|
|
174
112
|
magnetzTorrentProvider(),
|
|
175
113
|
],
|
|
176
|
-
providerTimeouts: {
|
|
177
|
-
"yts-torrent": 15_000,
|
|
178
|
-
"jacred-torrent": 20_000,
|
|
179
|
-
"bitsearch-torrent": 15_000,
|
|
180
|
-
"magnetz-torrent": 15_000,
|
|
181
|
-
},
|
|
182
114
|
});
|
|
183
115
|
|
|
184
|
-
const
|
|
116
|
+
const result = await media.discoverTorrents({
|
|
185
117
|
type: "movie",
|
|
186
118
|
title: "Inception",
|
|
187
119
|
year: 2010,
|
|
@@ -189,13 +121,12 @@ const torrents = await media.discoverTorrents({
|
|
|
189
121
|
});
|
|
190
122
|
```
|
|
191
123
|
|
|
192
|
-
|
|
193
|
-
|
|
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.
|
|
124
|
+
Discovery only returns normalized candidates and their handoff data. It does not download torrent
|
|
125
|
+
metadata, contact trackers, join a swarm, or play a file.
|
|
197
126
|
|
|
198
|
-
|
|
127
|
+
Public sources can change, rate-limit requests, or go offline. Keep engine caching enabled and
|
|
128
|
+
expect occasional partial results. Provider-specific settings and safety boundaries are described in
|
|
129
|
+
the [provider guide](https://github.com/Yaneart/media-engine/blob/main/docs/providers.md).
|
|
199
130
|
|
|
200
131
|
## License
|
|
201
132
|
|
package/README.ru.md
CHANGED
|
@@ -2,172 +2,111 @@
|
|
|
2
2
|
|
|
3
3
|
[English](https://github.com/Yaneart/media-engine/blob/main/packages/providers/README.md) | **Русский**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Это готовые источники данных для Media Engine. Установите пакет, если хотите искать в реальных
|
|
6
|
+
публичных каталогах и не писать адаптеры самостоятельно.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## Установка
|
|
8
9
|
|
|
9
10
|
```bash
|
|
10
11
|
npm install @media-engine/core @media-engine/providers
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Для встроенных провайдеров ваши API-ключи не нужны.
|
|
15
|
+
|
|
16
|
+
## Поиск метаданных
|
|
14
17
|
|
|
15
18
|
```ts
|
|
16
19
|
import { MediaEngine } from "@media-engine/core";
|
|
17
20
|
import {
|
|
18
21
|
aniListProvider,
|
|
19
|
-
|
|
20
|
-
flixHqStreamingProvider,
|
|
22
|
+
cinemetaProvider,
|
|
21
23
|
kinobdProvider,
|
|
22
|
-
kinobdStreamingProvider,
|
|
23
24
|
shikimoriProvider,
|
|
24
|
-
tvMazeProvider,
|
|
25
25
|
} from "@media-engine/providers";
|
|
26
26
|
|
|
27
27
|
const media = new MediaEngine({
|
|
28
|
-
providers: [
|
|
28
|
+
providers: [
|
|
29
|
+
kinobdProvider(),
|
|
30
|
+
cinemetaProvider(),
|
|
31
|
+
shikimoriProvider(),
|
|
32
|
+
aniListProvider(),
|
|
33
|
+
],
|
|
29
34
|
});
|
|
30
35
|
|
|
31
36
|
const result = await media.search({ title: "Ван-Пис" });
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
Подключайте только те
|
|
35
|
-
|
|
36
|
-
## Провайдеры метаданных
|
|
37
|
-
|
|
38
|
-
- `kinobdProvider()` — локализованные данные фильмов и сериалов;
|
|
39
|
-
- `cinemetaProvider()` — данные фильмов и сериалов, связанные с IMDb;
|
|
40
|
-
- `shikimoriProvider()` — поиск и детали аниме;
|
|
41
|
-
- `aniListProvider()` — международные названия аниме, популярность и изображения;
|
|
42
|
-
- `tvMazeProvider()` — резервные IMDb identity сериалов и локализованные aliases;
|
|
43
|
-
- `wikidataProvider()` — резервная проверка identity и обогащение открытыми структурированными данными;
|
|
44
|
-
- `imdbDatasetProvider()` — локальные данные IMDb в виде небольших in-memory TSV fixtures или через индексированный storage adapter приложения.
|
|
45
|
-
|
|
46
|
-
Для встроенных провайдеров не нужен ваш API-ключ. TMDB ID может встретиться в результате, но сам пакет не обращается к TMDB API.
|
|
39
|
+
Подключайте только те источники, которые нужны вашему приложению. Движок сам вызовет подходящие
|
|
40
|
+
провайдеры и объединит совпадающие результаты.
|
|
47
41
|
|
|
48
|
-
|
|
42
|
+
Готовые провайдеры метаданных:
|
|
49
43
|
|
|
50
|
-
|
|
44
|
+
- `kinobdProvider()` и `cinemetaProvider()` для фильмов и сериалов;
|
|
45
|
+
- `shikimoriProvider()` и `aniListProvider()` для аниме;
|
|
46
|
+
- `tvMazeProvider()` и `wikidataProvider()` как дополнительные источники идентичности;
|
|
47
|
+
- `imdbDatasetProvider()` для IMDb-датасета, которым управляет ваше приложение.
|
|
51
48
|
|
|
52
|
-
|
|
49
|
+
Данные TVmaze требуют указания источника. Сохраняйте и показывайте ссылку TVmaze, которая приходит
|
|
50
|
+
в результате. Подробности есть в [лицензии API TVmaze](https://www.tvmaze.com/api#licensing).
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
Опциональные инструменты для SQLite-индекса IMDb требуют Node.js 22.13 или новее. Для остального
|
|
53
|
+
пакета достаточно Node.js 20.
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Общий `fetchJson` по умолчанию читает потоково не больше 4 МиБ перед разбором JSON и принимает положительный `maxResponseBytes` для индивидуального лимита провайдера. Объявленное или фактическое превышение отменяет body и возвращает non-retryable `PROVIDER_RESPONSE_TOO_LARGE`; некорректный JSON в пределах лимита остаётся `PROVIDER_INVALID_RESPONSE`.
|
|
59
|
-
|
|
60
|
-
Низкоуровневые адаптеры могут передать `ProviderHttpScheduler` через
|
|
61
|
-
`FetchJsonOptions.scheduler`, когда нужен детерминированный контроль retry- и total-timeout
|
|
62
|
-
таймеров, прежде всего в тестах. Обычные provider-вызовы не задают его и используют системные
|
|
63
|
-
таймеры.
|
|
64
|
-
|
|
65
|
-
## Провайдеры плееров
|
|
66
|
-
|
|
67
|
-
- `kinobdStreamingProvider()` — варианты плееров для фильмов, сериалов и аниме;
|
|
68
|
-
- `flixHqStreamingProvider()` — международные варианты для фильмов и выбранных эпизодов сериалов;
|
|
69
|
-
- `ddbbStreamingProvider()` — opt-in поиск по Kinopoisk/IMDb через независимый маршрут DDBB;
|
|
70
|
-
- `aniLibertyStreamingProvider()` — opt-in точный поиск аниме по названию/году с прямыми HLS-сериями;
|
|
71
|
-
- `experimentalStreamingProvider()` — данные, настроенные вашим приложением для тестов и разработки интерфейса.
|
|
55
|
+
## Поиск вариантов просмотра
|
|
72
56
|
|
|
73
57
|
```ts
|
|
58
|
+
import {
|
|
59
|
+
flixHqStreamingProvider,
|
|
60
|
+
kinobdStreamingProvider,
|
|
61
|
+
} from "@media-engine/providers";
|
|
62
|
+
|
|
74
63
|
const media = new MediaEngine({
|
|
75
|
-
streamingProviders: [
|
|
76
|
-
kinobdStreamingProvider(),
|
|
77
|
-
flixHqStreamingProvider(),
|
|
78
|
-
],
|
|
64
|
+
streamingProviders: [kinobdStreamingProvider(), flixHqStreamingProvider()],
|
|
79
65
|
});
|
|
80
66
|
|
|
81
67
|
const result = await media.getAvailability({
|
|
82
68
|
type: "series",
|
|
83
|
-
title: "
|
|
69
|
+
title: "Игра престолов",
|
|
84
70
|
seasonNumber: 1,
|
|
85
71
|
episodeNumber: 1,
|
|
86
72
|
});
|
|
87
73
|
```
|
|
88
74
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
75
|
+
Пакет также экспортирует `ddbbStreamingProvider()`, `aniLibertyStreamingProvider()`,
|
|
76
|
+
`filmixStreamingProvider()`, `veoVeoStreamingProvider()`, `videoHubStreamingProvider()`,
|
|
77
|
+
`rutubeStreamingProvider()` и
|
|
78
|
+
`experimentalStreamingProvider()`.
|
|
79
|
+
Подключайте их явно, если они
|
|
80
|
+
подходят вашему приложению. Гостевой режим Filmix ограничен 480p и отбрасывает известные заглушки о
|
|
81
|
+
блокировке и служебные видео. Собственный device token повышает предел до 720p. Для авторизации
|
|
82
|
+
обязателен HTTPS `baseUrl`, если приложение явно не включило `allowInsecureHttpToken` для локальной
|
|
83
|
+
проверки совместимости. Этот режим отправляет токен без TLS и не должен использоваться в публичном
|
|
84
|
+
развёртывании. Ссылки на видео CDN используют HTTPS. VeoVeo использует DDBB только для получения публичного
|
|
85
|
+
content ID, отбрасывает iframe-токен и возвращает прямой подписанный HTTPS HLS.
|
|
86
|
+
VideoHUB ищет по ID Кинопоиска, а для сериала требует точный сезон и серию. Он возвращает
|
|
87
|
+
короткоживущие прямые MP4 в нескольких качествах. Ссылки привязаны к User-Agent проигрывающего
|
|
88
|
+
клиента и могут быть привязаны к внешнему IP. Передавайте точный User-Agent клиента через
|
|
89
|
+
`MediaEngineOperationOptions.playbackUserAgent`; для небраузерных клиентов нужное значение также
|
|
90
|
+
сохраняется в `access.headers` каждого варианта.
|
|
91
|
+
Rutube выполняет ограниченный точный поиск фильма по названию и году и возвращает только
|
|
92
|
+
официальный публичный embed-плеер Rutube. Прямые media-URL не извлекаются и не проксируются;
|
|
93
|
+
сериалы намеренно не поддерживаются.
|
|
94
|
+
|
|
95
|
+
Эти провайдеры возвращают сторонние ссылки или потоки. Media Engine не хранит видео, а внешний
|
|
96
|
+
плеер может быть недоступен в конкретной стране, сети или браузере.
|
|
97
|
+
|
|
98
|
+
## Поиск torrent-раздач
|
|
99
|
+
|
|
100
|
+
Torrent-провайдеры всегда подключаются явно:
|
|
98
101
|
|
|
99
102
|
```ts
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
],
|
|
107
|
-
});
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
После того же checkpoint API репозитория включает и `aniLibertyStreamingProvider()`. AniLiberty не
|
|
111
|
-
публикует для релизов MAL, AniList или Shikimori ID, поэтому адаптер требует одновременно название и
|
|
112
|
-
год, принимает только одно точное нормализованное совпадение и повторно проверяет загруженный релиз
|
|
113
|
-
перед возвратом потоков. Он поддерживает общую карту серий и точный `absoluteEpisodeNumber`, но не
|
|
114
|
-
угадывает season/episode. Каждый безопасный first-party URL 480p/720p/1080p возвращается как прямой
|
|
115
|
-
HLS, а географическая и copyright-блокировка релиза сохраняются в availability status.
|
|
116
|
-
|
|
117
|
-
Live-проверка удаляет вариант плеера только после HTTP 404/410 или устойчивого маркера удаления. Rate limit, ошибка сервера, сетевой сбой или timeout проверки сохраняют найденный вариант с `availability: "unknown"`, чтобы engine показал деградацию и повторил проверку вместо кеширования временно урезанного результата.
|
|
118
|
-
|
|
119
|
-
KinoBD по умолчанию ограничивает один availability lookup 24 дочерними HTTP-попытками и проверяет не больше восьми найденных плееров тремя workers. Публичная настройка также ограничена сверху (`childRequestLimit` до 64, `playerValidationLimit` до 16 и `playerValidationConcurrency` до 4). Вложенная iframe-проверка начинается, только если фиксированный deadline провайдера ещё позволяет выделить полное окно validation. Callback `onPlayerAudit` получает дополнительные `metrics`: найденные и проверенные плееры, пропуски по limit/budget, transient unknown, подтверждённые удаления и использованные дочерние запросы.
|
|
120
|
-
|
|
121
|
-
Навигация по FlixHQ не может покинуть настроенный origin, в том числе через redirects. Для внешних player/subtitle проверяются все A/AAAA-адреса, отклоняются private, local, reserved, multicast и смешанные public/private назначения, каждый ограниченный redirect hop валидируется, а соединение закрепляется за проверенным адресом. Пользовательский provider `fetch` считается явно доверенной transport-инъекцией для контролируемых тестов или self-hosted окружений и должен обеспечивать эквивалентную сетевую политику.
|
|
122
|
-
|
|
123
|
-
DDBB ограничивает размер JSON-ответа, количество output options и live validations, concurrency,
|
|
124
|
-
размер validation body и timeout каждого плеера. Его default transport применяет ту же hardened
|
|
125
|
-
политику DNS, redirects и connection pinning к endpoint DDBB и возвращённым плеерам. Пользовательский
|
|
126
|
-
`fetch` остаётся явной доверенной границей для тестов/self-hosted окружений. Варианты за пределом
|
|
127
|
-
ограниченного числа проверок остаются видимыми со статусом `availability: "unknown"` и никогда не
|
|
128
|
-
показываются как успешно проверенные. Alloha представлен одним main option, потому что озвучку
|
|
129
|
-
можно переключить внутри самого плеера; при отсутствии main iframe точкой входа становится не
|
|
130
|
-
больше одного безопасного translation URL. Остальные семейства плееров сохраняют отдельные
|
|
131
|
-
варианты переводов.
|
|
132
|
-
|
|
133
|
-
AniLiberty ограничивает число search-кандидатов и эпизодов релиза, размер JSON, retry и общее время
|
|
134
|
-
провайдера через общие engine/provider-механизмы. Default transport применяет hardened DNS,
|
|
135
|
-
redirect и connection-pinning политику к API-вызовам. Прямые HLS-цели проходят общую browser-facing
|
|
136
|
-
проверку URL; playback network policy остаётся ответственностью потребляющего приложения.
|
|
137
|
-
|
|
138
|
-
Перед публикацией artwork, player или subtitle URL встроенные провайдеры применяют одну output-политику: разрешены только HTTP(S)-цели без credentials, исходных управляющих символов и literal local/private/reserved адресов. Валидные пути и CDN query-параметры, включая временные подписи, сохраняются. Эта browser-facing проверка не заменяет DNS-валидацию или media proxy приложения.
|
|
139
|
-
|
|
140
|
-
## Источники torrent discovery
|
|
141
|
-
|
|
142
|
-
`ytsTorrentProvider()` — явно подключаемый no-key источник фильмов. Он принимает точный IMDb ID или
|
|
143
|
-
одно точное совпадение названия и года и возвращает нормализованные magnet-кандидаты вроде
|
|
144
|
-
720p/1080p/2160p с размером, сведениями о релизе и best-effort счётчиками пиров.
|
|
145
|
-
|
|
146
|
-
`jacRedTorrentProvider()` — явно подключаемый no-key русскоязычный/мультиязычный источник для
|
|
147
|
-
точного поиска фильмов, сериалов и аниме по названию и году. Он умеет фильтровать указанный сезон,
|
|
148
|
-
но намеренно не отвечает на запрос конкретной обычной или абсолютной серии. Название, год,
|
|
149
|
-
категория, сезон, info hash, source URL, сведения о релизе и счётчики пиров ограничиваются и
|
|
150
|
-
перепроверяются. Каждый результат также сохраняет ограниченный tracker ID JacRed в
|
|
151
|
-
`catalogSource`; известные значения получают подписи BitRu, RuTracker, RuTor, Kinozal, NNM-Club и
|
|
152
|
-
Knaben без ложной гарантии языка аудиодорожки. `baseUrl` и `searchPath` настраиваются, потому что фактический first-party маршрут
|
|
153
|
-
сейчас отличается от опубликованного.
|
|
154
|
-
|
|
155
|
-
`bitsearchTorrentProvider()` — явно подключаемый no-key источник с широким международным каталогом.
|
|
156
|
-
Он требует название и год, закрепляет категории movie/TV/anime и перед возвратом кандидата заново
|
|
157
|
-
проверяет точное название релиза, явно указанный год, тип медиа, запрошенный сезон и обычный или
|
|
158
|
-
абсолютный номер эпизода. Провайдер читает только ограниченный search-ответ, запоминает исчерпание
|
|
159
|
-
анонимной квоты из `X-RateLimit-*` и создаёт один канонический magnet на проверенный info hash.
|
|
160
|
-
Публичная анонимная квота сейчас составляет 200 запросов в сутки на IP, поэтому приложению следует
|
|
161
|
-
оставлять engine cache включённым и не выполнять speculative-вызовы.
|
|
162
|
-
|
|
163
|
-
`magnetzTorrentProvider()` — явно подключаемый no-key международный meta-search источник. Он делает
|
|
164
|
-
один ограниченный запрос первой страницы, затем локально перепроверяет точное название, год, сезон
|
|
165
|
-
и маркеры обычного или абсолютного эпизода. Провайдер не запускает отдельные detail-запросы для
|
|
166
|
-
каждого результата, создаёт один канонический magnet на проверенный info hash, сохраняет фактические
|
|
167
|
-
peer-счётчики и attribution и выдерживает секунду между началами запросов: live-сервис возвращал
|
|
168
|
-
короткие burst-429 даже при ненулевом остатке в rate-limit header.
|
|
103
|
+
import {
|
|
104
|
+
bitsearchTorrentProvider,
|
|
105
|
+
jacRedTorrentProvider,
|
|
106
|
+
magnetzTorrentProvider,
|
|
107
|
+
ytsTorrentProvider,
|
|
108
|
+
} from "@media-engine/providers";
|
|
169
109
|
|
|
170
|
-
```ts
|
|
171
110
|
const media = new MediaEngine({
|
|
172
111
|
torrentProviders: [
|
|
173
112
|
ytsTorrentProvider(),
|
|
@@ -175,29 +114,23 @@ const media = new MediaEngine({
|
|
|
175
114
|
bitsearchTorrentProvider(),
|
|
176
115
|
magnetzTorrentProvider(),
|
|
177
116
|
],
|
|
178
|
-
providerTimeouts: {
|
|
179
|
-
"yts-torrent": 15_000,
|
|
180
|
-
"jacred-torrent": 20_000,
|
|
181
|
-
"bitsearch-torrent": 15_000,
|
|
182
|
-
"magnetz-torrent": 15_000,
|
|
183
|
-
},
|
|
184
117
|
});
|
|
185
118
|
|
|
186
|
-
const
|
|
119
|
+
const result = await media.discoverTorrents({
|
|
187
120
|
type: "movie",
|
|
188
|
-
title: "
|
|
121
|
+
title: "Начало",
|
|
189
122
|
year: 2010,
|
|
190
123
|
ids: { imdb: "tt1375666" },
|
|
191
124
|
});
|
|
192
125
|
```
|
|
193
126
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
в API defaults: у Bitsearch небольшая суточная анонимная квота, Magnetz чувствителен к burst-нагрузке,
|
|
197
|
-
а у JacRed сохраняется редкий длинный timeout tail. Приложение явно выбирает нужное подмножество и
|
|
198
|
-
может контролировать его командой `pnpm smoke:torrents`, сохраняя собственный request budget.
|
|
127
|
+
Поиск только возвращает список кандидатов и данные для дальнейшей передачи. Он не загружает
|
|
128
|
+
torrent metadata, не обращается к trackers, не подключается к раздаче и не воспроизводит файл.
|
|
199
129
|
|
|
200
|
-
|
|
130
|
+
Публичные источники могут меняться, ограничивать запросы или временно не работать. Оставляйте кэш
|
|
131
|
+
движка включённым и будьте готовы к частичным результатам. Настройки и границы безопасности каждого
|
|
132
|
+
источника описаны в
|
|
133
|
+
[документации провайдеров](https://github.com/Yaneart/media-engine/blob/main/docs/providers.md).
|
|
201
134
|
|
|
202
135
|
## Лицензия
|
|
203
136
|
|