Skip to content

Downloading

unshackle dl is the main download command: it fetches a title's manifest from a streaming service, selects exactly the tracks you asked for, acquires and applies decryption keys, and muxes everything into a finished Matroska file. The flags below cover quality and codec selection, language and subtitle handling, episode ranges, and the download flow itself, with examples throughout.

Where the full flag list lives

This page covers the flags you will use most and explains how they interact. It is not an exhaustive enumeration. For the complete, always-current list of every option and its exact wording, run unshackle dl --help. Every flag shown here can also be given a default in your configuration file. See Configuration file.

Command shape

A download is always three layers: the root CLI, the dl command (which is where all the flags below are parsed), and a service tag subcommand that carries the title argument.

unshackle dl [OPTIONS] SERVICE [SERVICE ARGUMENTS]
  • unshackle: the root command.
  • dl: the download command. All of the options on this page are parsed here, so they go before the service tag.
  • SERVICE: a service tag such as EXAMPLE1, EXAMPLE2, EXAMPLE3. Service tags are case-insensitive and honour each service's aliases (for example example+ resolves to its real tag).
  • SERVICE ARGUMENTS: usually a title ID or URL. This positional argument belongs to the service, not to dl, so it comes after the tag.
A minimal download
unshackle dl EXAMPLE 81234567
Flags belong to dl, the title belongs to the service
unshackle dl -q 1080 -v H.265 -r HDR10 --lang en EXAMPLE 'https://www.example.com/...'

See what a service accepts

Because the positional argument is defined by each service, run unshackle dl SERVICE --help (e.g. unshackle dl EXAMPLE --help) to see that service's own argument and any service-specific options.

The download flow

When you run a download, dl moves through the pipeline below. Understanding the order helps explain why, for example, --list stops early and why keys are fetched even with --skip-dl.

  1. Setup: load the DRM CDM, key vaults, proxy providers, cookies, and credentials.
  2. Authenticate: sign in to the service with your profile's cookies/credentials.
  3. Fetch titles: retrieve the movie, episode list, or album (cached unless --no-cache/--reset-cache).
  4. Filter titles: apply --wanted, --latest-episode, or --select-titles.
  5. Get tracks: parse the manifest into video, audio, subtitle, and chapter tracks.
  6. Select tracks: narrow each type down using your quality, codec, range, language, and bitrate flags.
  7. Download: pull segments for the selected tracks (concurrently per --downloads).
  8. License & decrypt: acquire content keys (vault → CDM), decrypt each track.
  9. Post-process: extract closed captions, convert subtitles, repack, mux with mkvmerge, and move the finished file to your downloads directory.

--list and --list-titles stop after selection/filtering and print what would be downloaded. --skip-dl runs the license step but skips the actual segment download.

Choosing quality

Resolution

-q / --quality takes one or more target resolutions (heights) as a comma-separated list. Without it, unshackle picks the best available resolution.

Single resolution
unshackle dl -q 1080 EXAMPLE 81234567
Multiple resolutions in one run
unshackle dl -q 2160,1080,720 EXAMPLE 81234567

16:9 canvas matching

Resolution matching is by track height first. If no track has an exact matching height, unshackle falls back to a 16:9-canvas match, so -q 1080 will also match an anamorphic 1920×804 track (computed as int(width × 9 / 16)).

Best-available and worst

By default a missing requested resolution is an error. Two flags change that:

Flag Behaviour
--best-available If the requested resolution(s) aren't present, continue with the best that is available instead of failing. Also softens missing video/audio/subtitle languages and hybrid fallbacks.
--worst Within the specified quality, pick the lowest bitrate rendition. Requires -q/--quality.
Never fail on a missing resolution
unshackle dl -q 2160 --best-available EXAMPLE 0ABC123

Video codec and color range

Codec

-v / --vcodec selects one or more video codecs; the default is any codec. It accepts either enum names or their values, comma-separated.

Name Value
AVC H.264
HEVC H.265
VC1 VC-1
VP8 VP8
VP9 VP9
AV1 AV1
Either spelling works
unshackle dl -v HEVC   EXAMPLE 81234567
unshackle dl -v H.265  EXAMPLE 81234567
unshackle dl -v hevc,avc EXAMPLE 81234567

Color range

-r / --range selects one or more color ranges; the default is SDR.

Range Meaning
SDR Standard dynamic range (default)
HLG Hybrid Log-Gamma
HDR10 HDR10
HDR10P HDR10+
DV Dolby Vision
HYBRID Fetch both an HDR10/HDR10+ base and a DV track, then merge them
Grab HDR10 and Dolby Vision in one run
unshackle dl -q 2160 -r HDR10,DV EXAMPLE '...'

HYBRID requires dovi_tool

-r HYBRID produces a single hybrid stream by injecting the Dolby Vision RPU metadata onto an HDR10/HDR10+ base layer using dovi_tool. It requires the dovi_tool binary on your PATH and needs both an HDR10(+) and a DV track to be available, otherwise the title fails (unless --best-available lets it fall back). When HDR10+ is present it is preferred over HDR10 as the base layer.

To keep an HDR10+ deliverable alongside the hybrid, request both ranges: -r HYBRID,HDR10P. -r HYBRID on its own muxes only the merged hybrid.

Bitrate selection

By default unshackle keeps the highest-bitrate rendition for each selected resolution/codec/range/language combination. You can constrain this.

Flag Purpose
-vb / --vbitrate Exact video bitrate in kbps.
-ab / --abitrate Exact audio bitrate in kbps.
-vb-range / --vbitrate-range Video bitrate range in kbps, e.g. 6000-7000; picks the highest within it.
-ab-range / --abitrate-range Audio bitrate range in kbps, e.g. 128-256.

Exact vs range are mutually exclusive

--vbitrate cannot be combined with --vbitrate-range, and likewise for the audio pair. Pick one form.

Real bitrate probing

Manifest-declared bitrates are sometimes rounded or wrong. Services often advertise a peak or nominal bandwidth that is far from the stream's real average. This matters because a track's bitrate drives the track listing, the sort order, and the --vbitrate/--vbitrate-range selection above. A bogus declared value therefore makes unshackle pick the wrong track. These flags remove that risk by probing the actual media size to compute a true bitrate for the top renditions, overriding the manifest value:

  • -rvb / --real-video-bitrate: probe real video bitrates (per codec/range).
  • -rab / --real-audio-bitrate: probe real audio bitrates (per codec/channels/ language). Slower than the video variant because there are more renditions to probe.

Reading the probed numbers

A single-file track (DASH SegmentBase/BaseURL) is measured exactly. A multi-segment track (most HLS) is a sampled estimate, normally within a few percent of the true value. For MPEG-TS HLS the probed figure also reads a few percent above the demuxed elementary stream, because the segment bytes include container overhead. That is the real delivered size, not an over-report or a bug.

Why not every rendition is probed

Probing does not touch every rendition. Only the top rendition of each quality tier is probed in parallel (video grouped by codec+range, audio by codec+channels+language), and the pass then reaches downward only as far as it must to keep the ranking correct. This keeps probing fast even when a service exposes dozens of renditions. Tracks whose duration can't be determined fall back to ffprobe, and a probe failure is non-fatal: the manifest value is simply left in place.

Audio codec, channels, and Atmos

Codec

-a / --acodec selects one or more audio codecs (comma-separated); the default is any.

Name Value Codec
AAC AAC Advanced Audio Coding
AC3 DD Dolby Digital
EC3 DD+ Dolby Digital Plus
AC4 AC-4 Dolby AC-4
OPUS OPUS Opus
OGG VORB Vorbis
DTS DTS DTS
ALAC ALAC Apple Lossless
FLAC FLAC FLAC

Names, values, and a few aliases are accepted: eac3 and ddp both resolve to EC3, and vorbis resolves to OGG.

Prefer Dolby Digital Plus, fall back to AAC
unshackle dl -a EC3,AAC EXAMPLE 81234567

Channels and Atmos

  • -c / --channels: desired channel layout, e.g. 5.1 or 2.0. Matching is by ceiling, so 5.1 implicitly matches a 6.0-reported layout.
  • -naa / --noatmos: exclude Dolby Atmos audio tracks from selection.
5.1 audio, no Atmos
unshackle dl -c 5.1 --noatmos EXAMPLE 0ABC123

Languages

Video and audio language

-l / --lang sets the wanted language(s) for both video and audio. The default is orig, the title's original language.

Original language plus English
unshackle dl -l orig,en EXAMPLE 81234567

The special token orig is resolved to the title's actual original language everywhere it is used. You can override each stream type independently:

  • -vl / --v-lang: language for video only (overrides -l for video). Useful when the burned-in video language differs from the audio you want.
  • -al / --a-lang: language for audio only (overrides -l for audio).
English audio over the original video
unshackle dl -al en EXAMPLE 81234567

Exact vs fuzzy matching

By default language matching is fuzzy: -l en also accepts en-US, en-GB, etc. (up to a small distance). Pass --exact-lang to require an exact match: with it, -l es-419 matches only es-419, not es-ES.

The all and best tokens

For audio, the tokens all and best bypass the usual one-track-per-language pick and instead select the best track for each language present. For subtitles, all keeps every subtitle language.

Subtitles

Selecting subtitle languages

-sl / --s-lang sets the wanted subtitle language(s). The default is all, meaning every available subtitle language is downloaded.

Only English and Spanish subtitles
unshackle dl -sl en,es EXAMPLE 81234567

Requiring subtitles

--require-subs takes a list of languages that must exist. If they all exist, all subtitles are downloaded; if any is missing, the title fails. This is useful for gating a download on the presence of a specific subtitle track.

Cannot combine with --s-lang

--require-subs and --s-lang are mutually exclusive. Use one or the other.

Forced subtitles and output format

  • -fs / --forced-subs: include forced subtitle tracks (signs/foreign dialogue). Without this flag, forced subs are dropped from selection.
  • --sub-format: set the output subtitle format, converting only when necessary. Accepts codec names/values and common aliases (srt, vtt, ass, ssa, ttml, etc.), or the literal original to keep the source format.
Value Format
SRT / srt SubRip
VTT / vtt WebVTT
ASS / ass Advanced SubStation Alpha
SSA / ssa SubStation Alpha
TTML / ttml Timed Text Markup
original Keep the source format, no conversion
Convert subtitles to SRT
unshackle dl --sub-format srt EXAMPLE 81234567

SDH stripping happens by default

When a subtitle track is marked SDH (for the deaf/hard-of-hearing) and there is no plain same-language subtitle, unshackle produces a stripped, non-SDH variant automatically. This behaviour is governed by the subtitle.strip_sdh config option (default on).

Selecting episodes

For series, several flags control which episodes are downloaded. By default, all episodes are downloaded.

Wanted ranges

-w / --wanted accepts flexible season/episode ranges, comma-separated. Prefix a token with - to exclude it.

unshackle dl -w S01 EXAMPLE 81234567
unshackle dl -w S01-S03 EXAMPLE 81234567
unshackle dl -w S01,S03,S05 EXAMPLE 81234567
unshackle dl -w S01E01 EXAMPLE 81234567
unshackle dl -w S01E01-S01E05 EXAMPLE 81234567
unshackle dl -w S01E01-S02E03 EXAMPLE 81234567
# Seasons 1 through 5, but not season 3
unshackle dl -w S01-S05,-S03 EXAMPLE 81234567

Other selection flags

Flag Behaviour
--select-titles Interactively pick episodes from a list (Series only). Cannot combine with -w.
--latest-episode Download only the single most recent episode.
--list-titles List the titles that would be downloaded, then stop.
Grab just the newest episode
unshackle dl --latest-episode EXAMPLE 81234567

Including and excluding track types

You can restrict a download to certain track categories, either positively (only these) or negatively (everything but these).

Only these types (*-only flags):

  • -V / --video-only
  • -A / --audio-only
  • -S / --subs-only
  • -C / --chapters-only

Skip these types (no-* flags):

  • -nv / --no-video
  • -na / --no-audio
  • -ns / --no-subs
  • -nc / --no-chapters

Additional track-type flags:

  • -ad / --audio-description: include descriptive (audio-description) tracks, which are dropped by default.
  • --skip-subtitle-errors: if a subtitle fails to download, skip it and continue rather than aborting the whole title. Video and audio failures remain fatal.
Subtitles only
unshackle dl -S -sl en EXAMPLE 81234567
Everything except chapters
unshackle dl -nc EXAMPLE 81234567

Note

You can combine an *-only flag with no-* flags to fine-tune: *-only chooses the starting set of categories, then no-* subtracts from it. Attachments (e.g. fonts) are always kept.

Listing and dry runs

Before committing to a long download, inspect what unshackle would do:

Flag Effect
--list List the available tracks and which would be selected, then stop. No download.
--list-titles List the titles (episodes) that would be downloaded, then stop.
--skip-dl Skip downloading but still acquire the decryption keys.
See the track selection without downloading
unshackle dl -q 1080 -v H.265 -r HDR10 --list EXAMPLE 81234567

Output and muxing

Output location and folders

  • -o / --output: override the output directory for this run (otherwise the configured downloads directory is used).
  • --no-folder: do not create a per-show folder for TV downloads.
  • --no-source: remove the service source tag from the filename and path.
Send this download somewhere specific
unshackle dl -o ~/Videos/incoming EXAMPLE 81234567

Muxing behaviour

By default, tracks are muxed into a single Matroska (.mkv) file with mkvmerge. These flags change how the output is assembled:

Flag Behaviour Default source
--no-mux Do not mux; keep the individual track files. -
--split-audio Write a separate output file per audio codec instead of merging all audio. config muxing.merge_audio (on)
--merge-video Mux all selected video tracks into one file. config muxing.merge_video (off)

Naming tags

  • --tag: set the release group tag (overrides the configured tag).
  • --repack: add a REPACK tag to the output filename.
Custom group tag and a REPACK label
unshackle dl --tag MYGRP --repack EXAMPLE 81234567

Proxies

--proxy accepts a full proxy URI, a 2-letter country code (resolved through your configured proxy providers), or a provider:region form.

Proxy forms
unshackle dl --proxy us EXAMPLE 81234567
unshackle dl --proxy nordvpn:ca EXAMPLE 81234567
unshackle dl --proxy 'http://user:pass@host:8080' EXAMPLE 81234567

Two related flags:

  • --no-proxy: force-disable all proxy use for this run.
  • --no-proxy-download: bypass the proxy for segment downloads only. The manifest, license, and authentication requests still go through the proxy. This is useful when the proxy is only needed to satisfy geo-checks, not to move the bulk of the data.

Performance and caching

Flag Purpose
--workers N Threads used per track for segment downloads. Default depends on the downloader.
--downloads N Number of tracks downloaded concurrently. Default 1.
--slow [MIN-MAX] Add a delay between titles to look more like a real device. --slow alone means 60-120s; --slow 20-40 sets a custom range. Minimum 20s.
--no-cache Bypass the title cache for this download.
--reset-cache Clear the title cache before fetching.
Two tracks at a time, eight threads each
unshackle dl --downloads 2 --workers 8 EXAMPLE 81234567
Space out a season download
unshackle dl -w S01 --slow 30-60 EXAMPLE 81234567

Keys, vaults, and export

By default, unshackle checks your key vaults first and only asks a CDM to license a key when the vault misses. You can force one side or the other:

  • --cdm-only: only use the CDM (skip vaults).
  • --vaults-only: only use key vaults (never license via the CDM); a missing key fails.
Fetch keys only, no download
unshackle dl --skip-dl EXAMPLE 81234567

--export writes a JSON file, into the configured exports directory, containing track info and the acquired content keys for each title. This is the format consumed by unshackle import to reconstruct a download later.

Export track info and keys
unshackle dl --skip-dl --export EXAMPLE 81234567

Region is recorded only with a proxy

When --proxy is used, the export records the region so an import can reproduce the correct geofence. Without a proxy, no region is stored.

Metadata and tagging

unshackle looks up metadata automatically, but you can override the identifiers used for tagging and naming:

Flag Example Purpose
--tmdb --tmdb 27205 Use this TMDB ID instead of automatic lookup.
--imdb --imdb tt1375666 Use this IMDb ID.
--animeapi --animeapi mal:12345 Resolve via AnimeAPI (mal:/anilist: prefix; defaults to MAL).
--enrich - Override the show title and year from an external source. Requires one of --tmdb, --imdb, or --animeapi.
Force the right IMDb match and enrich the title
unshackle dl --imdb tt1375666 --enrich EXAMPLE 81234567

Configuration defaults

Every flag on this page can be set as a default in your configuration file so you don't have to type it each time, and defaults can be scoped per service. See Configuration file for the dl: block and per-service overrides.

Explicit flags always win

A value you pass on the command line (or via an environment variable) always takes precedence over both the global dl: defaults and any per-service dl: overrides. Config only fills in options you didn't set explicitly.

Quick reference

A condensed lookup of the most-used options. Run unshackle dl --help for the complete, authoritative list.

Flag Short Meaning
--quality -q Target resolution(s), e.g. 1080,720.
--vcodec -v Video codec(s).
--acodec -a Audio codec(s).
--range -r Color range(s); default SDR.
--channels -c Audio channel layout.
--noatmos -naa Exclude Atmos audio.
--lang -l Video + audio language(s); default orig.
--a-lang -al Audio-only language override.
--v-lang -vl Video-only language override.
--s-lang -sl Subtitle language(s); default all.
--forced-subs -fs Include forced subtitles.
--sub-format Output subtitle format.
--wanted -w Episode/season range.
--select-titles Interactively pick episodes.
--latest-episode Only the newest episode.
--video-only / --audio-only / --subs-only -V / -A / -S Restrict track types.
--no-video / --no-audio / --no-subs / --no-chapters -nv / -na / -ns / -nc Skip track types.
--worst Lowest bitrate within -q.
--best-available Degrade gracefully instead of failing.
--output -o Output directory for this run.
--split-audio / --merge-video / --no-mux Muxing behaviour.
--proxy / --no-proxy / --no-proxy-download Proxy control.
--workers / --downloads / --slow Concurrency and pacing.
--list / --list-titles / --skip-dl Dry runs.
--cdm-only / --vaults-only Key source control.
--export Export track info and keys to JSON.
--tmdb / --imdb / --animeapi / --enrich Metadata overrides.