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 the yt-dlp binary and extract direct MP4/WebM URLs
  • Performs a GET request to the .clock.json endpoint 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 implementing resolve-allmanga IPC, AES decryption (decodeTobeparsed), GraphQL client (allanimeGQL), and redirect handling (followRedirects)
  • src/ipc/player.js – Local HTTP server implementation for stream delivery and referer spoofing
  • src/ipc/downloads.js – Download queue management that consumes resolved URLs from the scraper
  • src/pages/TVPage.jsx – React UI component that triggers the resolution pipeline via IPC
  • preload.js – Exposes window.electron.invoke bridge 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 in src/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_PRIORITY and resolved through followRedirects(), with YouTube links processed via external yt-dlp invocation in resolveWithYtdlp().
  • 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →