zen-dl.sh is a command-line tool written in Bash to download anime series and episodes directly from a Zen API instance. It offers features like anime searching, flexible episode selection, resolution preference, server choice, and subtitle management.
Note
This script is designed to work with a running instance of the Zen API. Ensure you have access to such an instance before using this script. See the Configuration section for details on setting the API URL.
- Anime Discovery:
- Search for anime by name.
- Select from search results using an interactive
fzfmenu with detailed previews. - Alternatively, specify anime directly by its Zen API ID.
- Flexible Episode Selection:
- Download single episodes, multiple specific episodes, ranges, or all available.
- Exclude specific episodes or ranges.
- Select the latest 'N', first 'N', from 'N' onwards, or up to 'N' episodes.
- Combine selection criteria (e.g., "1-10,!5,L2").
- Interactive prompt for episode selection if not provided via command-line.
- Download Customization:
- Choose preferred audio type (subbed or dubbed).
- Specify preferred resolution via keywords (e.g., "1080", "720") to select the M3U8 variant stream.
- Specify preferred server via keywords (e.g., "HD", "Vidstream") to filter server choices.
- If no resolution preference is given, selects the highest bandwidth M3U8 variant stream by default.
- Subtitle Management:
- Default behavior: Downloads the subtitle track marked as "default" by the API, or falls back to an "English" subtitle if available.
-L <langs>: Option to specify preferred subtitle languages (e.g., "eng,spa,jpn").-L all: Option to download all available subtitles (ofkind: "captions").-L none: Option to download no subtitles.
- Efficient Downloading:
- Parallel segment downloads using GNU Parallel for faster HLS stream processing.
- Configurable number of download threads (
-t <num>). - Optional timeout for individual segment downloads (
-T <secs>).
- User Experience:
- Colorized and informative terminal output.
- Debug mode (
-d) for verbose logging. - Option to list stream links without downloading (
-l). - Organized video downloads into
~/Videos/ZenAnime/<Anime Title>/by default (configurable viaZEN_DL_VIDEO_DIR).
Before you can use zen-dl.sh, you need the following command-line tools installed on your system:
bash: Version 4.0 or higher recommended.curl: For making HTTP requests to the API and downloading files.jq: For parsing JSON responses from the API.fzf: For interactive selection menus.ffmpeg: For concatenating downloaded HLS video segments.GNU Parallel: For parallel downloading of HLS segments.mktemp: For creating temporary directories. (core utils)
Tip
You can usually install these dependencies using your system's package manager.
Installing Dependencies
You can install the required dependencies using your system's package manager.
sudo apt update
sudo apt install -y bash curl jq fzf ffmpeg parallel sudo dnf install -y bash curl jq fzf ffmpeg parallel sudo pacman -Syu bash curl jq fzf ffmpeg parallel brew install bash curl jq fzf ffmpeg parallel coreutilson windows, you can use WSL (Windows Subsystem for Linux) to run this script. Make sure to install the required dependencies in your WSL environment.
-
Download the script: Save the script content as
zen-dl.shin your desired location.# using curl: curl -o zen-dl.sh https://raw.githubusercontent.com/ruxartic/zen-anime-dl/refs/heads/main/zen-dl.sh # using git (clone the repo): git clone https://github.com/ruxartic/zen-anime-dl.git cd zen-anime-dl
-
Make the script executable:
chmod +x zen-dl.sh
-
(Optional) Place it in your PATH: For easier access from anywhere, move or symlink
zen-dl.shto a directory in your localPATH, like~/.local/bin/:ln zen-dl.sh ~/.local/bin/zen-dlOr add its directory to your
PATHenvironment variable in your shell's configuration file (e.g.,~/.bashrc,~/.zshrc).
The script determines the Zen API URL in the following order of precedence:
-
Environment Variable
ZEN_API_URL: If theZEN_API_URLenvironment variable is set and not empty, its value will be used. This is the recommended way to configure a custom API endpoint.# Example for your shell session: export ZEN_API_URL="https://my-custom-zen-api.example.com/api" # Then run the script: ./zen-dl.sh -a "Some Anime"
To make this permanent, add the
exportline to your shell's startup file (e.g.,~/.bashrc,~/.zshrc,~/.profile).
Note
The ZEN_API_URL should point to the base URL of a Zen API instance, including the /api route. For example: https://my-zen-api.example.com/api.
- Script's Default
_DEFAULT_ZEN_API_BASE_URL: IfZEN_API_URLis not set or is empty, the script will use the value of_DEFAULT_ZEN_API_BASE_URLdefined near the top of thezen-dl.shfile.
Important
The script won't work if neither the ZEN_API_URL environment variable is set (or is empty) NOR the _DEFAULT_ZEN_API_BASE_URL variable within the script points to a valid Zen API instance.
Other Configuration:
ZEN_DL_VIDEO_DIR: Environment variable to set the root directory where downloaded anime will be saved.- Default if unset:
"$HOME/Videos/ZenAnime" - Example:
export ZEN_DL_VIDEO_DIR="$HOME/MyAnimeCollection"
- Default if unset:
./zen-dl.sh [OPTIONS]
Common Options:
Mandatory (one of these):
-a <anime_name> Anime name to search for (ignored if -i is used).
-i <anime_id> Specify anime ID directly.
Episode Selection:
-e <selection> Episode selection string. Examples:
- Single: "1"
- Multiple: "1,3,5"
- Range: "1-5"
- All: "*"
- Exclude: "*,!1,!10-12" (all except 1 and 10-12)
- Latest N: "L3" (latest 3 available)
- First N: "F5" (first 5 available)
- From N: "10-" (episode 10 to last available)
- Up to N: "-5" (episode 1 to 5)
- Combined: "1-10,!5,L2" (1-10 except 5, plus latest 2)
If omitted, the script will list available episodes and prompt for selection.
Download Preferences:
-r <res_keyword> Optional, keyword for resolution in server name (e.g., "1080", "720").
Also used to select M3U8 variant stream.
-S <server_keyword> Optional, keyword for preferred server (e.g., "HD-1", "HD-2").
-o <type> Optional, audio type: "sub" or "dub". Default: "sub".
-L <langs> Optional, subtitle languages (comma-separated codes like "eng,spa",
or "all", "none", "default"). Default: "default".
Performance & Output:
-t <num_threads> Optional, number of parallel threads for segment downloads. Default: 4.
-T <timeout_secs> Optional, timeout for individual segment download jobs.
-l Optional, list m3u8/mp4 links without downloading videos.
-d Enable debug mode for verbose output.
-h | --help Display the help message.
For a full list of options, run:
./zen-dl.sh --help-
Search for "Frieren" and download episode 1 (default audio: sub, default subtitle behavior):
./zen-dl.sh -a "Frieren" -e 1 -
Download episodes 5 to 10 and the latest 2 of an anime with ID
anime-xyz, dubbed audio:./zen-dl.sh -i "anime-xyz" -e "5-10,L2" -o dub
-
Download episodes 1-5 using 8 threads for faster downloading:
./zen-dl.sh -a "Anime Title" -e "1-5" -t 8
-
Download all episodes of "My Favorite Anime" except ep 3, prefer 720p, Spanish subs:
./zen-dl.sh -a "My Favorite Anime" -e "*,!3" -r 720 -L spa
-
List stream links for episode 1 of "Another Anime" without downloading:
./zen-dl.sh -a "Another Anime" -e 1 -l -
Download all available subtitles for episode 1 of "Anime Name":
./zen-dl.sh -a "Anime Name" -e 1 -L all -
Download no subtitles for episode 1:
./zen-dl.sh -a "Anime Name" -e 1 -L none
- Initialization: Sets API URL (from
ZEN_API_URLenv var or script default) and checks dependencies. - Anime Identification:
- Uses
-a <name>to search via/api/search, thenfzffor selection. - Uses
-i <id>directly.
- Uses
- Episode List Retrieval: Fetches via
/api/episodes/{anime_id}. - Episode Selection Parsing: Parses the
-e <selection>string or prompts user. - Stream Details Acquisition (for each episode):
- Gets server list from
/api/servers/{episode_stream_id}. - Filters servers by user preferences (
-S,-o). - Gets stream info (M3U8/MP4 URL, subtitles) from
/api/streamusing the chosen server.
- Gets server list from
- M3U8 Handling (HLS):
- Downloads master M3U8.
- Parses it to find quality variants.
- Selects variant by
-r <res_keyword>or highest bandwidth. - Downloads the selected media M3U8 (containing segment URLs).
- Downloading:
- HLS segments are downloaded in parallel using GNU Parallel.
- Direct MP4s are downloaded.
- Subtitles are downloaded based on
-L <langs>preference.
- Assembly (HLS):
ffmpegconcatenates segments into a single.mp4file. - File Organization: Saves files to
VIDEO_DIR_PATH/ANIME_TITLE/Episode_NUM_TITLE.mp4. - Cleanup: Temporary files and directories are removed after download completion.
Warning
Downloading copyrighted material may be illegal in your country. This script is provided for educational purposes and for use with legitimately accessed API instances. Please respect copyright laws and the terms of service of any API provider. Use this script at your own responsibility.
Contributions are welcome! If you have suggestions, bug fixes, or feature requests, please open an issue or submit a pull request.
This project is licensed under the MIT License.