2026-08-14 12:27:08 +02:00
2026-09-09 22:54:01 +02:00
2026-08-10 11:26:20 +02:00
2026-08-09 11:50:46 +02:00
2026-09-10 09:28:14 +02:00

Kaizoku

Kaizoku is a local web app for searching, tracking, and downloading anime from Anikoto, AniNeko, and AnimePahe. It keeps its own SQLite state under .kaizoku/, resolves streams through bundled JavaScript provider modules, and finalizes downloads into Jellyfin-friendly TV or movie folders.

Features

  • Search anime through the configured provider and tag results with available SUB and DUB episode languages, ignoring empty provider language groups that do not expose playable servers.
  • Choose the active provider from Config defaults or directly from the Search page.
  • Prefer provider-supplied search artwork, with a local title-based thumbnail fallback when provider artwork is missing or broken.
  • Fill Watchlist thumbnails from AnimeSchedule or AniDB title metadata when provider artwork is missing.
  • Queue single episodes or batches in subbed or dubbed mode.
  • Monitor active Queue jobs with per-episode progress, segment counts, and live downloader output.
  • Open result actions in a floating window for watchlist, media type, subbed/dubbed mode, library name, season, episode range, and download folder choices.
  • Fall back across the other configured providers when an episode or stream cannot be resolved on the primary provider.
  • Save files with Jellyfin-friendly layout: TV/Series Name/Season 01/Series Name - S01E01.mp4, including Season 00 for specials.
  • Save English external subtitles when the provider exposes usable subtitle tracks.
  • Manage focused watchlists for Watching, Planned, Finished, and Dropped, with provider source tags and title links back to the original provider page.
  • Periodically refresh selected watchlists with a single visible advancing progress bar and auto-download newly available episodes.
  • Sync watchlist download flags from the filesystem.
  • Hand completed libraries to Jellyfin TV or movie folders.
  • Export/import watchlist backups.
  • Send unified Discord notifications for downloads, refreshes, Jellyfin handoff, and runtime errors.
  • Check bundled provider JavaScript against upstream TheYogMehta/extensions from the Config page.
  • Store configuration, queue state, and watchlist data in SQLite under .kaizoku/.

Requirements

  • Python 3.12 or newer.
  • Node.js and npm for the provider bridge.
  • ffmpeg available in PATH.
  • openssl available in PATH for AES-128 encrypted HLS segments.
  • pytest is optional; the current regression tests are unittest-compatible and can run with the Python standard library.
  • Docker builds install the locked Node dependencies with npm ci; rebuild the image after dependency updates.

Install Node dependencies once:

npm install

Run locally:

./kaizoku

Then open:

http://127.0.0.1:8421/

Run the local regression tests:

python3 -m unittest -q

Useful environment variables:

  • KAIZOKU_HOST=0.0.0.0
  • KAIZOKU_PORT=8421
  • KAIZOKU_ALLOW_REMOTE=1 to allow non-loopback clients.
  • KAIZOKU_AUTH_USERNAME=admin and KAIZOKU_AUTH_PASSWORD=choose-a-long-random-password for remote access.
  • KAIZOKU_JOB_STDOUT=true to mirror job logs to container or terminal output.
  • KAIZOKU_STATE_ROOT=/path/to/state to move SQLite state, config, thumbnails, sessions, and staging.
  • KAIZOKU_DOWNLOAD_DIR=/downloads for the default library output path.
  • KAIZOKU_REMOTE_PATH_ROOTS=/downloads,/jellyfin/tv,/jellyfin/movies to limit remote filesystem browsing; comma-separated and platform path separators are accepted.
  • KAIZOKU_MODE=sub, KAIZOKU_QUALITY=best, and KAIZOKU_DEBUG=1 for runtime defaults and diagnostics.
  • KAIZOKU_SEGMENT_RETRIES=8, KAIZOKU_SEGMENT_RETRY_DELAY=1.25, KAIZOKU_SEGMENT_RETRY_MAX_DELAY=15, and KAIZOKU_SEGMENT_DOWNLOAD_DELAY=0 to tune retry/backoff and optional pacing behavior for native HLS segment downloads. Retries cover temporary HTTP responses, DNS failures, connection errors, and socket timeouts.
  • KAIZOKU_MEDIA_HTTP_CLIENT=auto to let protected HLS segment fetches fall back from Python HTTP to curl or curl-impersonate after HTTP 403; use curl or urllib to force one client, and KAIZOKU_CURL_BIN=/path/to/curl_chrome142 to prefer a specific curl-compatible binary. Playlist, segment, and encryption-key requests preserve provider CDN session cookies for the duration of the download process.

Docker

docker compose up -d --build

