added manga integration

This commit is contained in:
2026-10-14 21:55:45 -07:00
parent 401a16d07d
commit b42f21f48a
6 changed files with 320 additions and 5 deletions

View File

@@ -44,10 +44,12 @@ TMDB_API_KEY=your_actual_tmdb_api_key_here
## Project Structure
- `src/sources/`: Scraper implementations for each provider.
- `src/manga/`: Manga catalog search and reader page resolvers.
- `src/config.js`: Source registry containing timeouts, retries, headers, and proxy flags.
- `src/downloads/downloads.js`: Downloader resolver extracting direct MP4 streams.
- `src/subtitles.js`: Subtitle mirror aggregation endpoints.
- `test/index.js`: Test runner for testing streams, subtitles, and downloads.
- `test/index.js`: Test runner for testing streams, subtitles, downloads, and manga.
```
---

View File

@@ -1,6 +1,6 @@
# SDK Reference
<p class="page-description">Scrape video streams, fetch subtitles, retrieve download links, and monitor provider health directly from your Node.js application.</p>
<p class="page-description">Scrape video streams, fetch subtitles, search manga catalogs, resolve chapter pages, retrieve download links, and monitor provider health directly from your Node.js application.</p>
The **Vyla SDK** (`@vyla-entertainment/sdk`) is a server-side JavaScript/TypeScript package that provides direct access to Vyla's stream resolvers, health probes, download resolvers, and subtitle providers.
@@ -15,11 +15,12 @@ The SDK can be used independently of the self-hosted Stream API. If you prefer t
## Features
- **Direct-to-Client Playback**: Scraped streams link directly to source CDNs. No proxy server overhead required unless specified by provider headers.
- **Manga & Comic Aggregation**: Search title catalogs, inspect volume/chapter indexes, and resolve full reader image sets.
- **Built-In Health Probing**: Monitor latency and uptime per provider with built-in health check utilities.
- **Automated Anime Sub/Dub Routing**: Automatically configures audio track requirements (`sub` vs `dub`) based on provider naming conventions.
- **Multi-Source Subtitle Aggregation**: Merges subtitle tracks from multiple redundant subtitle mirrors into a unified VTT/SRT format.
- **Metadata Fallbacks**: Automatically maps TMDB IDs to external IDs (such as IMDB and AniList) for smooth stream lookups.
- **Self-Contained**: No need to deploy a separate API server - all streaming functionality runs within your existing Node.js application.
- **Self-Contained**: No need to deploy a separate API server - all streaming and reading functionality runs within your existing Node.js application.
---
@@ -164,6 +165,14 @@ const downloads = await sdk.getDownloads("155");
const tvDownloads = await sdk.getDownloads("1399", 1, 1);
```
#### Parameters
| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `id` | `string` | **Yes** | - | TMDB media ID. |
| `s` | `string \| number` | **No** | `null` | Season number (required for TV shows). |
| `e` | `string \| number` | **No** | `null` | Episode number (required for TV shows). |
#### Example Response Format
```json
@@ -179,6 +188,131 @@ const tvDownloads = await sdk.getDownloads("1399", 1, 1);
---
### `searchManga(query, page?, perPage?)`
Searches manga catalogs by title, author, or keyword.
```javascript
const searchResults = await sdk.searchManga("Steel Ball Run", 1, 10);
```
#### Parameters
| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `query` | `string` | **Yes** | - | Search query text. |
| `page` | `number` | **No** | `1` | Page number. |
| `perPage` | `number` | **No** | `12` | Results per page limit. |
#### Example Response Format
```json
{
"page": 1,
"total": 2,
"results": [
{
"id": "aKXN8",
"title": "JoJo's Bizarre Adventure: Part 7–Steel Ball Run",
"englishTitle": null,
"authors": ["ARAKI Hirohiko"],
"type": "Manga",
"medium": "Comic",
"status": "Completed",
"year": 2004,
"rating": 9.03681428571429,
"popularity": "1.6M",
"poster": "https://cdn.atsu.moe/static/posters/nR3hGYk9GmOqgD52.jpg",
"posterSmall": "https://cdn.atsu.moe/static/posters/nR3hGYk9GmOqgD52-small.avif",
"posterMedium": "https://cdn.atsu.moe/static/posters/nR3hGYk9GmOqgD52-medium.avif"
}
]
}
```
---
### `getManga(id)`
Retrieves manga entry details, author info, synopsis, and full chapter list.
```javascript
const manga = await sdk.getManga("aKXN8");
```
#### Parameters
| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `id` | `string` | **Yes** | - | Unique manga ID. |
#### Example Response Format
```json
{
"id": "aKXN8",
"title": "JoJo's Bizarre Adventure: Part 7–Steel Ball Run",
"englishTitle": null,
"synopsis": "Riders from around the world gather in the Wild West for the race of the century...",
"status": "Completed",
"type": "Manga",
"medium": "Comic",
"rating": 9.03681428571429,
"views": "330.5K",
"authors": ["Hirohiko Araki"],
"genres": ["Action", "Adventure", "Drama"],
"tags": ["19th Century", "Seinen"],
"poster": "https://cdn.atsu.moe/static/posters/nR3hGYk9GmOqgD52.jpg",
"totalChapters": 95,
"chapters": [
{
"id": "8KyKadCx",
"number": 1,
"title": "# 1",
"pageCount": 48,
"createdAt": "2026-04-18T00:00:00.000Z"
}
]
}
```
---
### `getMangaChapter(mangaId, chapterId)`
Resolves all page image assets for a given manga chapter.
```javascript
const chapter = await sdk.getMangaChapter("aKXN8", "8KyKadCx");
```
#### Parameters
| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `mangaId` | `string` | **Yes** | - | Unique manga ID. |
| `chapterId` | `string` | **Yes** | - | Unique chapter ID. |
#### Example Response Format
```json
{
"id": "8KyKadCx",
"number": 1,
"title": "# 1",
"scanlatorId": "cmo3e2t970003ktp80ip0n5hb",
"pages": [
{
"number": 0,
"url": "https://cdn.atsu.moe/static/pages/aKXN8/8KyKadCx/0.webp",
"width": 1200,
"height": 1722,
"aspectRatio": 0.6968641114982579
}
]
}
```
## Provider & Health Management
### `getSources(excludeDisabled?)`
@@ -328,6 +462,26 @@ app.get("/api/subtitles", async (req, res) => {
}
});
app.get("/api/manga/search", async (req, res) => {
const { q, page, perPage } = req.query;
try {
const results = await sdk.searchManga(q, page || 1, perPage || 12);
return res.json(results);
} catch (error) {
return res.status(500).json({ error: error.message });
}
});
app.get("/api/manga/:mangaId/chapter/:chapterId", async (req, res) => {
const { mangaId, chapterId } = req.params;
try {
const pages = await sdk.getMangaChapter(mangaId, chapterId);
return res.json(pages);
} catch (error) {
return res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => console.log("Vyla SDK Server running on port 3000"));
```

