Files
unshackle/guide/downloading/index.html
T
2026-10-05 22:44:52 +00:00

4561 lines
150 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Movie, TV, and Music archival software. User guide and REST API reference">
<link rel="canonical" href="https://docs.unshackle.dev/guide/downloading/">
<link rel="prev" href="../../getting-started/configuration-file/">
<link rel="next" href="../cli-reference/">
<link rel="icon" href="../../assets/favicon.svg">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
<title>Downloading - unshackle</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.ec1eaa64.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../assets/_mkdocstrings.css">
<link rel="stylesheet" href="../../assets/extra.css">
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#downloading" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="unshackle" class="md-header__button md-logo" aria-label="unshackle" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m800-274-80-80v-206H514l-80-80h166v-80q0-50-34.5-85T481-840q-50 0-84 34.5T363-720v9l-73-73q22-61 75-98.5T481-920q83 0 141 58.5T680-720v80h40q33 0 56.5 23.5T800-560v286Zm20 246-62-62q-11 5-20 7.5T720-80H240q-33 0-56.5-23.5T160-160v-400q0-25 14.5-46t37.5-30L28-820l56-56L876-84l-56 56ZM686-160 539-309q-11 11-25.5 17t-31.5 6q-33 0-56.5-23.5T402-366q0-17 6-31.5t17-25.5L286-560h-46v400h446ZM486-360Zm131-97Z"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
unshackle
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Downloading
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme)" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1M8 13h8v-2H8zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 5-5 5 5 0 0 0-5-5"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="indigo" aria-label="Switch to system preference" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="Switch to system preference" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5M7 15a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/unshackle-dl/unshackle" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
unshackle-dl/unshackle
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../../getting-started/installation/" class="md-tabs__link">
Getting Started
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="./" class="md-tabs__link">
User Guide
</a>
</li>
<li class="md-tabs__item">
<a href="../../reference/configuration/" class="md-tabs__link">
Configuration
</a>
</li>
<li class="md-tabs__item">
<a href="../../dev/creating-a-service/" class="md-tabs__link">
Developer
</a>
</li>
<li class="md-tabs__item">
<a href="../../reference/api/service/" class="md-tabs__link">
API Reference
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="unshackle" class="md-nav__button md-logo" aria-label="unshackle" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m800-274-80-80v-206H514l-80-80h166v-80q0-50-34.5-85T481-840q-50 0-84 34.5T363-720v9l-73-73q22-61 75-98.5T481-920q83 0 141 58.5T680-720v80h40q33 0 56.5 23.5T800-560v286Zm20 246-62-62q-11 5-20 7.5T720-80H240q-33 0-56.5-23.5T160-160v-400q0-25 14.5-46t37.5-30L28-820l56-56L876-84l-56 56ZM686-160 539-309q-11 11-25.5 17t-31.5 6q-33 0-56.5-23.5T402-366q0-17 6-31.5t17-25.5L286-560h-46v400h446ZM486-360Zm131-97Z"/></svg>
</a>
unshackle
</label>
<div class="md-nav__source">
<a href="https://github.com/unshackle-dl/unshackle" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
unshackle-dl/unshackle
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
Getting Started
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Getting Started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../getting-started/installation/" class="md-nav__link">
<span class="md-ellipsis">
Installation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/quickstart/" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/configuration-file/" class="md-nav__link">
<span class="md-ellipsis">
The Configuration File
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="">
<span class="md-ellipsis">
User Guide
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
User Guide
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Downloading
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Downloading
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#command-shape" class="md-nav__link">
<span class="md-ellipsis">
Command shape
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-download-flow" class="md-nav__link">
<span class="md-ellipsis">
The download flow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#choosing-quality" class="md-nav__link">
<span class="md-ellipsis">
Choosing quality
</span>
</a>
<nav class="md-nav" aria-label="Choosing quality">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#resolution" class="md-nav__link">
<span class="md-ellipsis">
Resolution
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#best-available-and-worst" class="md-nav__link">
<span class="md-ellipsis">
Best-available and worst
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#video-codec-and-colour-range" class="md-nav__link">
<span class="md-ellipsis">
Video codec and colour range
</span>
</a>
<nav class="md-nav" aria-label="Video codec and colour range">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#codec" class="md-nav__link">
<span class="md-ellipsis">
Codec
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#colour-range" class="md-nav__link">
<span class="md-ellipsis">
Colour range
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#bitrate-selection" class="md-nav__link">
<span class="md-ellipsis">
Bitrate selection
</span>
</a>
<nav class="md-nav" aria-label="Bitrate selection">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#real-bitrate-probing" class="md-nav__link">
<span class="md-ellipsis">
Real bitrate probing
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#audio-codec-channels-and-atmos" class="md-nav__link">
<span class="md-ellipsis">
Audio codec, channels, and Atmos
</span>
</a>
<nav class="md-nav" aria-label="Audio codec, channels, and Atmos">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#codec_1" class="md-nav__link">
<span class="md-ellipsis">
Codec
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#channels-and-atmos" class="md-nav__link">
<span class="md-ellipsis">
Channels and Atmos
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#music-quality" class="md-nav__link">
<span class="md-ellipsis">
Music quality
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#languages" class="md-nav__link">
<span class="md-ellipsis">
Languages
</span>
</a>
<nav class="md-nav" aria-label="Languages">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#video-and-audio-language" class="md-nav__link">
<span class="md-ellipsis">
Video and audio language
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#excluding-languages" class="md-nav__link">
<span class="md-ellipsis">
Excluding languages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sort-order" class="md-nav__link">
<span class="md-ellipsis">
Sort order
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#exact-vs-fuzzy-matching" class="md-nav__link">
<span class="md-ellipsis">
Exact vs fuzzy matching
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#subtitles" class="md-nav__link">
<span class="md-ellipsis">
Subtitles
</span>
</a>
<nav class="md-nav" aria-label="Subtitles">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#selecting-subtitle-languages" class="md-nav__link">
<span class="md-ellipsis">
Selecting subtitle languages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#requiring-subtitles" class="md-nav__link">
<span class="md-ellipsis">
Requiring subtitles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#requiring-audio-and-video-languages" class="md-nav__link">
<span class="md-ellipsis">
Requiring audio and video languages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#forced-subtitles-and-output-format" class="md-nav__link">
<span class="md-ellipsis">
Forced subtitles and output format
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#selecting-episodes-and-tracks" class="md-nav__link">
<span class="md-ellipsis">
Selecting episodes and tracks
</span>
</a>
<nav class="md-nav" aria-label="Selecting episodes and tracks">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#wanted-ranges" class="md-nav__link">
<span class="md-ellipsis">
Wanted ranges
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#music-tracks" class="md-nav__link">
<span class="md-ellipsis">
Music tracks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#daily-and-date-based-content" class="md-nav__link">
<span class="md-ellipsis">
Daily and date-based content
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#split-episodes" class="md-nav__link">
<span class="md-ellipsis">
Split episodes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#other-selection-flags" class="md-nav__link">
<span class="md-ellipsis">
Other selection flags
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#including-and-excluding-track-types" class="md-nav__link">
<span class="md-ellipsis">
Including and excluding track types
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#listing-and-dry-runs" class="md-nav__link">
<span class="md-ellipsis">
Listing and dry runs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#output-and-muxing" class="md-nav__link">
<span class="md-ellipsis">
Output and muxing
</span>
</a>
<nav class="md-nav" aria-label="Output and muxing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#output-location-and-folders" class="md-nav__link">
<span class="md-ellipsis">
Output location and folders
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#muxing-behaviour" class="md-nav__link">
<span class="md-ellipsis">
Muxing behaviour
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#after-the-download" class="md-nav__link">
<span class="md-ellipsis">
After the download
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#naming-tags" class="md-nav__link">
<span class="md-ellipsis">
Naming tags
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#proxies" class="md-nav__link">
<span class="md-ellipsis">
Proxies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#performance-and-caching" class="md-nav__link">
<span class="md-ellipsis">
Performance and caching
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#keys-vaults-and-export" class="md-nav__link">
<span class="md-ellipsis">
Keys, vaults, and export
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#metadata-and-tagging" class="md-nav__link">
<span class="md-ellipsis">
Metadata and tagging
</span>
</a>
<nav class="md-nav" aria-label="Metadata and tagging">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#what-each-metadata-provider-supplies" class="md-nav__link">
<span class="md-ellipsis">
What each metadata provider supplies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#episode-ordering" class="md-nav__link">
<span class="md-ellipsis">
Episode ordering
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#configuration-defaults" class="md-nav__link">
<span class="md-ellipsis">
Configuration defaults
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-reference" class="md-nav__link">
<span class="md-ellipsis">
Quick reference
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../cli-reference/" class="md-nav__link">
<span class="md-ellipsis">
CLI Reference
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../drm-and-cdm/" class="md-nav__link">
<span class="md-ellipsis">
DRM & CDM Setup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../proxies-and-vpn/" class="md-nav__link">
<span class="md-ellipsis">
Proxies & VPN
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../vaults/" class="md-nav__link">
<span class="md-ellipsis">
Key Vaults
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../output-and-naming/" class="md-nav__link">
<span class="md-ellipsis">
Output & Naming
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../subtitles/" class="md-nav__link">
<span class="md-ellipsis">
Subtitles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../troubleshooting/" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<div class="md-nav__link md-nav__container">
<a href="../../reference/configuration/" class="md-nav__link ">
<span class="md-ellipsis">
Configuration
</span>
</a>
<label class="md-nav__link " for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Configuration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/configuration/directories/" class="md-nav__link">
<span class="md-ellipsis">
Directories
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/services/" class="md-nav__link">
<span class="md-ellipsis">
Services & Authentication
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/download/" class="md-nav__link">
<span class="md-ellipsis">
Download & Processing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/output/" class="md-nav__link">
<span class="md-ellipsis">
Output & Naming
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/drm/" class="md-nav__link">
<span class="md-ellipsis">
DRM & CDM
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/network/" class="md-nav__link">
<span class="md-ellipsis">
Network & Proxy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/vaults/" class="md-nav__link">
<span class="md-ellipsis">
Key Vaults
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/post-scripts/" class="md-nav__link">
<span class="md-ellipsis">
Post-Scripts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/misc/" class="md-nav__link">
<span class="md-ellipsis">
Other Settings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/configuration/example/" class="md-nav__link">
<span class="md-ellipsis">
Annotated Example
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Developer
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Developer
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../dev/creating-a-service/" class="md-nav__link">
<span class="md-ellipsis">
Creating a Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/service-architecture/" class="md-nav__link">
<span class="md-ellipsis">
Service Architecture
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_3" >
<div class="md-nav__link md-nav__container">
<a href="../../dev/rest-api/" class="md-nav__link ">
<span class="md-ellipsis">
REST API
</span>
</a>
<label class="md-nav__link " for="__nav_5_3" id="__nav_5_3_label" tabindex="0">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5_3">
<span class="md-nav__icon md-icon"></span>
REST API
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../dev/rest-api/quickstart/" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/authentication/" class="md-nav__link">
<span class="md-ellipsis">
Authentication
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/endpoints/" class="md-nav__link">
<span class="md-ellipsis">
Endpoints
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/job-lifecycle/" class="md-nav__link">
<span class="md-ellipsis">
Job Lifecycle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/dashboard/" class="md-nav__link">
<span class="md-ellipsis">
Dashboard
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/remote-sessions/" class="md-nav__link">
<span class="md-ellipsis">
Remote Sessions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../dev/rest-api/errors/" class="md-nav__link">
<span class="md-ellipsis">
Error Responses
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
API Reference
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
API Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../reference/api/service/" class="md-nav__link">
<span class="md-ellipsis">
Service
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/api/config/" class="md-nav__link">
<span class="md-ellipsis">
Config
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/api/tracks/" class="md-nav__link">
<span class="md-ellipsis">
Tracks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/api/titles/" class="md-nav__link">
<span class="md-ellipsis">
Titles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../reference/api/drm/" class="md-nav__link">
<span class="md-ellipsis">
DRM
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#command-shape" class="md-nav__link">
<span class="md-ellipsis">
Command shape
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-download-flow" class="md-nav__link">
<span class="md-ellipsis">
The download flow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#choosing-quality" class="md-nav__link">
<span class="md-ellipsis">
Choosing quality
</span>
</a>
<nav class="md-nav" aria-label="Choosing quality">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#resolution" class="md-nav__link">
<span class="md-ellipsis">
Resolution
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#best-available-and-worst" class="md-nav__link">
<span class="md-ellipsis">
Best-available and worst
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#video-codec-and-colour-range" class="md-nav__link">
<span class="md-ellipsis">
Video codec and colour range
</span>
</a>
<nav class="md-nav" aria-label="Video codec and colour range">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#codec" class="md-nav__link">
<span class="md-ellipsis">
Codec
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#colour-range" class="md-nav__link">
<span class="md-ellipsis">
Colour range
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#bitrate-selection" class="md-nav__link">
<span class="md-ellipsis">
Bitrate selection
</span>
</a>
<nav class="md-nav" aria-label="Bitrate selection">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#real-bitrate-probing" class="md-nav__link">
<span class="md-ellipsis">
Real bitrate probing
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#audio-codec-channels-and-atmos" class="md-nav__link">
<span class="md-ellipsis">
Audio codec, channels, and Atmos
</span>
</a>
<nav class="md-nav" aria-label="Audio codec, channels, and Atmos">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#codec_1" class="md-nav__link">
<span class="md-ellipsis">
Codec
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#channels-and-atmos" class="md-nav__link">
<span class="md-ellipsis">
Channels and Atmos
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#music-quality" class="md-nav__link">
<span class="md-ellipsis">
Music quality
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#languages" class="md-nav__link">
<span class="md-ellipsis">
Languages
</span>
</a>
<nav class="md-nav" aria-label="Languages">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#video-and-audio-language" class="md-nav__link">
<span class="md-ellipsis">
Video and audio language
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#excluding-languages" class="md-nav__link">
<span class="md-ellipsis">
Excluding languages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sort-order" class="md-nav__link">
<span class="md-ellipsis">
Sort order
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#exact-vs-fuzzy-matching" class="md-nav__link">
<span class="md-ellipsis">
Exact vs fuzzy matching
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#subtitles" class="md-nav__link">
<span class="md-ellipsis">
Subtitles
</span>
</a>
<nav class="md-nav" aria-label="Subtitles">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#selecting-subtitle-languages" class="md-nav__link">
<span class="md-ellipsis">
Selecting subtitle languages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#requiring-subtitles" class="md-nav__link">
<span class="md-ellipsis">
Requiring subtitles
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#requiring-audio-and-video-languages" class="md-nav__link">
<span class="md-ellipsis">
Requiring audio and video languages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#forced-subtitles-and-output-format" class="md-nav__link">
<span class="md-ellipsis">
Forced subtitles and output format
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#selecting-episodes-and-tracks" class="md-nav__link">
<span class="md-ellipsis">
Selecting episodes and tracks
</span>
</a>
<nav class="md-nav" aria-label="Selecting episodes and tracks">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#wanted-ranges" class="md-nav__link">
<span class="md-ellipsis">
Wanted ranges
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#music-tracks" class="md-nav__link">
<span class="md-ellipsis">
Music tracks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#daily-and-date-based-content" class="md-nav__link">
<span class="md-ellipsis">
Daily and date-based content
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#split-episodes" class="md-nav__link">
<span class="md-ellipsis">
Split episodes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#other-selection-flags" class="md-nav__link">
<span class="md-ellipsis">
Other selection flags
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#including-and-excluding-track-types" class="md-nav__link">
<span class="md-ellipsis">
Including and excluding track types
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#listing-and-dry-runs" class="md-nav__link">
<span class="md-ellipsis">
Listing and dry runs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#output-and-muxing" class="md-nav__link">
<span class="md-ellipsis">
Output and muxing
</span>
</a>
<nav class="md-nav" aria-label="Output and muxing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#output-location-and-folders" class="md-nav__link">
<span class="md-ellipsis">
Output location and folders
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#muxing-behaviour" class="md-nav__link">
<span class="md-ellipsis">
Muxing behaviour
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#after-the-download" class="md-nav__link">
<span class="md-ellipsis">
After the download
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#naming-tags" class="md-nav__link">
<span class="md-ellipsis">
Naming tags
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#proxies" class="md-nav__link">
<span class="md-ellipsis">
Proxies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#performance-and-caching" class="md-nav__link">
<span class="md-ellipsis">
Performance and caching
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#keys-vaults-and-export" class="md-nav__link">
<span class="md-ellipsis">
Keys, vaults, and export
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#metadata-and-tagging" class="md-nav__link">
<span class="md-ellipsis">
Metadata and tagging
</span>
</a>
<nav class="md-nav" aria-label="Metadata and tagging">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#what-each-metadata-provider-supplies" class="md-nav__link">
<span class="md-ellipsis">
What each metadata provider supplies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#episode-ordering" class="md-nav__link">
<span class="md-ellipsis">
Episode ordering
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#configuration-defaults" class="md-nav__link">
<span class="md-ellipsis">
Configuration defaults
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-reference" class="md-nav__link">
<span class="md-ellipsis">
Quick reference
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="downloading">Downloading<a class="headerlink" href="#downloading" title="Permanent link">&para;</a></h1>
<p><code>unshackle dl</code> 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.</p>
<div class="admonition note">
<p class="admonition-title">Where the full flag list lives</p>
<p>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, use <code>unshackle dl --help</code>. Every flag shown here can also be
given a default in your configuration file. See
<a href="../../getting-started/configuration-file/">Configuration file</a>.</p>
</div>
<h2 id="command-shape">Command shape<a class="headerlink" href="#command-shape" title="Permanent link">&para;</a></h2>
<p>A download is always three layers: the root CLI, the <code>dl</code> command (which is where
unshackle parses all the flags below), and a <strong>service tag</strong> subcommand that carries the
title argument.</p>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span><span class="o">[</span>OPTIONS<span class="o">]</span><span class="w"> </span>SERVICE<span class="w"> </span><span class="o">[</span>SERVICE<span class="w"> </span>ARGUMENTS<span class="o">]</span>
</span></code></pre></div>
<ul>
<li><code>unshackle</code>: the root command.</li>
<li><code>dl</code>: the download command. <strong>unshackle parses all of the options on this page here</strong>,
so they go <em>before</em> the service tag.</li>
<li><code>SERVICE</code>: a service tag such as <code>EXAMPLE1</code>, <code>EXAMPLE2</code>, <code>EXAMPLE3</code>. Service tags are
case-insensitive and honour each service's aliases (for example <code>example+</code> resolves to
its real tag).</li>
<li><code>SERVICE ARGUMENTS</code>: usually a title ID or URL. This positional argument belongs to
the <strong>service</strong>, not to <code>dl</code>, so it comes <em>after</em> the tag.</li>
</ul>
<div class="language-shell highlight"><span class="filename">A minimal download</span><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Flags belong to dl, the title belongs to the service</span><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>-v<span class="w"> </span>H.265<span class="w"> </span>-r<span class="w"> </span>HDR10<span class="w"> </span>--lang<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="s1">'https://www.example.com/...'</span>
</span></code></pre></div>
<div class="admonition tip">
<p class="admonition-title">See what a service accepts</p>
<p>Because each service defines its own positional argument, use
<code>unshackle dl SERVICE --help</code> (for example <code>unshackle dl EXAMPLE --help</code>) to see that
service's own argument and any service-specific options.</p>
</div>
<h2 id="the-download-flow">The download flow<a class="headerlink" href="#the-download-flow" title="Permanent link">&para;</a></h2>
<p>When you start a download, <code>dl</code> moves through the pipeline below. The order tells you
why, for example, <code>--list</code> stops early, and why unshackle fetches the content keys even
with <code>--skip-dl</code>.</p>
<ol>
<li><strong>Setup</strong>: load the DRM CDM, key vaults, proxy providers, cookies, and credentials.</li>
<li><strong>Authenticate</strong>: sign in to the service with your profile's cookies/credentials.</li>
<li><strong>Fetch titles</strong>: retrieve the movie, episode list, or album (cached unless
<code>--no-cache</code>/<code>--reset-cache</code>).</li>
<li><strong>Filter titles</strong>: apply <code>--wanted</code>, <code>--latest-episode</code>, <code>--latest-episodes</code>, or <code>--select-titles</code>.</li>
<li><strong>Get tracks</strong>: parse the manifest into video, audio, subtitle, and chapter tracks.</li>
<li><strong>Select tracks</strong>: narrow each type down using your quality, codec, range, language,
and bitrate flags.</li>
<li><strong>Download</strong>: pull segments for the selected tracks (concurrently per <code>--downloads</code>).</li>
<li><strong>License &amp; decrypt</strong>: get the content keys (vault → CDM), decrypt each track.</li>
<li><strong>Post-process</strong>: extract closed captions, convert subtitles, repack, mux with
<code>mkvmerge</code>, and move the finished file to your downloads directory.</li>
</ol>
<p><code>--list</code> prints the tracks a title exposes and stops before selection. <code>--list-titles</code>
prints every title the service returned and stops before <code>--wanted</code>/<code>--latest-episode</code>/<code>--latest-episodes</code>
filtering. <code>--skip-dl</code> runs the license step but skips the actual segment download.</p>
<h2 id="choosing-quality">Choosing quality<a class="headerlink" href="#choosing-quality" title="Permanent link">&para;</a></h2>
<h3 id="resolution">Resolution<a class="headerlink" href="#resolution" title="Permanent link">&para;</a></h3>
<p><code>-q</code> / <code>--quality</code> takes one or more target resolutions (heights) as a comma-separated
list. Without it, unshackle picks the <strong>best available</strong> resolution.</p>
<div class="language-shell highlight"><span class="filename">Single resolution</span><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Multiple resolutions in one run</span><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">2160</span>,1080,720<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">16:9 canvas matching</p>
<p>Resolution matching is by track <strong>height</strong> first. If no track height matches exactly,
unshackle falls back to a 16:9-canvas match, so <code>-q 1080</code> also selects an
anamorphic <code>1920×804</code> track (computed as <code>int(width × 9 / 16)</code>). unshackle applies the
fallback to each range and codec on its own. A service that crops only its HDR10 tracks
therefore keeps its <code>3840×1920</code> HDR10 track, even when another range has an exact
<code>2160</code> height match.</p>
</div>
<h3 id="best-available-and-worst">Best-available and worst<a class="headerlink" href="#best-available-and-worst" title="Permanent link">&para;</a></h3>
<p>By default a missing requested resolution is an error. Two flags change that:</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Behaviour</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--best-available</code> (<code>--warn-only</code>)</td>
<td>If the requested resolution(s) are not present, continue with the best that <em>is</em> available instead of failing. Also softens missing video/audio/subtitle languages and hybrid fallbacks, and with <code>--all-drm</code> a DRM system that does not license.</td>
</tr>
<tr>
<td><code>--worst</code></td>
<td>Within the specified quality, pick the <strong>lowest</strong> bitrate rendition. <strong>Requires <code>-q/--quality</code>.</strong></td>
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">Never fail on a missing resolution</span><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">2160</span><span class="w"> </span>--best-available<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span></code></pre></div>
<h2 id="video-codec-and-colour-range">Video codec and colour range<a class="headerlink" href="#video-codec-and-colour-range" title="Permanent link">&para;</a></h2>
<h3 id="codec">Codec<a class="headerlink" href="#codec" title="Permanent link">&para;</a></h3>
<p><code>-v</code> / <code>--vcodec</code> selects one or more video codecs. The default is any codec. It accepts
either enum <strong>names</strong> or their <strong>values</strong>, comma-separated.</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>AVC</code></td>
<td><code>H.264</code></td>
</tr>
<tr>
<td><code>HEVC</code></td>
<td><code>H.265</code></td>
</tr>
<tr>
<td><code>VC1</code></td>
<td><code>VC-1</code></td>
</tr>
<tr>
<td><code>VP8</code></td>
<td><code>VP8</code></td>
</tr>
<tr>
<td><code>VP9</code></td>
<td><code>VP9</code></td>
</tr>
<tr>
<td><code>AV1</code></td>
<td><code>AV1</code></td>
</tr>
</tbody>
</table>
<p><code>H264</code> and <code>H265</code> are aliases of <code>AVC</code> and <code>HEVC</code>.</p>
<div class="language-shell highlight"><span class="filename">Either spelling works</span><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-v<span class="w"> </span>HEVC<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-v<span class="w"> </span>H.265<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-v<span class="w"> </span>hevc,avc<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="colour-range">Colour range<a class="headerlink" href="#colour-range" title="Permanent link">&para;</a></h3>
<p><code>-r</code> / <code>--range</code> selects one or more colour ranges. The default is <code>SDR</code>.</p>
<table>
<thead>
<tr>
<th>Range</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>SDR</code></td>
<td>Standard dynamic range (default)</td>
</tr>
<tr>
<td><code>HLG</code></td>
<td>Hybrid Log-Gamma</td>
</tr>
<tr>
<td><code>HDR10</code></td>
<td>HDR10</td>
</tr>
<tr>
<td><code>HDR10P</code></td>
<td>HDR10+</td>
</tr>
<tr>
<td><code>DV</code></td>
<td>Dolby Vision</td>
</tr>
<tr>
<td><code>HYBRID</code></td>
<td>Fetch both an HDR10/HDR10+ base and a DV track, then merge them</td>
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">Grab HDR10 and Dolby Vision in one run</span><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">2160</span><span class="w"> </span>-r<span class="w"> </span>HDR10,DV<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="s1">'...'</span>
</span></code></pre></div>
<div class="admonition warning">
<p class="admonition-title">HYBRID requires dovi_tool</p>
<p><code>-r HYBRID</code> makes a single hybrid track by injecting the Dolby Vision RPU
metadata onto an HDR10/HDR10+ base layer with <strong>dovi_tool</strong>.
It requires the <code>dovi_tool</code> binary, resolved from unshackle's <code>binaries/</code> folder,
the <code>binaries</code> folder of your user data directory, or your <code>PATH</code>. The normal case is a DV track plus an HDR10 or HDR10+ base. With HDR10+
and no DV, unshackle converts the HDR10+ metadata to DV instead, which also needs
<code>hdr10plus_tool</code>. With no DV and no HDR10+, the title fails.
When HDR10+ is present, unshackle prefers it over HDR10 as the base layer.</p>
<p>To keep an HDR10+ deliverable <em>alongside</em> the hybrid, request both ranges:
<code>-r HYBRID,HDR10P</code>. <code>-r HYBRID</code> on its own muxes only the merged hybrid.</p>
</div>
<h2 id="bitrate-selection">Bitrate selection<a class="headerlink" href="#bitrate-selection" title="Permanent link">&para;</a></h2>
<p>By default unshackle keeps the highest-bitrate rendition for each selected
resolution/codec/range/language combination. You can constrain this.</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>-vb</code> / <code>--vbitrate</code></td>
<td>Exact video bitrate in kbps.</td>
</tr>
<tr>
<td><code>-ab</code> / <code>--abitrate</code></td>
<td>Exact audio bitrate in kbps.</td>
</tr>
<tr>
<td><code>-vb-range</code> / <code>--vbitrate-range</code></td>
<td>Video bitrate range in kbps, e.g. <code>6000-7000</code>; picks the highest within it.</td>
</tr>
<tr>
<td><code>-ab-range</code> / <code>--abitrate-range</code></td>
<td>Audio bitrate range in kbps, e.g. <code>128-256</code>.</td>
</tr>
</tbody>
</table>
<div class="admonition warning">
<p class="admonition-title">Exact vs range are mutually exclusive</p>
<p>You cannot combine <code>--vbitrate</code> with <code>--vbitrate-range</code>, and likewise for the audio
pair. Pick one form.</p>
</div>
<h3 id="real-bitrate-probing">Real bitrate probing<a class="headerlink" href="#real-bitrate-probing" title="Permanent link">&para;</a></h3>
<p>Manifest-declared bitrates are sometimes rounded or wrong. Services often advertise a
<strong>peak</strong> or <strong>nominal</strong> bandwidth that is far from the track's real average. This matters
because a track's bitrate drives the track listing, the sort order, <em>and</em> the
<code>--vbitrate</code>/<code>--vbitrate-range</code> selection above. A bogus declared value therefore makes
unshackle pick the wrong track. These flags probe the actual media size to compute a true
bitrate for the top renditions, overriding the manifest value:</p>
<ul>
<li><code>-rvb</code> / <code>--real-video-bitrate</code>: probe real video bitrates (per codec/range).</li>
<li><code>-rab</code> / <code>--real-audio-bitrate</code>: probe real audio bitrates (per codec/channels/
language). Slower than the video variant because there are more renditions to probe.</li>
</ul>
<div class="admonition note">
<p class="admonition-title">Reading the probed numbers</p>
<p>unshackle measures a single-file track (DASH <code>SegmentBase</code>/<code>BaseURL</code>) <strong>exactly</strong>. A
multi-segment track (most HLS) is a <strong>sampled estimate</strong>, normally within a few percent
of the true value. For MPEG-TS HLS the probed figure also reads a few percent <em>above</em>
the demuxed elementary stream, because the segment bytes include container overhead.
That is the real <em>delivered</em> size, not an over-report or a bug.</p>
</div>
<div class="admonition tip">
<p class="admonition-title">Why not every rendition is probed</p>
<p>Probing does not touch every rendition. unshackle probes only the five highest
declared-bitrate renditions of each quality tier, in parallel (video grouped by codec
and range, audio by codec, channels, language, and descriptive flag). It extends a
group downward while a lower unprobed rendition could still outrank a probed one.
This keeps probing fast even when a service exposes dozens of renditions. A track
whose duration unshackle cannot find falls back to <code>ffprobe</code>. A probe failure is
non-fatal: the manifest value stays in place.</p>
</div>
<h2 id="audio-codec-channels-and-atmos">Audio codec, channels, and Atmos<a class="headerlink" href="#audio-codec-channels-and-atmos" title="Permanent link">&para;</a></h2>
<h3 id="codec_1">Codec<a class="headerlink" href="#codec_1" title="Permanent link">&para;</a></h3>
<p><code>-a</code> / <code>--acodec</code> selects one or more audio codecs (comma-separated). The default is any.</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
<th>Codec</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>AAC</code></td>
<td><code>AAC</code></td>
<td>Advanced Audio Coding</td>
</tr>
<tr>
<td><code>AC3</code></td>
<td><code>DD</code></td>
<td>Dolby Digital</td>
</tr>
<tr>
<td><code>EC3</code></td>
<td><code>DD+</code></td>
<td>Dolby Digital Plus</td>
</tr>
<tr>
<td><code>AC4</code></td>
<td><code>AC-4</code></td>
<td>Dolby AC-4</td>
</tr>
<tr>
<td><code>OPUS</code></td>
<td><code>OPUS</code></td>
<td>Opus</td>
</tr>
<tr>
<td><code>OGG</code></td>
<td><code>VORB</code></td>
<td>Vorbis</td>
</tr>
<tr>
<td><code>DTS</code></td>
<td><code>DTS</code></td>
<td>DTS</td>
</tr>
<tr>
<td><code>DTSX</code></td>
<td><code>DTS-X</code></td>
<td>DTS:X Profile 2 (DTS-UHD)</td>
</tr>
<tr>
<td><code>ALAC</code></td>
<td><code>ALAC</code></td>
<td>Apple Lossless</td>
</tr>
<tr>
<td><code>FLAC</code></td>
<td><code>FLAC</code></td>
<td>FLAC</td>
</tr>
</tbody>
</table>
<p>unshackle accepts names, values, and a few aliases: <code>eac3</code> and <code>ddp</code> both give <code>EC3</code>,
and <code>vorbis</code> gives <code>OGG</code>.</p>
<div class="language-shell highlight"><span class="filename">Prefer Dolby Digital Plus, fall back to AAC</span><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>EC3,AAC<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="channels-and-atmos">Channels and Atmos<a class="headerlink" href="#channels-and-atmos" title="Permanent link">&para;</a></h3>
<ul>
<li><code>-c</code> / <code>--channels</code>: desired channel layout, for example <code>5.1</code> or <code>2.0</code>. Matching is by
ceiling, so <code>5.1</code> implicitly matches a <code>6.0</code>-reported layout. An immersive layout such as
<code>5.1.4</code> matches on its total number of channels, so <code>-c 10</code> selects it.</li>
<li><code>-naa</code> / <code>--noatmos</code>: exclude Atmos audio tracks from selection.</li>
</ul>
<div class="language-shell highlight"><span class="filename">5.1 audio, no Atmos</span><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-c<span class="w"> </span><span class="m">5</span>.1<span class="w"> </span>--noatmos<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span></code></pre></div>
<h3 id="music-quality">Music quality<a class="headerlink" href="#music-quality" title="Permanent link">&para;</a></h3>
<p>A music service gives one <code>Audio</code> track for each codec and bitrate it offers for a song.
The audio options above choose between them: <code>-a</code> picks the codec and <code>-ab</code> or <code>-ab-range</code>
picks the bitrate. If you set neither, unshackle takes the best track.</p>
<p><code>-q</code> / <code>--quality</code> is a video height. It has no effect on a music download.</p>
<div class="language-shell highlight"><span class="filename">Take the lossless track</span><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>FLAC<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Take the lossy track at 320 kb/s</span><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-a<span class="w"> </span>AAC<span class="w"> </span>-ab<span class="w"> </span><span class="m">320</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition tip">
<p class="admonition-title">Two FLAC tracks in one release</p>
<p>A service can offer both a CD FLAC and a hi-res FLAC. The two have the same codec, so
the bitrate is what separates them. Use <code>--list</code> to read the bitrates, then give <code>-ab</code>
the one you want.</p>
</div>
<h2 id="languages">Languages<a class="headerlink" href="#languages" title="Permanent link">&para;</a></h2>
<h3 id="video-and-audio-language">Video and audio language<a class="headerlink" href="#video-and-audio-language" title="Permanent link">&para;</a></h3>
<p><code>-l</code> / <code>--lang</code> sets the wanted language(s) for <strong>both video and audio</strong>. The default is
<code>orig</code>, the title's original language.</p>
<div class="language-shell highlight"><span class="filename">Original language plus English</span><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>orig,en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>unshackle changes the special token <code>orig</code> to the title's own original language
everywhere you use it. You can override each track type independently:</p>
<ul>
<li><code>-vl</code> / <code>--v-lang</code>: language for <strong>video only</strong> (overrides <code>-l</code> for video). Useful
when the burned-in video language differs from the audio you want.</li>
<li><code>-al</code> / <code>--a-lang</code>: language for <strong>audio only</strong> (overrides <code>-l</code> for audio).</li>
</ul>
<div class="language-shell highlight"><span class="filename">English audio over the original video</span><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-al<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="excluding-languages">Excluding languages<a class="headerlink" href="#excluding-languages" title="Permanent link">&para;</a></h3>
<p>Put a <code>-</code> in front of a language to remove it from the selection. This works on <code>-l</code>,
<code>-vl</code>, <code>-al</code>, <code>-sl</code>, and <code>-fsl</code>, in the same way as it works on <code>-w</code> / <code>--wanted</code>.</p>
<div class="language-shell highlight"><span class="filename">Every subtitle language except Spanish</span><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>all,-es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>unshackle subtracts the exclusions from the languages the flag would otherwise select,
and the order of the values does not matter. If you give only exclusions, the flag keeps its own
default: <code>-sl -es</code> is the same as <code>-sl all,-es</code>, and <code>-l -es</code> is the same as <code>-l orig,-es</code>.</p>
<div class="language-shell highlight"><span class="filename">Only exclusions</span><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="c1"># every subtitle language except Spanish and French</span>
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>-es,-fr<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a>
</span><span id="__span-15-4"><a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="c1"># the original audio language, unless it is Spanish</span>
</span><span id="__span-15-5"><a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>-es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p><code>-vl</code> and <code>-al</code> have no default of their own: they cascade to <code>-l</code>. An override that names
a language replaces <code>-l</code> for that track type, exclusions included. An override that gives
only exclusions adds them to the ones from <code>-l</code>.</p>
<div class="language-shell highlight"><span class="filename">Cascade</span><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="c1"># video keeps the Japanese track; only the audio drops Spanish</span>
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>en,-es<span class="w"> </span>-vl<span class="w"> </span>ja<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Rules for exclusion tokens</p>
<ul>
<li><code>orig</code> becomes the title's own original language, so <code>-sl -orig</code> drops the
subtitles in that language.</li>
<li><code>--exact-lang</code> applies to exclusions with the same matching rules as selection:
<code>-es</code> removes exactly the tracks that <code>es</code> would select. Without it, <code>-es</code> also
removes <code>es-419</code> and <code>es-ES</code>.</li>
<li>Tracks with no language tag are never excluded.</li>
<li>unshackle rejects <code>-all</code>. Name the languages you do not want instead.</li>
<li>The comma form is the documented style. <code>-sl -es</code> also works, but a shell can read
a lone <code>-es</code> as another option.</li>
</ul>
</div>
<h3 id="sort-order">Sort order<a class="headerlink" href="#sort-order" title="Permanent link">&para;</a></h3>
<p><code>-l</code> and <code>-sl</code> <strong>select</strong> languages: naming some removes the rest. To keep every language
but decide which ones come first, set a priority list in your configuration file:</p>
<div class="language-yaml highlight"><span class="filename">unshackle.yaml</span><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="nt">audio</span><span class="p">:</span>
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="w"> </span><span class="nt">language_priority</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">orig</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">en</span><span class="p p-Indicator">]</span>
</span><span id="__span-17-3"><a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a><span class="nt">subtitle</span><span class="p">:</span>
</span><span id="__span-17-4"><a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a><span class="w"> </span><span class="nt">group_by</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">language</span>
</span><span id="__span-17-5"><a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a><span class="w"> </span><span class="nt">language_priority</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">en</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">es</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">fr</span><span class="p p-Indicator">]</span>
</span></code></pre></div>
<p>Subtitles then start with English, Spanish, and French. The languages you leave out follow
alphabetically, after the title's original language. unshackle removes nothing. Audio
works the same way, but the languages you leave out keep their bitrate and codec order instead of an
alphabetical one.</p>
<p>See <a href="../../reference/configuration/download/#subtitle"><code>subtitle.language_priority</code></a> for the details.</p>
<h3 id="exact-vs-fuzzy-matching">Exact vs fuzzy matching<a class="headerlink" href="#exact-vs-fuzzy-matching" title="Permanent link">&para;</a></h3>
<p>By default language matching is fuzzy: <code>-l en</code> also accepts <code>en-US</code>, <code>en-GB</code>, and the
other regional forms (up to a small distance). Pass <code>--exact-lang</code> when only an exact
match is acceptable: with it, <code>-l es-419</code> selects only <code>es-419</code>, not <code>es-ES</code>.</p>
<div class="admonition tip">
<p class="admonition-title">The <code>all</code> and <code>best</code> tokens</p>
<p>For audio, the tokens <code>all</code> and <code>best</code> bypass the usual one-track-per-language pick
and instead select the best track for <strong>each</strong> language present. For subtitles, <code>all</code>
keeps every subtitle language.</p>
</div>
<h2 id="subtitles">Subtitles<a class="headerlink" href="#subtitles" title="Permanent link">&para;</a></h2>
<h3 id="selecting-subtitle-languages">Selecting subtitle languages<a class="headerlink" href="#selecting-subtitle-languages" title="Permanent link">&para;</a></h3>
<p><code>-sl</code> / <code>--s-lang</code> sets the wanted subtitle language(s). The default is <code>all</code>, so
unshackle downloads every available subtitle language.</p>
<div class="language-shell highlight"><span class="filename">Only English and Spanish subtitles</span><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>en,es<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>To keep the default and drop one language, use the <code>-</code> prefix described in
<a href="#excluding-languages">Excluding languages</a>. <code>-sl all,-es</code> keeps every subtitle language
except Spanish, forced Spanish subtitles included.</p>
<h3 id="requiring-subtitles">Requiring subtitles<a class="headerlink" href="#requiring-subtitles" title="Permanent link">&para;</a></h3>
<p><code>--require-subs</code> takes a list of languages that <strong>must</strong> exist. If any is missing, the
title fails, even under <code>--best-available</code> / <code>--warn-only</code>. Use it when a download is only
worth keeping if a specific subtitle track is present.</p>
<p>It gates the title. It does not select tracks: <code>--s-lang</code> still decides what to keep, and
it defaults to <code>all</code>:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="c1"># every subtitle language, but only if English is one of them</span>
</span><span id="__span-19-2"><a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--require-subs<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span><span id="__span-19-3"><a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a>
</span><span id="__span-19-4"><a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="c1"># English, Korean and Japanese only, and only if English is present</span>
</span><span id="__span-19-5"><a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-sl<span class="w"> </span>en,ko,ja<span class="w"> </span>--require-subs<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span></code></pre></div>
<h3 id="requiring-audio-and-video-languages">Requiring audio and video languages<a class="headerlink" href="#requiring-audio-and-video-languages" title="Permanent link">&para;</a></h3>
<p><code>--require-audio</code> and <code>--require-video</code> take a list of languages that <strong>must</strong> exist. If
one is missing, the title fails, even under <code>--best-available</code> / <code>--warn-only</code>. Like
<code>--require-subs</code>, they gate the title without selecting tracks: <code>-l</code> / <code>-al</code> / <code>-vl</code> still
decide what unshackle downloads.</p>
<p>This matters most with <code>-l best</code> or <code>-l all</code>, which accept whatever the service offers and
so never report a missing language on their own:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="c1"># every audio language except French, but only if English is one of them</span>
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>best,-fr<span class="w"> </span>--require-audio<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a>
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="c1"># English is required, French is optional</span>
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-l<span class="w"> </span>en,fr<span class="w"> </span>--require-audio<span class="w"> </span>en<span class="w"> </span>--warn-only<span class="w"> </span>EXAMPLE<span class="w"> </span>0ABC123
</span></code></pre></div>
<p>The check runs against the full track list, before any language selection or exclusion.
<code>orig</code> resolves to the title language, and <code>--exact-lang</code> applies. Audio carried inside the
video track counts. <code>--no-audio</code> and <code>--no-video</code> drop the matching requirement.</p>
<h3 id="forced-subtitles-and-output-format">Forced subtitles and output format<a class="headerlink" href="#forced-subtitles-and-output-format" title="Permanent link">&para;</a></h3>
<ul>
<li><code>-fs</code> / <code>--forced-subs</code>: include forced subtitle tracks (signs/foreign dialogue).
Without this flag, unshackle drops forced subtitle tracks from the selection.</li>
<li><code>-fsl</code> / <code>--forced-s-lang</code>: keep forced subtitles only in these languages (implies
<code>-fs</code>). Works independently of <code>--s-lang</code>, so <code>-sl all -fsl en</code> grabs every full
subtitle but only the English forced track. It accepts exclusions too: <code>-fsl all,-es</code>
keeps every forced subtitle except the Spanish one, and <code>-fsl -es</code> means the same.</li>
<li><code>--sub-format</code>: set the output subtitle format, converting only when necessary.
Accepts codec names/values and common aliases (<code>srt</code>, <code>vtt</code>, <code>ass</code>, <code>ssa</code>, <code>ttml</code>,
and the other codec aliases), or the literal <code>original</code> to keep the source format.</li>
</ul>
<table>
<thead>
<tr>
<th>Value</th>
<th>Format</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>SRT</code> / <code>srt</code></td>
<td>SubRip</td>
</tr>
<tr>
<td><code>VTT</code> / <code>vtt</code></td>
<td>WebVTT</td>
</tr>
<tr>
<td><code>ASS</code> / <code>ass</code></td>
<td>Advanced SubStation Alpha</td>
</tr>
<tr>
<td><code>SSA</code> / <code>ssa</code></td>
<td>SubStation Alpha</td>
</tr>
<tr>
<td><code>TTML</code> / <code>ttml</code></td>
<td>Timed Text Markup</td>
</tr>
<tr>
<td><code>original</code></td>
<td>Keep the source format, no conversion</td>
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">Convert subtitles to SRT</span><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--sub-format<span class="w"> </span>srt<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">SDH stripping happens by default</p>
<p>When a subtitle track carries the SDH flag (for the deaf/hard-of-hearing) and there
is no plain same-language subtitle, unshackle makes a stripped, non-SDH track
automatically. The <code>subtitle.strip_sdh</code> config option controls this behaviour
(default on).</p>
</div>
<h2 id="selecting-episodes-and-tracks">Selecting episodes and tracks<a class="headerlink" href="#selecting-episodes-and-tracks" title="Permanent link">&para;</a></h2>
<p>For series, several flags control which episodes unshackle downloads. The same flags
select the tracks of a music release. By default, unshackle downloads <strong>all</strong> episodes and
<strong>all</strong> tracks.</p>
<h3 id="wanted-ranges">Wanted ranges<a class="headerlink" href="#wanted-ranges" title="Permanent link">&para;</a></h3>
<p><code>-w</code> / <code>--wanted</code> accepts season and episode ranges, comma-separated. Prefix a token
with <code>-</code> to exclude it. For a music release, the same option takes track numbers. Read
<a href="#music-tracks">music tracks</a> below.</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:5"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Whole seasons</label><label for="__tabbed_1_2">Specific episodes</label><label for="__tabbed_1_3">Exclusions</label><label for="__tabbed_1_4">Split episodes</label><label for="__tabbed_1_5">Air dates</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01-S03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-22-3"><a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01,S03,S05<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01-S01E05<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01-S02E03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="c1"># Seasons 1 through 5, but not season 3</span>
</span><span id="__span-24-2"><a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01-S05,-S03<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="c1"># Part 2 of episode 1 only</span>
</span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01.2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-25-3"><a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a>
</span><span id="__span-25-4"><a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="c1"># Parts 1 through 3 of episode 1</span>
</span><span id="__span-25-5"><a id="__codelineno-25-5" name="__codelineno-25-5" href="#__codelineno-25-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01E01.1-S01E01.3<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-25-6"><a id="__codelineno-25-6" name="__codelineno-25-6" href="#__codelineno-25-6"></a>
</span><span id="__span-25-7"><a id="__codelineno-25-7" name="__codelineno-25-7" href="#__codelineno-25-7"></a><span class="c1"># All of season 1 except episode 1 part 2</span>
</span><span id="__span-25-8"><a id="__codelineno-25-8" name="__codelineno-25-8" href="#__codelineno-25-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01,-S01E01.2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="c1"># One day</span>
</span><span id="__span-26-2"><a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-11<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-26-3"><a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a>
</span><span id="__span-26-4"><a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="c1"># A range of days, colon separated</span>
</span><span id="__span-26-5"><a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-01:2026-08-31<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-26-6"><a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a>
</span><span id="__span-26-7"><a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a><span class="c1"># August, but not the 15th</span>
</span><span id="__span-26-8"><a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">2026</span>-08-01:2026-08-31,-2026-08-15<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
</div>
</div>
<h3 id="music-tracks">Music tracks<a class="headerlink" href="#music-tracks" title="Permanent link">&para;</a></h3>
<p><code>-w</code> selects the tracks of an album, EP, single, or playlist. Give a track by its number.
A release with more than one disc uses the <code>{disc}x{track}</code> form. A number on its own is a
track on disc 1, which is the number the track list shows for a single-disc release.</p>
<div class="tabbed-set tabbed-alternate" data-tabs="2:3"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Tracks</label><label for="__tabbed_2_2">More than one disc</label><label for="__tabbed_2_3">Exclusions</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="c1"># Track 3</span>
</span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">3</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a>
</span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a><span class="c1"># Tracks 1 through 5</span>
</span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>-5<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-27-6"><a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a>
</span><span id="__span-27-7"><a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a><span class="c1"># Tracks 1, 3 and 7</span>
</span><span id="__span-27-8"><a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>,3,7<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="c1"># Disc 2, track 3</span>
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>2x3<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-28-3"><a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a>
</span><span id="__span-28-4"><a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a><span class="c1"># Disc 2, tracks 1 through 4</span>
</span><span id="__span-28-5"><a id="__codelineno-28-5" name="__codelineno-28-5" href="#__codelineno-28-5"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>2x1-2x4<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-28-6"><a id="__codelineno-28-6" name="__codelineno-28-6" href="#__codelineno-28-6"></a>
</span><span id="__span-28-7"><a id="__codelineno-28-7" name="__codelineno-28-7" href="#__codelineno-28-7"></a><span class="c1"># Disc 1 track 3, through disc 2 track 2</span>
</span><span id="__span-28-8"><a id="__codelineno-28-8" name="__codelineno-28-8" href="#__codelineno-28-8"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>1x3-2x2<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
<div class="tabbed-block">
<div class="language-shell highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="c1"># Tracks 1 through 8, but not track 4</span>
</span><span id="__span-29-2"><a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span><span class="m">1</span>-8,-4<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
</div>
</div>
</div>
<div class="admonition tip">
<p class="admonition-title">Read the track list first</p>
<p><code>--list-titles</code> prints the release with its disc and track numbers, so you can see
which numbers to give <code>-w</code>.</p>
</div>
<h3 id="daily-and-date-based-content">Daily and date-based content<a class="headerlink" href="#daily-and-date-based-content" title="Permanent link">&para;</a></h3>
<p>Talk shows, news and sports have no official episode numbering, so unshackle names them
by air date. unshackle writes an episode that carries an air date as <code>Show.YYYY.MM.DD</code>
instead of <code>SxxExx</code>, the <code>{date}</code> token holds the ISO date, and the season folder becomes
the year.</p>
<p>A service that only carries this kind of title sets <code>DAILY = True</code> on its class, and a
service can set <code>air_date</code> on each episode itself. Add <code>--daily</code> to mark any other title
as date-based:</p>
<div class="language-shell highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--daily<span class="w"> </span>--tvdb<span class="w"> </span><span class="m">73871</span><span class="w"> </span>--enrich<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>With <code>--enrich</code> and a TVDB ID, <code>--daily</code> fills in the air date of every episode that has
none. An air date the service already set is kept. unshackle skips dates before 1970 and
dates in the future, because TVDB carries placeholder schedule dates for episodes that
have not aired. Without <code>--enrich</code> unshackle has no source to fill from, and says so.</p>
<p>A dated episode answers to its air date in <code>-w</code>, as well as to its <code>SxxExx</code> token. A date
token is a plain ISO date (<code>2026-08-11</code>). A date range uses a colon (<code>2026-08-01:2026-08-31</code>),
because the dashes in a date are part of the date. A range cannot span more than 1000 days.
You can mix date tokens and <code>SxxExx</code> tokens in one <code>-w</code>.</p>
<h3 id="split-episodes">Split episodes<a class="headerlink" href="#split-episodes" title="Permanent link">&para;</a></h3>
<p>A few services split one episode into several separately playable videos. Where a service
reports that, add <code>.N</code> after the episode to pick one part.</p>
<table>
<thead>
<tr>
<th>Token</th>
<th>Selects</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>S01E01</code></td>
<td>All parts of episode 1.</td>
</tr>
<tr>
<td><code>S01E01.2</code></td>
<td>Part 2 of episode 1, and nothing else.</td>
</tr>
<tr>
<td><code>S01E01.1-S01E01.3</code></td>
<td>Parts 1 to 3 of episode 1.</td>
</tr>
<tr>
<td><code>S01,-S01E01.2</code></td>
<td>All of season 1 except episode 1 part 2. Parts 1 and 3 are kept.</td>
</tr>
</tbody>
</table>
<p>A season token such as <code>S01</code> covers every episode and every part, so you only need <code>.N</code>
when you want a part on its own.</p>
<div class="admonition warning">
<p class="admonition-title">A part range stays inside one episode</p>
<p><code>S01E01.1-S01E01.3</code> is valid. unshackle rejects <code>S01E01.1-S01E02.3</code>, because the
parser cannot know how many parts episode 1 has and so cannot work out where the range
ends. To span episodes, write the parts you want as separate tokens:
<code>-w S01E01.2,S01E02.1</code>.</p>
</div>
<div class="admonition note">
<p class="admonition-title">A part of an unsplit episode selects nothing</p>
<p><code>-w S01E02.2</code> on an episode that was never split is deliberately empty: it tells you
the episode has no parts, rather than quietly handing you the whole episode. Use
<code>--list-titles</code> to see which episodes carry parts.</p>
</div>
<h3 id="other-selection-flags">Other selection flags<a class="headerlink" href="#other-selection-flags" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Behaviour</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--select-titles</code></td>
<td>Interactively pick episodes of a series, or films when a title has more than one. <strong>Cannot combine with <code>-w</code>.</strong></td>
</tr>
<tr>
<td><code>--latest-episode</code></td>
<td>Download only the single most recent episode.</td>
</tr>
<tr>
<td><code>--latest-episodes N</code></td>
<td>Download only the N most recent episodes. The newest episodes can come from more than one season. A <a href="#split-episodes">split episode</a> counts as one episode, and all its parts download.</td>
</tr>
<tr>
<td><code>--list-titles</code></td>
<td>List every title the service returned, then stop. <code>-w</code>, <code>--latest-episode</code> and <code>--latest-episodes</code> are not applied to this listing.</td>
</tr>
</tbody>
</table>
<p>When <code>--latest-episode</code> or <code>--latest-episodes</code> is set, <code>-w</code> has no effect.</p>
<div class="language-shell highlight"><span class="filename">Grab just the newest episode</span><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--latest-episode<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Grab the three newest episodes</span><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--latest-episodes<span class="w"> </span><span class="m">3</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h2 id="including-and-excluding-track-types">Including and excluding track types<a class="headerlink" href="#including-and-excluding-track-types" title="Permanent link">&para;</a></h2>
<p>You can restrict a download to certain track categories, either positively (only these)
or negatively (everything but these).</p>
<p><strong>Only these types</strong> (<code>*-only</code> flags):</p>
<ul>
<li><code>-V</code> / <code>--video-only</code></li>
<li><code>-A</code> / <code>--audio-only</code></li>
<li><code>-S</code> / <code>--subs-only</code></li>
<li><code>-C</code> / <code>--chapters-only</code></li>
</ul>
<p><strong>Skip these types</strong> (<code>no-*</code> flags):</p>
<ul>
<li><code>-nv</code> / <code>--no-video</code></li>
<li><code>-na</code> / <code>--no-audio</code></li>
<li><code>-ns</code> / <code>--no-subs</code></li>
<li><code>-nc</code> / <code>--no-chapters</code></li>
<li><code>-nt</code> / <code>--no-attachments</code> (cover art, subtitle fonts, and files the service attaches)</li>
</ul>
<p>Additional track-type flags:</p>
<ul>
<li><code>-ad</code> / <code>--audio-description</code>: include descriptive (audio-description) tracks, which
unshackle drops by default.</li>
<li><code>--skip-subtitle-errors</code>: if a subtitle fails to download, skip it and continue rather
than aborting the whole title. Video and audio failures remain fatal.</li>
</ul>
<div class="language-shell highlight"><span class="filename">Subtitles only</span><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-S<span class="w"> </span>-sl<span class="w"> </span>en<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Everything except chapters</span><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-nc<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>You can combine an <code>*-only</code> flag with <code>no-*</code> flags to fine-tune: <code>*-only</code> chooses the
starting set of categories, then <code>no-*</code> subtracts from it. Attachments (for example fonts)
are always kept.</p>
</div>
<h2 id="listing-and-dry-runs">Listing and dry runs<a class="headerlink" href="#listing-and-dry-runs" title="Permanent link">&para;</a></h2>
<p>Before committing to a long download, inspect what unshackle <em>would</em> do:</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Effect</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--list</code></td>
<td>List the tracks the service exposes for each title, then stop. No selection, no download.</td>
</tr>
<tr>
<td><code>--list-titles</code></td>
<td>List every title the service returned, then stop. <code>-w</code>, <code>--latest-episode</code> and <code>--latest-episodes</code> are not applied to this listing.</td>
</tr>
<tr>
<td><code>--skip-dl</code></td>
<td>Skip downloading but still acquire the decryption keys.</td>
</tr>
<tr>
<td><code>--all-drm</code></td>
<td>License each track with both Widevine and PlayReady. See <a href="../drm-and-cdm/#widevine-and-playready-on-the-same-title">Widevine and PlayReady on the same title</a>.</td>
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">See the track selection without downloading</span><pre><span></span><code><span id="__span-35-1"><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-q<span class="w"> </span><span class="m">1080</span><span class="w"> </span>-v<span class="w"> </span>H.265<span class="w"> </span>-r<span class="w"> </span>HDR10<span class="w"> </span>--list<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h2 id="output-and-muxing">Output and muxing<a class="headerlink" href="#output-and-muxing" title="Permanent link">&para;</a></h2>
<h3 id="output-location-and-folders">Output location and folders<a class="headerlink" href="#output-location-and-folders" title="Permanent link">&para;</a></h3>
<ul>
<li><code>-o</code> / <code>--output</code>: override the output directory for this run (otherwise unshackle
uses the configured downloads directory).</li>
<li><code>--no-folder</code>: do not make a per-show folder for TV downloads.</li>
<li><code>--no-source</code>: remove the service source tag from the filename and path.</li>
</ul>
<div class="language-shell highlight"><span class="filename">Send this download somewhere specific</span><pre><span></span><code><span id="__span-36-1"><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-o<span class="w"> </span>~/Videos/incoming<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="muxing-behaviour">Muxing behaviour<a class="headerlink" href="#muxing-behaviour" title="Permanent link">&para;</a></h3>
<p>By default, <code>mkvmerge</code> muxes the tracks of a movie or an episode into a single Matroska
(<code>.mkv</code>) file. These flags change how unshackle assembles the output:</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Behaviour</th>
<th>Default source</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--no-mux</code></td>
<td>Do not mux; keep the individual track files.</td>
<td>-</td>
</tr>
<tr>
<td><code>--split-audio</code></td>
<td>Write a separate output file per audio codec instead of merging all audio.</td>
<td>config <code>muxing.merge_audio</code> (on)</td>
</tr>
<tr>
<td><code>--merge-video</code></td>
<td>Mux video tracks that share a height, range, and codec into one file, so only language varies inside a file.</td>
<td>config <code>muxing.merge_video</code> (off)</td>
</tr>
</tbody>
</table>
<div class="admonition note">
<p class="admonition-title">Music is never muxed</p>
<p>A song skips the muxer. unshackle keeps the container that the service
delivered, such as <code>.flac</code>, <code>.m4a</code>, or <code>.mp3</code>, and writes the metadata into that file.
Read <a href="../output-and-naming/#music-output-files">Music output files</a>.</p>
</div>
<h3 id="after-the-download">After the download<a class="headerlink" href="#after-the-download" title="Permanent link">&para;</a></h3>
<p><code>--postscript "&lt;command&gt;"</code> runs your own command once per output file, with unshackle's
metadata substituted into <code>{variable}</code> placeholders. It is repeatable, and it replaces the
<code>post_scripts</code> config for that run. No <code>success</code> post-script operates under <code>--no-mux</code>, because
that run writes no muxed output. A <code>failure</code> post-script still operates if the download fails.</p>
<div class="language-shell highlight"><span class="filename">Hand each finished file to an uploader</span><pre><span></span><code><span id="__span-37-1"><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--postscript<span class="w"> </span><span class="s2">"python /opt/upload.py {filepath} --service={service}"</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p><code>--no-postscript</code> operates the run with no post-script at all. It silences the <code>post_scripts</code>
config and <code>--postscript</code> together, for every event and mode.</p>
<div class="language-shell highlight"><span class="filename">Skip the uploader for one run</span><pre><span></span><code><span id="__span-38-1"><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--no-postscript<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>For post-scripts that continue across runs, for the <code>season</code> and <code>run</code> modes, for <code>failure</code>
post-scripts and for the full variable list, see
<a href="../../reference/configuration/post-scripts/">Post-scripts</a>.</p>
<h3 id="naming-tags">Naming tags<a class="headerlink" href="#naming-tags" title="Permanent link">&para;</a></h3>
<ul>
<li><code>--tag</code>: set the release group tag (overrides the configured tag).</li>
<li><code>--repack</code>: add a <code>REPACK</code> tag to the output filename.</li>
</ul>
<div class="language-shell highlight"><span class="filename">Custom group tag and a REPACK label</span><pre><span></span><code><span id="__span-39-1"><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--tag<span class="w"> </span>MYGRP<span class="w"> </span>--repack<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h2 id="proxies">Proxies<a class="headerlink" href="#proxies" title="Permanent link">&para;</a></h2>
<p><code>--proxy</code> accepts a full proxy URI, a country or location code (resolved through your
configured proxy providers), or a <code>provider:region</code> form. See
<a href="../proxies-and-vpn/#how-proxy-resolution-works">Proxies &amp; VPN</a> for the exact grammar.</p>
<div class="language-shell highlight"><span class="filename">Proxy forms</span><pre><span></span><code><span id="__span-40-1"><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>us<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-40-2"><a id="__codelineno-40-2" name="__codelineno-40-2" href="#__codelineno-40-2"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>nordvpn:ca<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-40-3"><a id="__codelineno-40-3" name="__codelineno-40-3" href="#__codelineno-40-3"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span>controld:yul<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span><span id="__span-40-4"><a id="__codelineno-40-4" name="__codelineno-40-4" href="#__codelineno-40-4"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--proxy<span class="w"> </span><span class="s1">'http://user:pass@host:8080'</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>Three related flags:</p>
<ul>
<li><code>--no-proxy</code>: force-disable all proxy use for this run.</li>
<li><code>--no-proxy-download</code>: bypass the proxy for <strong>all downloads</strong>. The manifest,
license, and authentication requests still go through the proxy. This is useful when you
need the proxy only to satisfy geo-checks, not to move the bulk of the data.</li>
<li><code>--proxy-download</code>: use a different proxy for <strong>all downloads</strong>. The manifest,
license, and authentication requests still go through <code>--proxy</code>. Takes the same forms
as <code>--proxy</code>.</li>
</ul>
<h2 id="performance-and-caching">Performance and caching<a class="headerlink" href="#performance-and-caching" title="Permanent link">&para;</a></h2>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--workers N</code></td>
<td>Threads used per track for segment downloads. Default depends on the downloader.</td>
</tr>
<tr>
<td><code>--adaptive-workers</code></td>
<td>Opt-in: start the per-track worker count at <code>--workers</code>, reduce it when the CDN returns errors, then raise it again while the extra workers add measured throughput. The count never goes above <code>--workers</code>. Off by default (fixed worker count).</td>
</tr>
<tr>
<td><code>--download-processes N</code></td>
<td>Opt-in: split a large segment batch across <code>N</code> download processes, each with its own worker pool. A single process tops out around 1.3 Gb/s (Python interpreter limit); <code>2</code> reaches 2.5GbE line rate on fast CDNs. Only engages for batches of 24+ segments. Ignored while <code>--speed-limit</code> (or serve's <code>global_speed_limit</code>) is set: the cap is one shared budget, which extra processes cannot share, so the download stays in a single process. Also ignored when the service HTTP session carries state a child process cannot rebuild, such as a custom TLS adapter. The download stays in a single process instead of running with the wrong settings. Default <code>1</code>.</td>
</tr>
<tr>
<td><code>--continue-downloads</code></td>
<td>Opt-in: keep completed segment files when a download fails so the next run resumes instead of restarting from zero. One-off enable of the <a href="../../reference/configuration/download/#continue_downloads"><code>continue_downloads</code></a> config option, which documents what can and cannot resume.</td>
</tr>
<tr>
<td><code>--downloads N</code></td>
<td>Number of tracks downloaded concurrently. Default <code>1</code>.</td>
</tr>
<tr>
<td><code>--slow [MIN-MAX]</code></td>
<td>Add a delay between titles to look more like a real device. <code>--slow</code> alone means 60-120s; <code>--slow 20-40</code> sets a custom range. Minimum 20s.</td>
</tr>
<tr>
<td><code>--no-cache</code></td>
<td>Bypass the title cache for this download.</td>
</tr>
<tr>
<td><code>--reset-cache</code></td>
<td>Clear the title cache before fetching.</td>
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">Two tracks at a time, eight threads each</span><pre><span></span><code><span id="__span-41-1"><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--downloads<span class="w"> </span><span class="m">2</span><span class="w"> </span>--workers<span class="w"> </span><span class="m">8</span><span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Space out a season download</span><pre><span></span><code><span id="__span-42-1"><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>-w<span class="w"> </span>S01<span class="w"> </span>--slow<span class="w"> </span><span class="m">30</span>-60<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h2 id="keys-vaults-and-export">Keys, vaults, and export<a class="headerlink" href="#keys-vaults-and-export" title="Permanent link">&para;</a></h2>
<p>By default, unshackle checks your <strong>key vaults</strong> first and only asks a <strong>CDM</strong> to license
a content key when the vault misses. You can force one side or the other:</p>
<ul>
<li><code>--cdm-only</code>: only use the CDM (skip vaults). Over a <code>server_cdm</code> remote session the flag does not reach the server, whose vault shortcut still runs; it only skips the client's decode check on a server key.</li>
<li><code>--cdm &lt;name&gt;</code>: use the named CDM device for this run, ignoring the <code>cdm</code> config mapping (including its quality and Widevine/PlayReady sub-entries). Over <code>--remote</code>, that device licenses the remote session, not the server CDM.</li>
<li><code>--vaults-only</code>: only use key vaults and never license through the CDM. A missing
content key fails.</li>
</ul>
<div class="language-shell highlight"><span class="filename">Fetch keys only, no download</span><pre><span></span><code><span id="__span-43-1"><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p><code>--export</code> writes a <code>mediaexport</code> JSON file into the configured exports directory. It holds
the manifest, the DRM init data, the content keys, the KIDs of each track and the title
metadata for each title. <code>unshackle import</code> reads it to reconstruct a download later, and gives
each track only the content keys for its KIDs. The importer also reads the
older unshackle <code>version: 2</code> files and unidl's own export files.</p>
<div class="language-shell highlight"><span class="filename">Export track info and keys</span><pre><span></span><code><span id="__span-44-1"><a id="__codelineno-44-1" name="__codelineno-44-1" href="#__codelineno-44-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>--export<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>Add <code>--all-drm</code> to get the content keys of each DRM system the title offers. The export then
holds the DRM init data of both. A Key Vault that has a content key stops the challenge for
its KID; add <code>--cdm-only</code> to send a challenge for each DRM system.</p>
<div class="language-shell highlight"><span class="filename">License with Widevine and PlayReady, no download</span><pre><span></span><code><span id="__span-45-1"><a id="__codelineno-45-1" name="__codelineno-45-1" href="#__codelineno-45-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--skip-dl<span class="w"> </span>--all-drm<span class="w"> </span>--export<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>The file name tells what the file holds, in the form
<code>{title}.{scope}.{resolutions}.{codecs}.{ranges}.{manifests}.{audio}-{SERVICE}.json</code>:</p>
<table>
<thead>
<tr>
<th>Export</th>
<th>File name</th>
</tr>
</thead>
<tbody>
<tr>
<td>A movie</td>
<td><code>Example.Movie.2024.1080p.h264.sdr.hls.aac2.0-EXAMPLE.json</code></td>
</tr>
<tr>
<td>A whole season</td>
<td><code>Example.Show.S01.2160p.h265.sdr.hdr10.dash.dd5.1-EXAMPLE.json</code></td>
</tr>
<tr>
<td>Episodes 5 to 9 and 12</td>
<td><code>Example.Show.S01E05-E09.S01E12.1080p.h264.sdr.dash.aac2.0-EXAMPLE.json</code></td>
</tr>
</tbody>
</table>
<ul>
<li>A dot separates each part and each word of the title. The name has no spaces or
underscores. It does not follow your <code>output_template</code>: a template with spaces does not
change the export name.</li>
<li>The scope is <code>S01</code> only when the file holds every episode the service lists for that season.
Otherwise it names each run of episodes. Whole seasons in a row become <code>S01-S03</code>. After three
parts, <code>+N</code> counts the parts left out. A movie has no scope.</li>
<li>The quality parts come from the video and audio tracks selected for the titles in the file.
Each value shows once.</li>
<li>unshackle renames the file after each write, so the name always matches what the file holds.
When a run stops early, the file is complete for the titles it holds.</li>
<li>When another file already has the name, unshackle adds <code>-2</code>, <code>-3</code>, and so on. It never
writes over another export.</li>
</ul>
<p>The run logs the file name at the first write, the track and content key counts for each title, and
at the end the path and the total counts.</p>
<p>The export holds a content key for each track your flags selected and no others. To make a
file another person can use, select generously: for example <code>-a AAC,EC3</code> and every language
you want them to have. An import can only pick tracks whose key is in the file. A track
that another tool exported as a direct file URL is added next to the manifest's own tracks.
An export with no manifest, for example a unidl export of whole media files, gets all of its
tracks from those URLs. If such an export does not give the title a language, <code>orig</code> has no
value: select the languages with <code>-l</code> and <code>-vl</code>.</p>
<p>An import uses only the content keys in the file and in your vaults. It never gets a licence
from a CDM. When a track needs a content key that neither has, the import stops and names the
KID. To fix this, export the title again with that track selected.</p>
<div class="admonition warning">
<p class="admonition-title">The export file is a secret</p>
<p>It holds the content keys and usually a signed manifest URL. Hand it over on purpose,
not by accident.</p>
</div>
<p>The <a href="https://github.com/unshackle-dl/mediaexport">mediaexport</a> package specifies the
<code>mediaexport</code> format and is the reader and writer unshackle uses.</p>
<div class="admonition note">
<p class="admonition-title">Region is recorded only with a proxy</p>
<p>When you use <code>--proxy</code>, the export records the region so an import can reproduce the
correct geofence. Without a proxy, the export stores no region.</p>
</div>
<div class="admonition warning">
<p class="admonition-title">Some DASH and Smooth exports need a title language</p>
<p>An import re-fetches the DASH or ISM manifest and parses it again. Most manifests label
their own streams, and those import fine. When a manifest labels nothing, the parse falls
back to the title's original language, which comes from <code>Title.language</code> on the exporting
service. If a service never sets it, importing that export fails with a message naming
the service. Neither end guesses a language for you, so the fix belongs in the service.</p>
<p>An HLS master playlist gives no language for a video track. When the export gives no
title language, the video track takes the language of the default audio track. When
the master playlist gives no audio language either, the import stops with a message.</p>
</div>
<h2 id="metadata-and-tagging">Metadata and tagging<a class="headerlink" href="#metadata-and-tagging" title="Permanent link">&para;</a></h2>
<p>unshackle looks up metadata automatically, but you can override the identifiers used for
tagging and naming. An ID you give is authoritative: unshackle looks it up directly instead of
searching by title, and the ID stays in the tags. An ID only settles <em>which</em> title this is.
To also take that source's title, year and original language, add <code>--enrich</code>. Give at most one
of <code>--tmdb</code>, <code>--imdb</code> and <code>--tvdb</code>, and unshackle works the rest out from it. To stop the automatic
lookups but keep the IDs you give, set
<a href="../../reference/configuration/misc/#external-api-keys"><code>disable_metadata</code></a> in your config.</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--tmdb</code></td>
<td><code>--tmdb 27205</code></td>
<td>Use this TMDB ID instead of an automatic search. Needs <code>tmdb_api_key</code>.</td>
</tr>
<tr>
<td><code>--imdb</code></td>
<td><code>--imdb tt1375666</code></td>
<td>Use this IMDb ID instead of an automatic search. Needs no API key.</td>
</tr>
<tr>
<td><code>--tvdb</code></td>
<td><code>--tvdb 73871</code></td>
<td>Use this TVDB ID instead of looking the series up. Needs <code>tvdb_api_key</code>.</td>
</tr>
<tr>
<td><code>--anilist</code></td>
<td><code>--anilist 21</code></td>
<td>Use this AniList ID instead of an automatic search. <code>mal:12345</code> is also accepted. Needs no API key.</td>
</tr>
<tr>
<td><code>--enrich</code></td>
<td>-</td>
<td>Overwrite the show title, year and original language with the external source's. <strong>Requires</strong> one of <code>--tmdb</code>, <code>--imdb</code>, <code>--tvdb</code>, or <code>--anilist</code>.</td>
</tr>
<tr>
<td><code>--tvdb-order</code></td>
<td><code>--tvdb-order dvd</code></td>
<td>Renumber episodes to a TVDB season order. Needs <code>tvdb_api_key</code>.</td>
</tr>
</tbody>
</table>
<div class="language-shell highlight"><span class="filename">Force the right IMDb match, and keep the service&#x27;s own naming</span><pre><span></span><code><span id="__span-46-1"><a id="__codelineno-46-1" name="__codelineno-46-1" href="#__codelineno-46-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--imdb<span class="w"> </span>tt1375666<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<div class="language-shell highlight"><span class="filename">Force the match and take IMDb&#x27;s title, year and language too</span><pre><span></span><code><span id="__span-47-1"><a id="__codelineno-47-1" name="__codelineno-47-1" href="#__codelineno-47-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--imdb<span class="w"> </span>tt1375666<span class="w"> </span>--enrich<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<h3 id="what-each-metadata-provider-supplies">What each metadata provider supplies<a class="headerlink" href="#what-each-metadata-provider-supplies" title="Permanent link">&para;</a></h3>
<p>Metadata providers differ in what they answer with, so the fields <code>--enrich</code> can replace
depend on which ID you gave. Every metadata provider except <code>imdb</code> and <code>anilist</code> only
operates when you set its config key:</p>
<table>
<thead>
<tr>
<th>Provider</th>
<th>Config key</th>
<th>Title and year</th>
<th>Original language</th>
<th>External IDs it returns</th>
</tr>
</thead>
<tbody>
<tr>
<td>TMDB</td>
<td><code>tmdb_api_key</code></td>
<td>yes</td>
<td>yes, alpha-2 such as <code>ko</code></td>
<td>IMDb, TMDB, TVDB</td>
</tr>
<tr>
<td>TVDB</td>
<td><code>tvdb_api_key</code></td>
<td>yes</td>
<td>yes, alpha-3 such as <code>kor</code></td>
<td>TMDB, TVDB, sometimes IMDb</td>
</tr>
<tr>
<td>OMDb</td>
<td><code>omdb_api_key</code></td>
<td>yes</td>
<td>yes, as an English name such as <code>Korean</code></td>
<td>IMDb</td>
</tr>
<tr>
<td>IMDb</td>
<td><em>(no config key needed)</em></td>
<td>yes</td>
<td>yes, alpha-2 such as <code>ko</code></td>
<td>IMDb</td>
</tr>
<tr>
<td>SIMKL</td>
<td><code>simkl_client_id</code></td>
<td>yes</td>
<td>no, it publishes a country and no language</td>
<td>IMDb, TMDB, TVDB</td>
</tr>
<tr>
<td>AniList</td>
<td><em>(no config key needed)</em></td>
<td>yes</td>
<td>yes, worked out from the country of origin, such as <code>ja</code></td>
<td>AniList</td>
</tr>
</tbody>
</table>
<p>Whatever the tag looks like, unshackle normalises it before use, so <code>ko</code>, <code>kor</code> and <code>Korean</code>
all end up as the same language.</p>
<div class="admonition note">
<p class="admonition-title">AniList only answers for anime</p>
<p>It is last in the default metadata provider order and returns nothing for a title
that is not anime. The only cost is one search that misses. Put <code>anilist</code> earlier in
<a href="../../reference/configuration/misc/#external-api-keys"><code>metadata_providers</code></a> if you mostly
download anime. <a href="../../reference/configuration/misc/#external-api-keys"><code>anilist_title_language</code></a>
sets which of the three AniList title variants unshackle uses.</p>
<p>A service can also mark its titles as anime. For those titles unshackle tries AniList
first. When AniList has no match, it falls through to the normal order.</p>
</div>
<p>Each ID goes to the providers that read that kind of ID, in
<a href="../../reference/configuration/misc/#external-api-keys"><code>metadata_providers</code></a> order:</p>
<ul>
<li><code>--tmdb</code> reads TMDB.</li>
<li><code>--imdb</code> reads IMDb, then falls back to OMDb. IMDb needs no API key, so this path works
out of the box, and an OMDb API key only matters when IMDb has no answer.</li>
<li><code>--tvdb</code> reads TVDB. It needs <code>tvdb_api_key</code>.</li>
<li><code>--anilist</code> reads AniList, which needs no API key. It supplies the title, the year and the
original language, and writes an AniList tag. It knows no TMDB, IMDB or TVDB ID, so pair it
with <code>--tmdb</code>, <code>--imdb</code> or <code>--tvdb</code> when you want those tags as well.</li>
</ul>
<p>Give <strong>one</strong> of <code>--tmdb</code>, <code>--imdb</code> and <code>--tvdb</code>. You cannot combine them, because one ID
does the job on its own: unshackle finds the other two from it and writes all three to the
tags.
Passing two is an error rather than a silent choice between them. <code>--anilist</code> is the exception
and still pairs with one of the three, which is how you tag an anime title with a western ID.</p>
<p>The ID you give must have a metadata provider that can find it, so unshackle makes sure of
that before it downloads anything. <code>--tmdb</code> without <code>tmdb_api_key</code>, or an ID whose metadata
providers your <code>metadata_providers</code> list leaves out, fails immediately with a message naming
what to set. <code>--imdb</code> needs no API key, because the <code>imdb</code> metadata provider is keyless
and in the default order.</p>
<p>With <code>--enrich</code>, the title, year and original language are all replaced with the external
source's values, whether or not the service already filled them in. A field the source does
not answer with is left alone, and unshackle logs which fields those were, so a metadata provider
with a thin record cannot blank out what the service told you.</p>
<p><code>--enrich</code> also fills in the absolute episode number of each episode from TVDB's absolute
order, for any series that has one and where the service did not supply it. Anime is the
usual beneficiary, but nothing here applies only to anime. This only adds the
<a href="../../reference/configuration/output/#output_template"><code>{absolute}</code></a> naming variable.
<code>--enrich</code> never changes the season and episode numbers.</p>
<p>With <code>--daily</code>, <code>--enrich</code> also fills in the air date of each episode from TVDB. See
<a href="#daily-and-date-based-content">Daily and date-based content</a>.</p>
<div class="admonition warning">
<p class="admonition-title"><code>--enrich</code> replaces the original language, which affects more than the filename</p>
<p>Track selection reads the original language, so replacing it changes which audio is
treated as the original. That is the point when a service mislabels it, but it means a
wrong ID can pick the wrong audio track and not only write a wrong name. Without
<code>--enrich</code>, unshackle keeps the service's own value and does not change track
selection.</p>
</div>
<h3 id="episode-ordering">Episode ordering<a class="headerlink" href="#episode-ordering" title="Permanent link">&para;</a></h3>
<p>A service does not always number a series the way TVDB's aired order does. Some services use
TVDB's <code>alternate</code> (Streaming) order for Futurama, for example, while TVDB's <code>official</code> order
holds back four season-one episodes to the start of season two. <code>--tvdb-order</code> works out which
order the service used, then renumbers the episodes into the order you asked for:</p>
<div class="language-shell highlight"><span class="filename">Download Futurama in DVD order</span><pre><span></span><code><span id="__span-48-1"><a id="__codelineno-48-1" name="__codelineno-48-1" href="#__codelineno-48-1"></a>unshackle<span class="w"> </span>dl<span class="w"> </span>--tvdb-order<span class="w"> </span>dvd<span class="w"> </span>EXAMPLE<span class="w"> </span><span class="m">81234567</span>
</span></code></pre></div>
<p>Available orders are <code>official</code> (aired), <code>dvd</code>, <code>absolute</code>, <code>alternate</code>, and <code>regional</code>. Set
<code>tvdb_order</code> in your config to apply one by default.</p>
<div class="admonition warning">
<p class="admonition-title">Orders that do not cover the whole series</p>
<p>An order can leave out episodes the service carries. TVDB's <code>dvd</code> order does not
contain Futurama's four movies. Those episodes keep their original numbering. If that would give
two episodes the same season/episode slot, and so the same filename, unshackle logs an
error and leaves the numbering untouched. Pick an order that covers the whole series.</p>
</div>
<h2 id="configuration-defaults">Configuration defaults<a class="headerlink" href="#configuration-defaults" title="Permanent link">&para;</a></h2>
<p>You can set every flag on this page as a default in your configuration file so you do not
have to type it each time, and you can scope defaults per service. See
<a href="../../getting-started/configuration-file/">Configuration file</a> for the <code>dl:</code> block and
per-service overrides.</p>
<div class="admonition tip">
<p class="admonition-title">Explicit flags always win</p>
<p>A value you pass on the command line (or through an environment variable) always takes
precedence over both the global <code>dl:</code> defaults and any per-service <code>dl:</code> overrides.
Config only fills in options you did not set explicitly.</p>
</div>
<h2 id="quick-reference">Quick reference<a class="headerlink" href="#quick-reference" title="Permanent link">&para;</a></h2>
<p>A condensed lookup of the most-used options. Use <code>unshackle dl --help</code> for the complete,
authoritative list.</p>
<table>
<thead>
<tr>
<th>Flag</th>
<th>Short</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--quality</code></td>
<td><code>-q</code></td>
<td>Target resolution(s), e.g. <code>1080,720</code>.</td>
</tr>
<tr>
<td><code>--vcodec</code></td>
<td><code>-v</code></td>
<td>Video codec(s).</td>
</tr>
<tr>
<td><code>--acodec</code></td>
<td><code>-a</code></td>
<td>Audio codec(s).</td>
</tr>
<tr>
<td><code>--range</code></td>
<td><code>-r</code></td>
<td>Colour range(s). Default <code>SDR</code>.</td>
</tr>
<tr>
<td><code>--channels</code></td>
<td><code>-c</code></td>
<td>Audio channel layout.</td>
</tr>
<tr>
<td><code>--noatmos</code></td>
<td><code>-naa</code></td>
<td>Exclude Atmos audio.</td>
</tr>
<tr>
<td><code>--lang</code></td>
<td><code>-l</code></td>
<td>Video + audio language(s); default <code>orig</code>. <code>-</code> excludes, e.g. <code>all,-es</code>.</td>
</tr>
<tr>
<td><code>--a-lang</code></td>
<td><code>-al</code></td>
<td>Audio-only language override. <code>-</code> excludes.</td>
</tr>
<tr>
<td><code>--v-lang</code></td>
<td><code>-vl</code></td>
<td>Video-only language override. <code>-</code> excludes.</td>
</tr>
<tr>
<td><code>--s-lang</code></td>
<td><code>-sl</code></td>
<td>Subtitle language(s); default <code>all</code>. <code>-</code> excludes, e.g. <code>all,-es</code>.</td>
</tr>
<tr>
<td><code>--forced-subs</code></td>
<td><code>-fs</code></td>
<td>Include forced subtitles.</td>
</tr>
<tr>
<td><code>--forced-s-lang</code></td>
<td><code>-fsl</code></td>
<td>Forced subtitle language(s); implies <code>-fs</code>. <code>-</code> excludes.</td>
</tr>
<tr>
<td><code>--sub-format</code></td>
<td></td>
<td>Output subtitle format.</td>
</tr>
<tr>
<td><code>--wanted</code></td>
<td><code>-w</code></td>
<td>Episode/season range, an air date, or a track number for a music release (<code>1-5</code>, <code>2x3</code>).</td>
</tr>
<tr>
<td><code>--daily</code></td>
<td></td>
<td>Fill missing air dates from TVDB during <code>--enrich</code>.</td>
</tr>
<tr>
<td><code>--select-titles</code></td>
<td></td>
<td>Interactively pick episodes or films.</td>
</tr>
<tr>
<td><code>--latest-episode</code></td>
<td></td>
<td>Only the newest episode.</td>
</tr>
<tr>
<td><code>--latest-episodes N</code></td>
<td></td>
<td>Only the N newest episodes.</td>
</tr>
<tr>
<td><code>--video-only</code> / <code>--audio-only</code> / <code>--subs-only</code></td>
<td><code>-V</code> / <code>-A</code> / <code>-S</code></td>
<td>Restrict track types.</td>
</tr>
<tr>
<td><code>--no-video</code> / <code>--no-audio</code> / <code>--no-subs</code> / <code>--no-chapters</code> / <code>--no-attachments</code></td>
<td><code>-nv</code> / <code>-na</code> / <code>-ns</code> / <code>-nc</code> / <code>-nt</code></td>
<td>Skip track types.</td>
</tr>
<tr>
<td><code>--worst</code></td>
<td></td>
<td>Lowest bitrate within <code>-q</code>.</td>
</tr>
<tr>
<td><code>--require-audio</code></td>
<td></td>
<td>Audio languages that must exist. The title fails if one is missing.</td>
</tr>
<tr>
<td><code>--require-video</code></td>
<td></td>
<td>Video languages that must exist. The title fails if one is missing.</td>
</tr>
<tr>
<td><code>--best-available</code></td>
<td></td>
<td>Degrade gracefully instead of failing.</td>
</tr>
<tr>
<td><code>--output</code></td>
<td><code>-o</code></td>
<td>Output directory for this run.</td>
</tr>
<tr>
<td><code>--split-audio</code> / <code>--merge-video</code> / <code>--no-mux</code></td>
<td></td>
<td>Muxing behaviour.</td>
</tr>
<tr>
<td><code>--postscript</code> / <code>--no-postscript</code></td>
<td></td>
<td>Run a command after each output file, or run none.</td>
</tr>
<tr>
<td><code>--proxy</code> / <code>--no-proxy</code> / <code>--no-proxy-download</code> / <code>--proxy-download</code></td>
<td></td>
<td>Proxy control.</td>
</tr>
<tr>
<td><code>--workers</code> / <code>--downloads</code> / <code>--slow</code></td>
<td></td>
<td>Concurrency and pacing.</td>
</tr>
<tr>
<td><code>--list</code> / <code>--list-titles</code> / <code>--skip-dl</code></td>
<td></td>
<td>Dry runs.</td>
</tr>
<tr>
<td><code>--cdm-only</code> / <code>--vaults-only</code></td>
<td></td>
<td>Content key source control.</td>
</tr>
<tr>
<td><code>--cdm &lt;name&gt;</code></td>
<td></td>
<td>Pin one CDM device, bypassing the <code>cdm</code> config mapping.</td>
</tr>
<tr>
<td><code>--export</code></td>
<td></td>
<td>Export track info and keys to JSON.</td>
</tr>
<tr>
<td><code>--tmdb</code> / <code>--imdb</code> / <code>--tvdb</code> / <code>--anilist</code> / <code>--enrich</code></td>
<td></td>
<td>Metadata overrides.</td>
</tr>
<tr>
<td><code>--tvdb-order</code></td>
<td></td>
<td>Renumber episodes to a TVDB season order.</td>
</tr>
</tbody>
</table>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../../getting-started/configuration-file/" class="md-footer__link md-footer__link--prev" aria-label="Previous: The Configuration File">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
The Configuration File
</div>
</div>
</a>
<a href="../cli-reference/" class="md-footer__link md-footer__link--next" aria-label="Next: CLI Reference">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
CLI Reference
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["content.code.annotate", "content.code.copy", "content.tabs.link", "content.tooltips", "navigation.footer", "navigation.indexes", "navigation.sections", "navigation.tabs", "navigation.top", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.d7400e89.min.js"></script>
</body>
</html>