The compose file builds the local checkout and runs Kaizoku on port 8421 by default. It mounts:

  • ./downloads to /downloads
  • ${JELLYFIN_TV_DIR:-./jellyfin/tv} to /jellyfin/tv
  • ${JELLYFIN_MOVIE_DIR:-./jellyfin/movies} to /jellyfin/movies
  • ./.kaizoku to /app/.kaizoku

Use /jellyfin/tv for the Jellyfin TV directory and /jellyfin/movies for the Jellyfin movie directory inside the Config page. Override JELLYFIN_TV_DIR and JELLYFIN_MOVIE_DIR to point those container paths at your real host Jellyfin library folders.

The Docker image installs Python, Node.js, npm, curl, curl-impersonate browser wrappers, ffmpeg, openssl, and util-linux for optional UID/GID switching, then runs npm ci --omit=dev for the provider bridge. Downloads go through Kaizoku's provider bridge and provider_downloader.py.

Useful Compose overrides:

KAIZOKU_PORT=8080 docker compose up -d --build
KAIZOKU_ALLOW_REMOTE=1 KAIZOKU_AUTH_USERNAME=admin KAIZOKU_AUTH_PASSWORD='change-me' docker compose up -d
USER_UID=$(id -u) USER_GID=$(id -g) docker compose up -d

When USER_UID and USER_GID are set, the entrypoint attempts to adjust ownership for /downloads, /jellyfin/tv, /jellyfin/movies, and Kaizoku state paths. Ownership changes are best-effort so policy-managed or read-only Jellyfin mounts can still be browsed and used when their existing permissions allow it.

Keep ./.kaizoku mounted for production instances. That directory contains the SQLite database, configuration, queue history, watchlist data, thumbnail cache, remote sessions, and temporary staging files. Removing the mount starts Kaizoku with a fresh empty state.

Download Flow

Kaizoku stores provider-backed show IDs as provider:id, for example anikoto:some-show-slug. Queue jobs resolve the episode source through providers/bridge.js, then provider_downloader.py downloads the media with ffmpeg into a staging directory. If a provider returns multiple servers for the requested sub or dub mode, Kaizoku tries every same-mode server source in quality order before falling back to another provider, including when resolving one server's playlist raises an HTTP error. It does not use sub sources for dub downloads, or dub sources for sub downloads. If a provider returns a master HLS playlist, Kaizoku selects the highest-bandwidth variant before starting ffmpeg. When a media playlist uses extensionless, SnapCDN, or disguised CDN segments, Kaizoku skips direct ffmpeg and uses a StrawVerse-style segment downloader; if HLS preflight fails, it stays on that native path instead of falling through to ffmpeg. The native downloader fetches the media playlist, preserves provider CDN session cookies across playlist, segment, and encryption-key requests, downloads and concatenates segments itself with browser-like media headers and the provider referer, can fall back to curl-impersonate browser wrappers after protected CDN HTTP 403 responses, strips short PNG wrappers when present, retries temporary HTTP failures such as 429 Too Many Requests, optionally paces requests with KAIZOKU_SEGMENT_DOWNLOAD_DELAY, then remuxes the local transport stream to MP4. Direct ffmpeg attempts also have a timeout guard so stalled HLS inputs can fall back cleanly. Each episode is written as a temporary .mp4.part file and moved into the downloads library after that episode succeeds, so already-finished episodes from a larger batch survive if a later episode fails. Retrying that failed queue job requests only the remaining episodes while keeping the original episode range for display and watchlist sync. Finalization preserves episode numbers from staged SxxEyy or Episode yy filenames before applying configured season/episode offsets.

If the primary provider cannot list, resolve, or download a requested episode, Kaizoku searches the same title on the remaining providers and tries the matching episode there. Existing finalization code moves staged files into the configured library layout, preserving data already present in production download folders.

Data Safety

Kaizoku uses additive SQLite migrations for queue and watchlist schema changes. Upgrades do not delete configuration, watchlists, queue history, or downloaded files. Jellyfin handoff moves only completed library folders that pass the existing readiness checks.

Provider Source

The Anikoto, AniNeko, and AnimePahe parser modules in providers/extensions/Anime/ are adapted from TheYogMehta/extensions and retain their GPL/license headers. The bundled anime provider versions are currently:

  • Anikoto 5.0.5
  • AniNeko 3.0.3
  • AnimePahe 4.0.1

The Config page checks the bundled JavaScript against the upstream main branch and reports whether upstream updates are available. If Kaizoku carries a newer local provider patch than upstream, such as the patched Anikoto module, the Config page reports it separately as a local change. Kaizoku acts as a local client-side parser/downloader wrapper and does not host media.

S
Description
No description provided
Readme
736 KiB
Languages
Python 92%
JavaScript 7.7%
Dockerfile 0.2%
Shell 0.1%