-
Notifications
You must be signed in to change notification settings - Fork 0
Extractors
🌐 English · Deutsch
Extractors resolve a video host's embed URL into a direct stream link (usually HLS/MP4) that yt-dlp/FFmpeg can download.
Enabled (SUPPORTED_PROVIDERS in config.py):
| Host | Module | Notes |
|---|---|---|
| VOE | voe.py |
Multi-stage deobfuscation (ROT13, junk patterns, Base64), captcha support |
| Vidmoly | vidmoly.py |
Requires referer https://vidmoly.biz
|
| Vidoza | vidoza.py |
— |
| VeeV | veev.py |
Custom headers (referer/origin veev.to), availability check via /api/veev/check
|
Present but disabled (commented out in SUPPORTED_PROVIDERS): Doodstream, Filemoon, LoadX, Luluvdo, Streamtape, Vidara.
extractors/__init__.py imports all modules from extractors/provider/ and registers every function whose name starts with get_direct_link_from_ or get_preview_image_link_from_ in the provider_functions dict:
provider_functions["get_direct_link_from_voe"](embed_url)At app startup, _get_working_providers() (web/app.py) probes each entry from SUPPORTED_PROVIDERS with an empty URL string: if the extractor raises NotImplementedError it counts as not implemented; any other exception means "implemented" (it correctly rejected the empty URL). Only functional providers appear in the UI (WORKING_PROVIDERS).
-
Create the file:
src/aniworld/extractors/provider/<host>.py -
Implement the function (mind the naming convention —
<host>lowercase):
import logging
logger = logging.getLogger(__name__)
try:
from ...config import GLOBAL_SESSION, is_source_unavailable
except ImportError:
from aniworld.config import GLOBAL_SESSION, is_source_unavailable
def get_direct_link_from_<host>(embed_url: str) -> str:
if not embed_url:
raise ValueError("Empty URL")
resp = GLOBAL_SESSION.get(embed_url)
if is_source_unavailable(resp.text, resp.status_code):
raise ValueError("Source removed")
# ... parse HTML/JS, extract the stream URL ...
return direct_link-
Enable the provider: add its name to
SUPPORTED_PROVIDERS(config.py) — spelling must matchfunc_name = f"get_direct_link_from_{p.lower()}". -
Define headers: if the host needs special headers, add them to
PROVIDER_HEADERS_D(download) and possiblyPROVIDER_HEADERS_W(watch) inconfig.py— these are passed to yt-dlp/FFmpeg. - Optional:
get_preview_image_link_from_<host>()for preview images.
| Function | Purpose |
|---|---|
GLOBAL_SESSION |
Thread-safe niquests session with realistic headers and DoH DNS |
is_source_unavailable(html, status) |
Detects removed videos (404/410/451 + HTML markers) without an extra request |
check_redirect_available(url) |
Follows the streaming site's redirect and checks whether the host still has the video (curl_cffi with Chrome impersonation against Cloudflare) |
resolve_redirect_url(url) |
Returns the final host URL behind a redirect |
When an extractor detects a captcha page (is_captcha_page from playwright/captcha.py), it can call solve_captcha(...). If the call runs inside the queue worker, the queue_id is set via thread-local — which makes the solving interactive in the WebUI (live screenshot + click forwarding). Chromium runs with stealth patches, network ad blocking and protection against ad overlays.
🇬🇧 English
Users
- Installation
- Getting Started
- Migration from AniWorld
- Configuration
- Web UI
- Download System
- Download History
- AutoSync
- Calendar
- Library
- Authentication
- Notifications
- Integrations
- SyncPlay
- Anime4K Upscaling
- Encoding
- Docker
- Supported Sites
Developers