### Filename Template Example
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/5.1-‐-CR‐Settings
Defines a folder structure and filename for downloaded episodes using template variables. This example creates a series folder and names the episode file with series, season, episode, height, width, and dub information.
```text
${seriesTitle}\
${seriesTitle} - ${season}E${episode}
```
--------------------------------
### Docker Compose Management Commands
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Commands to manage the Docker Compose setup for FlareSolverr and MITM proxy. Use `docker compose up -d` to start services, `docker ps` to verify, and `docker logs` to check service output.
```bash
docker compose up -d
docker ps # verify containers are running
docker logs flaresolverr-mitm-proxy # check MITM proxy logs
docker logs flaresolverr # check FlareSolverr logs
```
--------------------------------
### Start FlareSolverr Containers
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/6.-FlareSolverr-MITM-Proxy
Command to start the Docker containers defined in the docker-compose.yml file in detached mode.
```bash
docker compose up -d
```
--------------------------------
### Custom Webhook Body Template Example
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Demonstrates using a custom template for the webhook body with placeholder syntax `{{placeholder}}`. The template is rendered with specific metadata values.
```text
// --- Custom webhook body template (uses {{placeholder}} syntax) ---
// Template: { "content": "{{eventType}}: {{seriesTitle}} - S{{seasonNumber}}E{{episodeNumber}}" }
// Rendered: { "content": "DownloadFinished: Attack on Titan - S4E28" }
```
--------------------------------
### Custom Webhook Body Template Example
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/5-‐-General-Settings
An example of a custom request body template for webhook notifications. Placeholders are replaced with actual event data.
```json
{
"content": "{{eventType}}: {{seriesTitle}} - {{episodeTitle}}"
}
```
--------------------------------
### Configure .csproj for Avalonia Project
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/0-‐-Build
Replace the existing .csproj file content with this configuration to set up the Avalonia .NET MVVM application. Ensure the TargetFramework and package references are correct for your project setup.
```xml
WinExe
net10.0
enable
true
app.manifest
true
en
Assets\app_icon.ico
1.1.1.1
ContentDialogInputLoginView.axaml
Code
ContentDialogSonarrMatchEpisodeView.axaml
Code
ContentDialogFeaturedMusicView.axaml
Code
ContentDialogSeriesDetailsView.axaml
Code
ContentDialogMultiProfileSelectView.axaml
Code
```
--------------------------------
### Docker Compose Command
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Command to start the Docker Compose services defined in the `docker-compose.yml` file in detached mode.
```bash
docker compose up -d
```
--------------------------------
### Default Webhook JSON Payload Example
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Illustrates the default JSON payload sent to a webhook when the body template is empty. This structure includes event type, title, message, timestamp, and metadata.
```json
// POST
// Content-Type: application/json
// {
// "eventType": "DownloadFinished",
// "title": "Download finished",
// "message": "Finished processing Attack on Titan.",
// "timestampUtc": "2025-01-15T18:30:00.0000000+00:00",
// "metadata": {
// "seriesTitle": "Attack on Titan",
// "episodeTitle": "The Dawn of Humanity",
// "episodeNumber": "28",
// ...
// }
// }
```
--------------------------------
### Run Crunchy Downloader Webtop with Docker Compose
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/Home
This snippet shows a basic docker-compose.yml configuration for the Crunchy Downloader Webtop service. It specifies the image to use, container name, restart policy, shared memory size, port mappings, environment variables (including timezone and user/group IDs), and volume mounts for persistent data.
```yaml
services:
webtop:
image: ghcr.io/crunchy-dl/crunchy-downloader-webtop:
container_name: crunchy-downloader-webtop
restart: unless-stopped
shm_size: "1gb"
ports:
- "3000:3000"
- "3001:3001"
environment:
TZ: "${TZ:-Etc/UTC}"
PUID: "${PUID:-1000}"
PGID: "${PGID:-1000}"
TITLE: "Crunchy Downloader Webtop"
volumes:
- ./docker/webtop-config:/config
- ./docker/crd-data:/crd-data
- ./docker/local-data:/data
```
--------------------------------
### Configure Sonarr Integration in Crunchy-DL
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Set up Sonarr integration by enabling it and providing connection details. When `UseSonarrNumbering` is true, filename templates will use Sonarr's S/E numbers for matched episodes.
```csharp
var opts = CrunchyrollManager.Instance.CrunOptions;
// --- Connect to Sonarr ---
opts.SonarrProperties = new SonarrProperties{
SonarrEnabled = true,
Host = "localhost",
Port = 8989,
ApiKey = "your_sonarr_api_key",
UseSSL = false,
UseSonarrNumbering = true, // use Sonarr S/E numbers instead of Crunchyroll's
};
// When UseSonarrNumbering = true, ${season} and ${episode} in filename templates
// resolve to Sonarr's numbering for history-matched episodes.
// Additional Sonarr-specific filename template variables:
// ${sonarrSeriesTitle} → series title from Sonarr
// ${sonarrSeriesReleaseYear} → release year from Sonarr
// ${sonarrEpisodeTitle} → episode title from Sonarr
// --- History settings for Sonarr ---
opts.HistoryMissingEpisodesFromSonarr = true; // use Sonarr's missing count
opts.HistorySkipSonarrUnmonitored = true; // skip unmonitored episodes
```
--------------------------------
### Initialize and Access CrunchyrollManager Singleton
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Access the CrunchyrollManager singleton to initialize subsystems and retrieve download options. It also provides a method to fetch the base64-encoded authentication token.
```csharp
using CRD.Downloader.Crunchyroll;
// Access the singleton
var mgr = CrunchyrollManager.Instance;
// Initialize all sub-systems (call once at startup)
mgr.InitOptions();
// Creates: CrAuthEndpoint1, CrAuthEndpoint2, CrAuthGuest,
// CrEpisode, CrSeries, CrMovies, CrMusic, CrQueue, History
// Access download options (lazy-initialized from settings.json)
var opts = mgr.CrunOptions;
Console.WriteLine(opts.FileName);
// → "${seriesTitle} - S${season}E${episode} [${height}p]" (default)
// Key default option values set in InitDownloadOptions():
// opts.DubLang = ["ja-JP"]
// opts.DlSubs = ["en-US"]
// opts.QualityVideo = "best"
// opts.QualityAudio = "best"
// opts.SimultaneousDownloads = 2
// opts.Chapters = true
// opts.SkipMuxing = false
// opts.Numbers = 2 (leading zeros: S01E01)
// opts.RetryAttempts = 5
// opts.RetryDelay = 5 (seconds)
// opts.StreamEndpoint = { Endpoint = "tv/android_tv", Audio = true, Video = true }
// Fetch the base64-encoded auth token from Crunchyroll's JS bundle
string b64token = await CrunchyrollManager.GetBase64EncodedTokenAsync();
```
--------------------------------
### Docker Compose Deployment for Webtop Environment
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
This Docker Compose configuration sets up a containerized Crunchyroll Downloader environment accessible via a web browser. It maps ports for HTTP/HTTPS access and defines volumes for configuration and data persistence.
```yaml
# docker-compose.yml
services:
webtop:
image: ghcr.io/crunchy-dl/crunchy-downloader-webtop:latest
container_name: crunchy-downloader-webtop
restart: unless-stopped
shm_size: "1gb"
ports:
- "3000:3000" # HTTP web UI
- "3001:3001" # HTTPS web UI
environment:
TZ: "America/New_York"
PUID: "1000"
PGID: "1000"
TITLE: "Crunchy Downloader Webtop"
volumes:
- ./docker/webtop-config:/config
- ./docker/crd-data:/crd-data
- ./docker/local-data:/data
```
--------------------------------
### View MITM Proxy Container Logs
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/6.-FlareSolverr-MITM-Proxy
Command to display logs for the flaresolverr-mitm-proxy container.
```bash
docker logs flaresolverr-mitm-proxy
```
--------------------------------
### Headless Operation Startup Parameters
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Use these command-line arguments to run CRD in headless mode for automated operations without a GUI. The `--exit` flag ensures the application closes after completing the specified tasks.
```bash
CRD.exe --headless
```
```bash
CRD.exe --headless --historyRefreshAll --exit
```
```bash
CRD.exe --headless --historyRefreshActive --exit
```
```bash
CRD.exe --headless --historyRefreshActive --historyAddToQueue --exit
```
--------------------------------
### Configure FlareSolverr Settings
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Sets up FlareSolverr for Cloudflare bypass. Enable `UseFlareSolverr` and configure the host, port, and SSL settings. `UseMitmFlareSolverr` enables MITM proxy for header-preserving requests.
```csharp
// --- FlareSolverr (Cloudflare bypass) ---
opts.FlareSolverrProperties = new FlareSolverrSettings{
UseFlareSolverr = true,
Host = "127.0.0.1",
Port = 8191,
UseSSL = false,
UseMitmFlareSolverr = true, // enable MITM proxy for header-preserving requests
MitmHost = "127.0.0.1",
MitmPort = 8080,
};
// Restart the app after changing proxy/FlareSolverr settings
```
--------------------------------
### Configure HTTP Proxy Settings
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Configures HTTP or SOCKS5 proxy settings for the application. Ensure `ProxyEnabled` is set to true and provide the host, port, and optional credentials.
```csharp
var opts = CrunchyrollManager.Instance.CrunOptions;
// --- HTTP Proxy ---
opts.ProxyEnabled = true;
opts.ProxySocks = false; // false = HTTP proxy; true = SOCKS5
opts.ProxyHost = "127.0.0.1";
opts.ProxyPort = "8080";
opts.ProxyUsername = "user"; // optional
opts.ProxyPassword = "pass"; // optional
// Resulting URL: http://127.0.0.1:8080 (or socks5://127.0.0.1:8080)
```
--------------------------------
### View FlareSolverr Container Logs
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/6.-FlareSolverr-MITM-Proxy
Command to display logs for the flaresolverr container.
```bash
docker logs flaresolverr
```
--------------------------------
### Configure CalendarManager Options
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Set Crunchyroll calendar options to control locale, custom calendar mode, dub filtering, and history updates. Ensure CrDownloadOptions are accessible via CrunchyrollManager.Instance.CrunOptions.
```csharp
using CRD.Downloader;
var cal = CalendarManager.Instance;
// Supported calendar locale keys:
// "en-us" → https://www.crunchyroll.com/simulcastcalendar
// "es" → https://www.crunchyroll.com/es/simulcastcalendar
// "es-es" → Spanish (Spain)
// "pt-br" → Portuguese (Brazil)
// "pt-pt" → Portuguese (Portugal)
// "fr" → French
// "de" → German
// "ar" → Arabic
// "it" → Italian
// "ru" → Russian
// "hi" → Hindi
// The calendar is controlled via CrDownloadOptions:
var opts = CrunchyrollManager.Instance.CrunOptions;
opts.SelectedCalendarLanguage = "en-us"; // locale key
opts.CustomCalendar = true; // use custom calendar (last 6 days + today)
opts.HideCalendarDubs = false; // show dub entries
opts.CalendarDubFilter = "ja-JP"; // filter to a specific dub language ("none" = all)
opts.ShowUpcomingEpisodes = true; // include next week's upcoming episodes
opts.UpdateHistoryFromCalendar = true; // refresh history using calendar releases (faster)
```
--------------------------------
### Manage Configuration and History with CfgManager
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Use CfgManager to read and write application settings, history, and tokens. It handles JSON parsing, GZip compression for history, and automatic daily backups. Error logging can also be enabled or disabled.
```csharp
using CRD.Utils.Files;
// --- Reading settings from file into an existing options object ---
// Merges only properties present in the JSON file; others keep defaults
var options = new CrDownloadOptions();
CfgManager.UpdateSettingsFromFile(options, CfgManager.PathCrDownloadOptions);
// options now reflects saved user preferences merged over defaults
// --- Writing current options to disk ---
CfgManager.WriteCrSettings();
// Writes CrunchyrollManager.Instance.CrunOptions → config/settings.json
// --- Writing history (gzip-compressed, with rolling daily backups) ---
CfgManager.UpdateHistoryFile();
// Saves HistoryList → config/history.json (GZip compressed)
// Keeps up to 5 daily backups: config/.history.json.2025-01-15.bak
// --- Reading back gzip history (auto-detects plain vs gzip) ---
string? json = CfgManager.DecompressJsonFile(CfgManager.PathCrHistory);
// Returns plain JSON string; null if file not found
// --- Generic JSON read/write ---
CfgManager.WriteJsonToFile(CfgManager.PathCrToken, myToken);
var token = CfgManager.ReadJsonFromFile(CfgManager.PathCrToken);
// --- Enable/disable error logging to logfile.txt ---
CfgManager.EnableLogMode(); // redirects Console.Error → logfile.txt
CfgManager.DisableLogMode(); // restores standard error stream
// --- Key path constants ---
// CfgManager.PathCrDownloadOptions → config/settings.json
// CfgManager.PathCrHistory → config/history.json
// CfgManager.PathCrQueue → config/queue.json
// CfgManager.PathFFMPEG → lib/ffmpeg.exe
// CfgManager.PathMKVMERGE → lib/mkvmerge.exe
// CfgManager.PathMP4Decrypt → lib/mp4decrypt.exe
// CfgManager.PathWIDEVINE_DIR → widevine/
// CfgManager.PathFONTS_DIR → fonts/
```
--------------------------------
### Docker Compose for FlareSolverr and MITM Proxy
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Provides a docker-compose.yml file to set up FlareSolverr and a MITM proxy. This configuration allows for easy deployment and management of these services.
```yaml
# docker-compose.yml for FlareSolverr + MITM proxy
version: "2.1"
services:
flaresolverr-mitm-proxy:
image: ghcr.io/zelak312/flaresolverr-mitm-proxy:latest
container_name: flaresolverr-mitm-proxy
restart: unless-stopped
ports:
- 8080:8080
# environment:
# - PROXY=http://upstream-proxy:8181 # optional upstream proxy
# - PROXY_AUTH=user:pass
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
environment:
- LOG_LEVEL=info
- TZ=Europe/London
ports:
- 8191:8191
restart: unless-stopped
```
--------------------------------
### Available NotificationEventTypes
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Lists the available types for `NotificationEvent`. Each type corresponds to a specific download lifecycle event or application status.
```text
// --- Available NotificationEventTypes ---
// NotificationEventType.QueueFinished → all downloads done
// NotificationEventType.DownloadFinished → single item done
// NotificationEventType.DownloadFailed → single item failed
// NotificationEventType.TrackedSeriesEpisodeReleased → new ep from history series detected
// NotificationEventType.LoginExpired → session refresh failed
// NotificationEventType.UpdateAvailable → new app version found
```
--------------------------------
### Check Container Status
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/6.-FlareSolverr-MITM-Proxy
Command to list all running Docker containers.
```bash
docker ps
```
--------------------------------
### CrAuth - Handle Crunchyroll Authentication Flows
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Handles token management, including initial authentication, refreshing tokens, anonymous login, and profile switching. Use this for all interactions requiring authentication with Crunchyroll services.
```csharp
using CRD.Downloader.Crunchyroll;
var mgr = CrunchyrollManager.Instance;
var auth = mgr.CrAuthEndpoint1;
// --- Initial authentication (loads saved token or falls back to anonymous) ---
await auth.Auth();
// If config/cr_token.json exists → LoginWithToken()
// Otherwise → AuthAnonymous()
// --- Refresh token before API calls (skips if still valid) ---
await auth.RefreshToken(needsToken: true);
// needsToken=true: only refreshes if token is expired or within 60s of expiry
// needsToken=false: forces refresh
// --- Anonymous/guest auth (no account needed) ---
await auth.AuthAnonymous();
// --- Profile info after successful login ---
Console.WriteLine(auth.Profile.Username); // "MyUsername"
Console.WriteLine(auth.Profile.HasPremium); // true
Console.WriteLine(auth.Subscription?.IsActive); // true
// --- Multi-profile: switch to a specific profile ---
await auth.ChangeProfile("profile_id_string");
// --- Check current profile ---
var profile = auth.Profile;
// profile.Username, profile.Avatar, profile.PreferredContentAudioLanguage,
// profile.PreferredContentSubtitleLanguage, profile.HasPremium
// --- Endpoint selection (controls which token file is used) ---
// Endpoint "tv/android_tv" → cr_token_tv.json
// Endpoint "android/phone" → cr_token_android.json
// Endpoint "---" (guest) → cr_token_guest.json
// Default → cr_token.json
```
--------------------------------
### Configure History Auto-Refresh Interval and Mode
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Set the auto-refresh interval in minutes (0 to disable) and choose a refresh mode. FastNewReleases is recommended for efficient checking.
```csharp
var opts = CrunchyrollManager.Instance.CrunOptions;
// Auto-refresh interval (0 = disabled)
opts.HistoryAutoRefreshIntervalMinutes = 60; // refresh every 60 minutes
// Refresh mode
opts.HistoryAutoRefreshMode = HistoryRefreshMode.FastNewReleases;
// HistoryRefreshMode.DefaultAll → full refresh of all history entries
// HistoryRefreshMode.DefaultActive → refresh only entries marked Active
// HistoryRefreshMode.FastNewReleases → fast check via release feed (recommended)
```
--------------------------------
### QueueManager - Control Download Queue
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Manages the observable download queue, including active downloads, queue state, and completion events. Use this to add items, monitor progress, and react to queue changes.
```csharp
using CRD.Downloader;
var qm = QueueManager.Instance;
// --- Add a resolved episode metadata item to the queue ---
vim.AddToQueue(crunchyEpMetaItem);
// --- Queue state ---
Console.WriteLine(qm.ActiveDownloads); // number of currently active downloads
Console.WriteLine(qm.HasActiveDownloads); // bool
Console.WriteLine(qm.HasFailedItem); // bool – true if any item is in Error state
// --- Queue contents (observable) ---
foreach (var ep in qm.Queue){
Console.WriteLine($"{ep.SeriesTitle} S{ep.Season}E{ep.EpisodeNumber}");
}
// --- React to queue state changes ---
vim.QueueStateChanged += (sender, args) => {
Console.WriteLine($"Queue changed. Active: {qm.ActiveDownloads}");
};
// --- Download item UI models (bound to the Downloads tab) ---
foreach (var item in qm.DownloadItemModels){
Console.WriteLine($"{item.EpTitle} – {item.DownloadState}");
// DownloadState: Queued, Downloading, Paused, Processing, Done, Error
}
```
--------------------------------
### One-Shot Headless Refresh CLI Flags
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
These CLI flags can be used for a single, non-interactive refresh of history entries. --historyAddToQueue can be combined to automatically add missing episodes.
```bash
// Equivalent CLI flags for one-shot headless refresh:
// --historyRefreshAll → HistoryRefreshMode.DefaultAll
// --historyRefreshActive → HistoryRefreshMode.DefaultActive
// --historyAddToQueue → after refresh, add missing episodes to queue
```
--------------------------------
### Filename Template Variables
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
A comprehensive list of variables for customizing filenames and folder structures. Includes standard variables and Sonarr-specific ones that are available when Sonarr is connected and an episode is matched.
```text
${seriesTitle} Series name (e.g., "Attack on Titan")
${seasonTitle} Season name (e.g., "The Final Season")
${title} Episode title (e.g., "The Dawn of Humanity")
${season} Season number (zero-padded per Numbers setting: "04")
${episode} Episode number (zero-padded: "28")
${height} Video height in pixels (e.g., "1080")
${width} Video width in pixels (e.g., "1920")
${dubs} Selected dub languages (e.g., "ja-JP")
# Sonarr variables (only when Sonarr is connected and episode is matched)
${sonarrSeriesTitle} Series title from Sonarr
${sonarrSeriesReleaseYear} Series release year from Sonarr
${sonarrEpisodeTitle} Episode title from Sonarr
# Folder structure example:
# Template: ${seriesTitle}\${seriesTitle} - S${season}E${episode} [${height}p]
# Result: Attack on Titan/Attack on Titan - S04E28 [1080p]
```
--------------------------------
### Docker Compose for FlareSolverr MITM Proxy
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/6.-FlareSolverr-MITM-Proxy
Defines services for FlareSolverr and its MITM proxy. Configure optional upstream proxy settings using environment variables.
```yaml
version: "2.1"
services:
flaresolverr-mitm-proxy:
image: ghcr.io/zelak312/flaresolverr-mitm-proxy:latest
container_name: flaresolverr-mitm-proxy
restart: unless-stopped
# environment:
# - PROXY=http://localhost:8181 # Optional: only use if you want to use an upstream proxy
# - PROXY_AUTH=user:pass # Optional: only use if you have an upstream proxy with auth
ports:
- 8080:8080
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
environment:
- LOG_LEVEL=${LOG_LEVEL:-info}
- LOG_HTML=${LOG_HTML:-false}
- CAPTCHA_SOLVER=${CAPTCHA_SOLVER:-none}
- TZ=Europe/London
ports:
- 8191:8191
restart: unless-stopped
```
--------------------------------
### Crunchyroll Downloader Directory Structure
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
This outlines the expected directory structure for Crunchyroll Downloader (CRD). It specifies the locations for required executables, Widevine CDM files, fonts, presets, and configuration files.
```tree
CRD/
├── lib/
│ ├── ffmpeg.exe # Required for muxing/encoding
│ ├── mkvmerge.exe # Required for MKV muxing
│ ├── mp4decrypt.exe # Required for DRM decryption (Bento4)
│ └── shaka-packager.exe # Alternative DRM decryptor (use v2.6.1, NOT v3.x)
├── widevine/
│ ├── device_client_id_blob.bin # Widevine CDM – must be sourced independently
│ └── device_private_key.pem # Widevine CDM – must be sourced independently
├── fonts/ # Optional: subtitle fonts (.ttf/.otf)
├── presets/ # Encoding presets (FFmpeg)
├── config/
│ ├── settings.json # CrDownloadOptions persisted here
│ ├── cr_token.json # Auth token (auto-managed)
│ ├── history.json # Download history (gzip-compressed JSON)
│ └── queue.json # Persisted download queue
└── CRD.exe
```
--------------------------------
### Apply Variable Overrides and Sanitize Filenames
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Modify existing variables using a list of override strings and sanitize strings to remove illegal filesystem characters.
```csharp
using CRD.Utils.Files;
using CRD.Utils.Structs;
// --- Build variable list ---
var variables = new List{
new Variable { Name = "seriesTitle", ReplaceWith = "Attack on Titan", Type = "string", Sanitize = true },
new Variable { Name = "seasonTitle", ReplaceWith = "Season 4", Type = "string", Sanitize = true },
new Variable { Name = "season", ReplaceWith = 4, Type = "int32" },
new Variable { Name = "episode", ReplaceWith = 28, Type = "int32" },
new Variable { Name = "title", ReplaceWith = "The Dawn of Humanity", Type = "string", Sanitize = true },
new Variable { Name = "height", ReplaceWith = 1080, Type = "int32" },
new Variable { Name = "width", ReplaceWith = 1920, Type = "int32" },
new Variable { Name = "dubs", ReplaceWith = "ja-JP", Type = "string", Sanitize = true },
};
// --- Apply variable overrides ---
var overrides = new List{ "season='99'", "episode='01'" };
var overridden = FileNameManager.ParseOverride(variables, overrides);
// --- Sanitize a filename string directly ---
string clean = FileNameManager.CleanupFilename("Title: With/Illegal?Chars*");
// clean = "Title With IllegalChars" (illegal chars removed)
```
--------------------------------
### HTTP Proxy URL Format
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/5-‐-General-Settings
Specifies the URL format for HTTP proxy connections when 'Use Socks5 Proxy' is disabled. Ensure the host and port are correctly configured.
```text
http://HOST:PORT
```
--------------------------------
### Dispatch Download Finished Notification
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Dispatches a notification event for a finished download. Ensure NotificationDispatcher is initialized and CrunOptions are accessible. Metadata can be customized for specific event details.
```csharp
using CRD.Utils.Notifications;
// --- Dispatch a notification event ---
var settings = CrunchyrollManager.Instance.CrunOptions.NotificationSettings;
var evt = new NotificationEvent{
Type = NotificationEventType.DownloadFinished,
Title = "Download finished",
Message = "Finished processing Attack on Titan.",
TimestampUtc = DateTimeOffset.UtcNow,
Metadata = new Dictionary{
{ "seriesTitle", "Attack on Titan" },
{ "seriesId", "GYQ4MQ496" },
{ "seasonTitle", "Season 4" },
{ "seasonId", "GY9PX29Q6" },
{ "seasonNumber", "4" },
{ "episodeTitle", "The Dawn of Humanity" },
{ "episodeId", "GRDKJZ81Y" },
{ "episodeNumber","28" },
{ "downloadPath", "C:/Downloads/Attack on Titan/S04E28.mkv" },
{ "downloadSubs", "en-US" },
{ "downloadDubs", "ja-JP,en-US" },
}
};
await NotificationDispatcher.Instance.PublishAsync(settings, evt);
```
--------------------------------
### CrQueue - Add Episodes to Download Queue
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Adds a Crunchyroll episode to the download queue by its ID. It resolves stream metadata, applies overrides, and handles authentication refresh. Specify desired dub languages and download modes.
```csharp
using CRD.Downloader.Crunchyroll;
var crQueue = CrunchyrollManager.Instance.CrQueue;
// --- Add a single episode by ID ---
await crQueue.CrAddEpisodeToQueue(
epId: "GRDKJZ81Y", // Crunchyroll episode ID from URL /watch/GRDKJZ81Y
crLocale: "en-US", // Language for title/description
dubLang: new List { "ja-JP", "en-US" }, // Desired dub languages
updateHistory: true, // Update history record after queuing
episodeDownloadMode: EpisodeDownloadMode.Default // Default, OnlyVideo, OnlyAudio, OnlySubs
);
// --- EpisodeDownloadMode options ---
// EpisodeDownloadMode.Default → download video + audio + subs
// EpisodeDownloadMode.OnlyVideo → video stream only
// EpisodeDownloadMode.OnlyAudio → audio stream only
// EpisodeDownloadMode.OnlySubs → subtitle files only
// The method automatically:
// - Refreshes auth token before calling the API
// - Checks premium status for premium-only episodes
// - Applies history dub/sub language overrides if History is enabled
// - Applies Sonarr season/episode numbering if SonarrProperties.UseSonarrNumbering = true
// - Resolves per-series download folder overrides
```
--------------------------------
### URL Input Formats for Adding Downloads
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
CRD accepts full Crunchyroll URLs or path-only shorthand for adding downloads. The locale in the URL path determines the language for the title and description.
```text
# Full URLs (locale in path sets language for title/description)
https://www.crunchyroll.com/series/GY9PX29Q6/attack-on-titan
https://www.crunchyroll.com/watch/GRDKJZ81Y/the-dawn-of-humanity
https://www.crunchyroll.com/fr/series/GY9PX29Q6 # French locale
https://www.crunchyroll.com/artist/MA179CB50X
# Path-only shorthand (also accepted)
/series/GY9PX29Q6
/watch/GRDKJZ81Y
/artist/MA179CB50X
```
--------------------------------
### SOCKS5 Proxy URL Format
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/5-‐-General-Settings
Specifies the URL format for SOCKS5 proxy connections when 'Use Socks5 Proxy' is enabled. This format is used for SOCKS5 proxy configurations.
```text
socks5://HOST:PORT
```
--------------------------------
### Parse Filename Templates with Variables
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Use FileNameManager to parse template strings with `${variable}` placeholders. Provide a list of Variable objects and specify options for number padding and whitespace replacement.
```csharp
using CRD.Utils.Files;
using CRD.Utils.Structs;
// --- Build variable list ---
var variables = new List{
new Variable { Name = "seriesTitle", ReplaceWith = "Attack on Titan", Type = "string", Sanitize = true },
new Variable { Name = "seasonTitle", ReplaceWith = "Season 4", Type = "string", Sanitize = true },
new Variable { Name = "season", ReplaceWith = 4, Type = "int32" },
new Variable { Name = "episode", ReplaceWith = 28, Type = "int32" },
new Variable { Name = "title", ReplaceWith = "The Dawn of Humanity", Type = "string", Sanitize = true },
new Variable { Name = "height", ReplaceWith = 1080, Type = "int32" },
new Variable { Name = "width", ReplaceWith = 1920, Type = "int32" },
new Variable { Name = "dubs", ReplaceWith = "ja-JP", Type = "string", Sanitize = true },
};
// --- Parse a flat filename template ---
string template = "${seriesTitle} - S${season}E${episode} [${height}p]";
List parts = FileNameManager.ParseFileName(
template,
variables,
numbers: 2, // leading zero width (e.g., 2 → "04", "28")
whiteSpaceReplace: ".", // replace spaces with "." in string variables
override: null
);
// parts = ["Attack.on.Titan - S04E28 [1080p]"]
// --- Parse a template with folder structure ---
string folderTemplate = "${seriesTitle}\\${seriesTitle} - S${season}E${episode}";
List pathParts = FileNameManager.ParseFileName(
folderTemplate, variables, 2, "", null
);
// pathParts = ["Attack on Titan", "Attack on Titan - S04E28"]
// Join with Path.Combine to get: "Attack on Titan/Attack on Titan - S04E28"
```
--------------------------------
### Supported Locales for Dubs and Subs
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
List of locale codes supported by Crunchy-DL for specifying dub and sub languages. Use the string value in your settings.
```csharp
// Locale enum values (use the string value in settings)
"en-US" // English (US)
"es-LA" // Spanish (Latin America)
"es-ES" // Spanish (Spain)
"pt-BR" // Portuguese (Brazil)
"pt-PT" // Portuguese (Portugal)
"fr-FR" // French
"de-DE" // German
"ar-ME" // Arabic (Middle East)
"ar-SA" // Arabic (Saudi Arabia)
"it-IT" // Italian
"ru-RU" // Russian
"tr-TR" // Turkish
"hi-IN" // Hindi
"zh-CN" // Chinese (Simplified)
"zh-TW" // Chinese (Traditional)
"zh-HK" // Chinese (Hong Kong)
"ko-KR" // Korean
"ja-JP" // Japanese
"id-ID" // Indonesian
"pl-PL" // Polish
"th-TH" // Thai
"ms-MY" // Malay
"vi-VN" // Vietnamese
```
--------------------------------
### Delete Empty Folders
Source: https://context7.com/crunchy-dl/crunchy-downloader/llms.txt
Recursively delete empty subfolders within a specified directory. The root directory itself can also be deleted if it becomes empty.
```csharp
using CRD.Utils.Files;
// --- Delete empty folders after a download ---
FileNameManager.DeleteEmptyFolders("/path/to/temp/dir", deleteRootIfEmpty: true);
```
--------------------------------
### Default Webhook Payload Structure
Source: https://github.com/crunchy-dl/crunchy-downloader/wiki/5-‐-General-Settings
This is the default JSON payload sent for webhook notifications when no custom body template is specified. It includes event details and metadata.
```json
{
"eventType": "DownloadFinished",
"title": "Download finished",
"message": "Finished processing Example Series.",
"timestampUtc": "2026-05-14T18:30:00.0000000+00:00",
"metadata": {
"seriesTitle": "Example Series",
"seriesId": "G6ABC1234",
"seasonTitle": "Season 1",
"seasonId": "G6ABCSEASON1",
"seasonNumber": "1",
"episodeTitle": "Episode Title",
"episodeId": "G6ABCEP001",
"episodeNumber": "1"
}
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.