How Streambert's AllManga.to Scraper Handles Anime Downloads
Streambert enables ad-free anime downloads by querying the AllAnime GraphQL API directly, decrypting AES-256-CTR encrypted payloads in decodeTobeparsed(), and resolving direct video URLs through provider prioritization and redirect chains.
Streambert is an Electron-based desktop application designed for streaming and downloading anime without browser-based advertisements. The src/ipc/allmanga.js module implements the core Streambert allmanga.to scraper anime download functionality, bypassing the public AllManga website entirely to communicate with the AllAnime API backend. This article examines the technical architecture, decryption algorithms, and video resolution pipeline that enable direct MP4 and HLS stream extraction.
How the AllManga.to Scraper Works in Streambert
IPC Handler Architecture
The scraper registers the resolve-allmanga IPC handler in src/ipc/allmanga.js (lines 6689-6820). This handler acts as the central coordinator between the React frontend and the network layer. When a user selects an episode in the UI, the renderer process invokes this handler through window.electron.invoke('resolve-allmanga', {...}), passing parameters including title, season number, episode number, and translation type (sub/dub).
GraphQL API Communication
Instead of parsing HTML, the system communicates with https://api.allanime.day/api using two primary functions. The allanimeGQL() function (lines 3000-3015) sends POST requests with headers matching the web UI—including User-Agent, Referer, and Origin—to evade Cloudflare protection. For episode resolution, allanimeGQLEpisode() (lines 6640-6661) first attempts a GET request with a persisted query hash, then falls back to POST if the cached query fails.
Decrypting the Video Sources
AllAnime encrypts video source data using a proprietary AES-256-CTR scheme. The decodeTobeparsed() function (lines 1200-1248) handles decryption by decoding Base64 input, extracting the initialization vector and ciphertext, and returning an array of {sourceUrl, sourceName, priority} objects. Additionally, decodeAllanimeUrl() (lines 100-108) normalizes the special "--hex" URL format used by AllAnime endpoints, converting paths like /clock to /clock.json for direct API access.
The Anime Resolution Pipeline
Step 1: Show Lookup and Episode Mapping
The pipeline begins by checking internal hardcoded show ID mappings around line 3350 in HARDCODED_SHOW_IDS and synchronizing with AniList to resolve canonical English or romaji titles. If the title requires correction, the system queries AniList before performing a GraphQL search via SEARCH_GQL to obtain the showId required for episode queries.
Step 2: Source URL Extraction and Decryption
Using the episode GraphQL query EPISODE_GQL, the system retrieves source data. If the response contains an encrypted tobeparsed field, the code calls decodeTobeparsed() to reveal the source array. Plain sourceUrls arrays are processed directly without decryption, though most anime episodes require the decryption step to obtain playable URLs.
Step 3: Provider Prioritization and URL Resolution
Sources are filtered against a PROVIDER_PRIORITY array: ["S-mp4","Luf-Mp4","Yt-mp4","Default","Sl-Hls"]. For each candidate, the code:
- Normalizes the URL via
decodeAllanimeUrl() - For fast4speed.rsvp or Yt-mp4 entries, invokes
followRedirects()(lines 1666-1685) to resolve up to 10 redirect hops and obtain the final CDN location - For YouTube watch pages, triggers
resolveWithYtdlp()(lines 1700-1725) to externally call theyt-dlpbinary and extract direct MP4/WebM URLs - Performs a
GETrequest to the.clock.jsonendpoint for standard providers, parsing the JSON to select the highest-resolution MP4 link
Local Player Server and Download Implementation
Serving Streams via Local HTTP
Once resolved, the direct URL passes to the set-player-video IPC channel, which launches a local HTTP server via getPlayerServer() and buildPlayerHtml() (lines 2000-2065). This server exposes a /player endpoint that injects hls.js for HLS manifest playback and a /proxy endpoint that rewrites Referer headers, bypassing hotlink protection on video CDNs while enabling seamless playback in the Electron renderer.
Download Integration
The src/ipc/downloads.js module consumes the resolved URLs from the scraper to manage download queues. Because the scraper provides direct video URLs (post-redirect resolution and yt-dlp extraction), the download module can perform byte-range requests for resumable downloads without browser sandbox restrictions, handling MP4, WebM, and HLS streams alike.
Code Examples
Requesting a Stream from the React Frontend
The UI layer in src/pages/TVPage.jsx invokes the scraper and player setup sequentially:
const streamEpisode = async (title, season, ep) => {
const result = await window.electron.invoke('resolve-allmanga', {
title,
seasonNumber: season,
episodeNumber: ep,
isMovie: false,
translationType: 'sub',
});
if (result?.ok) {
const { playerUrl } = await window.electron.invoke('set-player-video', {
url: result.url,
referer: result.referer,
startTime: 0,
});
window.open(playerUrl, '_blank', 'width=1280,height=720');
}
};
Extending Hardcoded Show Mappings
To handle shows with non-standard API IDs, extend the HARDCODED_SHOW_IDS object in src/ipc/allmanga.js:
const HARDCODED_SHOW_IDS = {
"attack on titan": [
"MeX4czvkwKGo3zdDp", // Season 1
"zyqDjR8te4z6taKyk", // Season 2
],
"custom anime title": [
"NewShowIdHere1234", // Season 1
],
};
Embedding the Local Player
Once set-player-video returns, the player URL can be embedded directly:
<iframe
src="http://127.0.0.1:45532/player"
width="100%"
height="100%"
allowfullscreen>
</iframe>
The server automatically detects HLS manifests and injects the appropriate hls.js configuration, or proxies MP4 content through the /proxy route.
Key Source Files and Functions
src/ipc/allmanga.js– Core scraper implementingresolve-allmangaIPC, AES decryption (decodeTobeparsed), GraphQL client (allanimeGQL), and redirect handling (followRedirects)src/ipc/player.js– Local HTTP server implementation for stream delivery and referer spoofingsrc/ipc/downloads.js– Download queue management that consumes resolved URLs from the scrapersrc/pages/TVPage.jsx– React UI component that triggers the resolution pipeline via IPCpreload.js– Exposeswindow.electron.invokebridge to the renderer process
Summary
- Streambert's scraper communicates directly with the AllAnime GraphQL API at
api.allanime.day, bypassing the AllManga.to web interface entirely. - The
decodeTobeparsed()function insrc/ipc/allmanga.js(lines 1200-1248) uses AES-256-CTR decryption to extract video source arrays from encrypted API payloads. - Provider sources are prioritized via
PROVIDER_PRIORITYand resolved throughfollowRedirects(), with YouTube links processed via externalyt-dlpinvocation inresolveWithYtdlp(). - A local HTTP server (
src/ipc/player.js) serves the final streams to the Electron renderer, enabling ad-free playback and download capabilities through referer-rewriting proxies.
Frequently Asked Questions
Does Streambert scrape the AllManga.to website directly?
No. According to the truelockmc/streambert source code, the application queries the AllAnime GraphQL API at https://api.allanime.day/api. It never parses the HTML of the AllManga.to website, instead using encrypted API responses and hardcoded show ID mappings to obtain direct video URLs.
How does Streambert decrypt the video URLs from AllAnime?
The decodeTobeparsed() function in src/ipc/allmanga.js (lines 1200-1248) implements AES-256-CTR decryption. It decodes Base64 input, extracts the initialization vector and ciphertext, and decrypts the proprietary tobeparsed field to reveal an array of source URLs with associated provider priorities.
Can Streambert download episodes from YouTube sources found on AllManga?
Yes. When the scraper encounters a Yt-mp4 provider or YouTube watch page URL during the resolution chain, it invokes resolveWithYtdlp() (lines 1700-1725) to externally call the yt-dlp binary. This extracts a direct MP4 or WebM URL that the application can stream through the local server or download via src/ipc/downloads.js.
Why does Streambert use a local HTTP server for playback?
The local player server eliminates cross-origin restrictions and referer-checking issues. Implemented in src/ipc/player.js and coordinated through src/ipc/allmanga.js (lines 2000-2065), it serves a /player endpoint that injects hls.js for HLS manifests and proxies video requests through a referer-rewriting middleware, ensuring CDNs serve the content to the Electron application.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →