AllmangaProvider
AllmangaProvider resolves streams from allmanga.to via the AllAnime GraphQL endpoint. It supports sub, dub, and raw and handles multiple source types: mp4upload embeds, wixmp packager links, and generic HLS embeds.
Constructor
Section titled “Constructor”import { HttpClient, AllmangaProvider } from 'anime-sdk';
const provider = new AllmangaProvider(client);
// With options:const provider = new AllmangaProvider(client, { defaultLanguage: 'dub', // default used when language is omitted per-call baseUrl: 'https://api.allanime.day/api', // override the API endpoint});interface AllmangaOptions { baseUrl?: string; defaultLanguage?: ContentLanguage; // defaults to 'sub'}Does not require DOMParser: it uses the GraphQL API, not HTML scraping.
import { HttpClient, AllmangaProvider } from 'anime-sdk';
const provider = new AllmangaProvider(new HttpClient());
// Searchconst shows = await provider.search('Attack on Titan');// shows[0] => { id: 'shingeki-no-kyojin', title: 'Attack on Titan',// catalogType: 'ANIME', providerId: 'allmanga',// availableLanguages: ['sub', 'dub'] }
// Episodes: one call, language-agnostic. sub/dub/raw availability is// merged per episode into `availableLanguages`.const eps = await provider.fetchContentUnits(shows[0].id);// eps[0] => { id: 'shingeki-no-kyojin/1', title: 'Episode 1',// number: 1, availableLanguages: ['sub', 'dub'] }
// Stream: pick the translation here.const result = await provider.resolveStream(eps[0].id, 'dub');// result => { type: 'video', streams: [...] }
if (result.type === 'video') { const best = result.streams[0]; // pre-sorted by quality score console.log(best.sourceUrl, best.quality, best.isHLS);}Supported languages
Section titled “Supported languages”| Language | Support |
|---|---|
'sub' | Full: most titles |
'dub' | Full: many popular titles |
'raw' | Where available; falls back to 'sub' |
search() returns availableLanguages per title; fetchContentUnits() returns it per episode. resolveStream() falls back to 'sub' if the requested language isn’t available for that episode.
Content unit ID format
Section titled “Content unit ID format”AllManga unit IDs are language-agnostic:
{showId}/{episodeString}Example: shingeki-no-kyojin/1. The legacy {showId}/{episodeString}/{language} shape from older builds still resolves. Do not construct these manually: always use IDs from fetchContentUnits.
How stream resolution works
Section titled “How stream resolution works”- Persisted GraphQL query: fetches episode sources using a SHA-256 hash to identify the query. The response contains a
tobeparsedfield. - AES-CTR decrypt:
tobeparsedis base64-decoded, then the nonce (bytes 1–12) and ciphertext (bytes 13 to end−16) are extracted. The key is SHA-256 of the string'Xot36i3lK3:v1'. The IV is the 16-byte nonce with a counter suffix.crypto.subtle.decrypt(AES-CTR) recovers the source URL list. - XOR decode: individual source URLs starting with
--are a hex string where each byte is XOR’d with0x38. After decode,/clockis rewritten to/clock.json. - Source dispatch: each decoded URL is routed to the appropriate handler:
/clock.json: internal AllAnime endpoint that returns alinksarray with wixmp packager or direct MP4/HLS URLs.m3u8or.mp4: used directlymp4upload.com: passed toMp4UploadExtractortools.fast4speed.rsvp: used directly (Yt-mp4 alias)- Anything else: tried with
GenericHlsExtractoras a best-effort fallback
- Fallback: if the persisted query fails, a regular GraphQL POST is used instead.
- Ranking: streams are sorted by a quality score: mp4upload direct > wixstatic mp4 > HLS m3u8 > other. The highest-scoring stream is first in the array.
Wixmp packager
Section titled “Wixmp packager”When a clock.json response contains a repackager.wixmp.com URL, AllManga expands the encoded quality variants (e.g. ,480p,720p,1080p,) into individual IVideoPayload entries with the corresponding quality label.
clock.jsonendpoints have an 8-second timeout and are fetched on eachresolveStreamcall.- The AES key phrase (
'Xot36i3lK3:v1') is embedded in the source and may change if AllAnime updates its API.