137
sdk/vyla-sdk/manga.md Normal file
View File

@@ -0,0 +1,137 @@
# Manga Integration
<p class="page-description">Search manga catalogs, retrieve chapter listings, and resolve reader-ready page images directly with Vyla SDK.</p>
Vyla SDK provides built-in manga support to discover titles, fetch full chapter indices, and resolve high-resolution page image URLs with asset dimensions and aspect ratios.
---
## Manga Methods
### `searchManga(query, page?, perPage?)`
Searches the manga catalog for titles matching a query string.
```javascript
const searchResults = await sdk.searchManga("Steel Ball Run", 1, 10);
console.log(searchResults.results[0]);
```
#### Parameters
| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `query` | `string` | **Yes** | - | Title, author, or acronym search query. |
| `page` | `number` | **No** | `1` | Pagination page number. |
| `perPage` | `number` | **No** | `12` | Results per page. |
#### Response Format
```json
{
"page": 1,
"total": 2,
"results": [
{
"id": "aKXN8",
"title": "JoJo's Bizarre Adventure: Part 7–Steel Ball Run",
"englishTitle": null,
"authors": ["ARAKI Hirohiko"],
"type": "Manga",
"medium": "Comic",
"status": "Completed",
"year": 2004,
"rating": 9.03681428571429,
"popularity": "1.6M",
"poster": "https://cdn.atsu.moe/static/posters/nR3hGYk9GmOqgD52.jpg",
"posterSmall": "https://cdn.atsu.moe/static/posters/nR3hGYk9GmOqgD52-small.avif",
"posterMedium": "https://cdn.atsu.moe/static/posters/nR3hGYk9GmOqgD52-medium.avif"
}
]
}
```
---
### `getManga(id)`
Retrieves comprehensive details for a manga entry, including synopsis, genres, authors, and full chapter list.
```javascript
const manga = await sdk.getManga("aKXN8");
console.log(manga.title, manga.totalChapters);
```
#### Parameters
| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `id` | `string` | **Yes** | - | Unique manga identifier. |
#### Response Format
```json
{
"id": "aKXN8",
"title": "JoJo's Bizarre Adventure: Part 7–Steel Ball Run",
"englishTitle": null,
"synopsis": "Riders from around the world gather in the Wild West for the race of the century...",
"status": "Completed",
"type": "Manga",
"medium": "Comic",
"rating": 9.03681428571429,
"views": "330.5K",
"authors": ["Hirohiko Araki"],
"genres": ["Action", "Adventure", "Drama", "Historical", "Supernatural"],
"tags": ["19th Century", "Horses", "Seinen"],
"poster": "https://cdn.atsu.moe/static/posters/nR3hGYk9GmOqgD52.jpg",
"totalChapters": 95,
"chapters": [
{
"id": "8KyKadCx",
"number": 1,
"title": "# 1",
"pageCount": 48,
"createdAt": "2026-04-18T00:00:00.000Z"
}
]
}
```
---
### `getMangaChapter(mangaId, chapterId)`
Resolves all page images for a selected chapter, including pixel dimensions and aspect ratios for smooth responsive rendering.
```javascript
const chapter = await sdk.getMangaChapter("aKXN8", "8KyKadCx");
console.log(chapter.pages[0].url);
```
#### Parameters
| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `mangaId` | `string` | **Yes** | - | Unique manga identifier. |
| `chapterId` | `string` | **Yes** | - | Unique chapter identifier. |
#### Response Format
```json
{
"id": "8KyKadCx",
"number": 1,
"title": "# 1",
"scanlatorId": "cmo3e2t970003ktp80ip0n5hb",
"pages": [
{
"number": 0,
"url": "https://cdn.atsu.moe/static/pages/aKXN8/8KyKadCx/0.webp",
"width": 1200,
"height": 1722,
"aspectRatio": 0.6968641114982579
}
]
}
```

View File

@@ -56,6 +56,21 @@ console.log(candidates.map(({ url, type, quality }) => ({ url, type, quality }))
const result = await vyla.getStream(provider.key, 1396, 1, 1);
```
## Read manga
Search manga titles, retrieve chapter listings, and resolve reader-ready page images directly:
```javascript
const search = await vyla.searchManga("Steel Ball Run", 1, 5);
const firstResult = search.results[0];
const manga = await vyla.getManga(firstResult.id);
const firstChapter = manga.chapters[manga.chapters.length - 1];
const chapterData = await vyla.getMangaChapter(manga.id, firstChapter.id);
console.log(chapterData.pages.map(p => p.url));
```
## Make it resilient
Provider results are inherently variable: a source can fail, time out, return more than one candidate, or be temporarily disabled. In production: