So I've installed unshackle, total newbie here. What do I do now to download as this doesn't work. Obviously I have blanked out the url
run unshackle dl https://xxxxxxxx/episode/xxxx/xxxxxxxxxxx
+ Reply to Thread
Results 331 to 345 of 345
-
-
uv run unshackle dl -w s01e01 itv https://xxxxxxxx/episode/xxxx/xxxxxxxxxxx
you must have all binaries and services to make it work
service:
https://forum.videohelp.com/threads/418705-Unshackle-Modular-Movie-TV-and-Music-Archiv...e9#post2782045
and also create new unshackle.yaml to add thingsLast edited by iamghost; 28th Oct 2025 at 16:30.
-
Last edited by tvdownloaderfan; 28th Oct 2025 at 16:52.
-
Even though I've installed MKVToolNix it still shows I haven't ??
[Attachment 89418 - Click to enlarge] -
unshackle.yaml
https://forum.videohelp.com/threads/418705-Unshackle-Modular-Movie-TV-and-Music-Archiv...e2#post2779137
[Attachment 89419 - Click to enlarge]
go read from page 1 through 12, it everything have answer -
Almost there but I can't get MKVToolNix installed
[Attachment 89423 - Click to enlarge]Last edited by tvdownloaderfan; 28th Oct 2025 at 19:07.
-
-
If you use the unshackle-example.yaml and then save it as unshackle.yaml, the only critical sections are the CDM and Services. The rest are for you to tinker with. Use BBC as a test as it doesn't use the CDM and no authentication is required but you need to have the services folder with at a minimum, iP as the first service config. -
No idea what you mean. What and where do I add for BBC ITV STV ch4 and ch 5 ?
# Set terminal background color (custom option not in CONFIG.md)
set_terminal_bg: false
# Set file naming convention
# true for style - Prime.Suspect.S07E01.The.Final.Act.Part.One.1080p. ITV.WEB-DL.AAC2.0.H.264
# false for style - Prime Suspect S07E01 The Final Act - Part One
scene_naming: true
# Whether to include the year in series names for episodes and folders (default: true)
# true for style - Show Name (2023) S01E01 Episode Name
# false for style - Show Name S01E01 Episode Name
series_year: true
# Check for updates from GitHub repository on startup (default: true)
update_checks: true
# How often to check for updates, in hours (default: 24)
update_check_interval: 24
# Title caching configuration
# Cache title metadata to reduce redundant API calls
title_cache_enabled: true # Enable/disable title caching globally (default: true)
title_cache_time: 1800 # Cache duration in seconds (default: 1800 = 30 minutes)
title_cache_max_retention: 86400 # Maximum cache retention for fallback when API fails (default: 86400 = 24 hours)
# Muxing configuration
muxing:
set_title: false
# Login credentials for each Service
credentials:
# Direct credentials (no profile support)
EXAMPLE: email@example.com
assword
# Per-profile credentials with default fallback
SERVICE_NAME:
default: default@email.com
assword # Used when no -p/--profile is specified
profile1: user1@email.com
assword1
profile2: user2@email.com
assword2
# Per-profile credentials without default (requires -p/--profile)
SERVICE_NAME2:
john: john@example.com:johnspassword
jane: jane@example.com:janespassword
# You can also use list format for passwords with special characters
SERVICE_NAME3:
default: ["user@email.com", ":PasswordWith:Colons"]
# Override default directories used across unshackle
directories:
cache: Cache
cookies: Cookies
dcsl: DCSL # Device Certificate Status List
downloads: Downloads
logs: Logs
temp: Temp
wvds: WVDs
prds: PRDs
# Additional directories that can be configured:
# commands: Commands
services:
- /path/to/services
- /other/path/to/services
# vaults: Vaults
# fonts: Fonts
# Pre-define which Widevine or PlayReady device to use for each Service
cdm:
# Global default CDM device (fallback for all services/profiles)
default: WVD_1
# Direct service-specific CDM
DIFFERENT_EXAMPLE: PRD_1
# Per-profile CDM configuration
EXAMPLE:
john_sd: chromecdm_903_l3 # Profile 'john_sd' uses Chrome CDM L3
jane_uhd: nexus_5_l1 # Profile 'jane_uhd' uses Nexus 5 L1
default: generic_android_l3 # Default CDM for this service
# NEW: Quality-based CDM selection
# Use different CDMs based on video resolution
# Supports operators: >=, >, <=, <, or exact match
EXAMPLE_QUALITY:
"<=1080": generic_android_l3 # Use L3 for 1080p and below
">1080": nexus_5_l1 # Use L1 for above 1080p (1440p, 2160p)
default: generic_android_l3 # Optional: fallback if no quality match
# You can mix profiles and quality thresholds in the same service
NETFLIX:
# Profile-based selection (existing functionality)
john: netflix_l3_profile
jane: netflix_l1_profile
# Quality-based selection (new functionality)
"<=720": netflix_mobile_l3
"1080": netflix_standard_l3
">=1440": netflix_premium_l1
# Fallback
default: netflix_standard_l3
# Use pywidevine Serve-compliant Remote CDMs
remote_cdm:
- name: "chrome"
device_name: chrome
device_type: CHROME
system_id: 27175
security_level: 3
host: https://domain.com/api
secret: secret_key
- name: "chrome-2"
device_name: chrome
device_type: CHROME
system_id: 26830
security_level: 3
host: https://domain-2.com/api
secret: secret_key
- name: "decrypt_labs_chrome"
type: "decrypt_labs" # Required to identify as DecryptLabs CDM
device_name: "ChromeCDM" # Scheme identifier - must match exactly
device_type: CHROME
system_id: 4464 # Doesn't matter
security_level: 3
host: "https://keyxtractor.decryptlabs.com"
secret: "your_decrypt_labs_api_key_here" # Replace with your API key
- name: "decrypt_labs_l1"
type: "decrypt_labs"
device_name: "L1" # Scheme identifier - must match exactly
device_type: ANDROID
system_id: 4464
security_level: 1
host: "https://keyxtractor.decryptlabs.com"
secret: "your_decrypt_labs_api_key_here"
- name: "decrypt_labs_l2"
type: "decrypt_labs"
device_name: "L2" # Scheme identifier - must match exactly
device_type: ANDROID
system_id: 4464
security_level: 2
host: "https://keyxtractor.decryptlabs.com"
secret: "your_decrypt_labs_api_key_here"
- name: "decrypt_labs_playready_sl2"
type: "decrypt_labs"
device_name: "SL2" # Scheme identifier - must match exactly
device_type: PLAYREADY
system_id: 0
security_level: 2000
host: "https://keyxtractor.decryptlabs.com"
secret: "your_decrypt_labs_api_key_here"
- name: "decrypt_labs_playready_sl3"
type: "decrypt_labs"
device_name: "SL3" # Scheme identifier - must match exactly
device_type: PLAYREADY
system_id: 0
security_level: 3000
host: "https://keyxtractor.decryptlabs.com"
secret: "your_decrypt_labs_api_key_here"
# Key Vaults store your obtained Content Encryption Keys (CEKs)
# Use 'no_push: true' to prevent a vault from receiving pushed keys
# while still allowing it to provide keys when requested
key_vaults:
- type: SQLite
name: Local
path: key_store.db
# Additional vault types:
# - type: API
# name: "Remote Vault"
# uri: "https://key-vault.example.com"
# token: "secret_token"
# no_push: true # This vault will only provide keys, not receive them
# - type: MySQL
# name: "MySQL Vault"
# host: "127.0.0.1"
# port: 3306
# database: vault
# username: user
# password: pass
# no_push: false # Default behavior - vault both provides and receives keys
# Choose what software to use to download data
downloader: aria2c
# Options: requests | aria2c | curl_impersonate | n_m3u8dl_re
# Can also be a mapping:
# downloader:
# NF: requests
# AMZN: n_m3u8dl_re
# DSNP: n_m3u8dl_re
# default: requests
# aria2c downloader configuration
aria2c:
max_concurrent_downloads: 4
max_connection_per_server: 3
split: 5
file_allocation: falloc # none | prealloc | falloc | trunc
# N_m3u8DL-RE downloader configuration
n_m3u8dl_re:
thread_count: 16
ad_keyword: "advertisement"
use_proxy: true
# curl_impersonate downloader configuration
curl_impersonate:
browser: chrome120
# Pre-define default options and switches of the dl command
dl:
sub_format: srt
downloads: 4
workers: 16
lang:
- en
- fr
EXAMPLE:
bitrate: CBR
# Chapter Name to use when exporting a Chapter without a Name
chapter_fallback_name: "Chapter {j:02}"
# Case-Insensitive dictionary of headers for all Services
headers:
Accept-Language: "en-US,en;q=0.8"
User-Agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
# Override default filenames used across unshackle
filenames:
log: "unshackle_{name}_{time}.log"
config: "config.yaml"
root_config: "unshackle.yaml"
chapters: "Chapters_{title}_{random}.txt"
subtitle: "Subtitle_{id}_{language}.srt"
# API key for The Movie Database (TMDB)
tmdb_api_key: ""
# conversion_method:
# - auto (default): Smart routing - subby for WebVTT/SAMI, standard for others
# - subby: Always use subby with advanced processing
# - pycaption: Use only pycaption library (no SubtitleEdit, no subby)
# - subtitleedit: Prefer SubtitleEdit when available, fall back to pycaption
# - pysubs2: Use pysubs2 library (supports SRT/SSA/ASS/WebVTT/TTML/SAMI/MicroDVD/MPL2/TMP)
subtitle:
conversion_method: auto
sdh_method: auto
# Configuration for pywidevine's serve functionality
serve:
users:
secret_key_for_user:
devices:
- generic_nexus_4464_l3
username: user
# devices:
# - '/path/to/device.wvd'
# Configuration data for each Service
services:
# Service-specific configuration goes here
# Profile-specific configurations can be nested under service names
# Example: with profile-specific device configs
EXAMPLE:
# Global service config
api_key: "service_api_key"
# Service certificate for Widevine L1/L2 (base64 encoded)
# This certificate is automatically used when L1/L2 schemes are selected
# Services obtain this from their DRM provider or license server
certificate: |
CAUSwwUKvQIIAxIQ5US6QAvBDzfTtjb4tU/7QxiH8c+TBSKOAjCCAQoCggEBAObzvlu2hZRsapAPx4Aa4GUZj 4/GjxgXUtBH4THSkM40x63wQeyVxlEEo
# ... (full base64 certificate here)
# Profile-specific device configurations
profiles:
john_sd:
device:
app_name: "AIV"
device_model: "SHIELD Android TV"
jane_uhd:
device:
app_name: "AIV"
device_model: "Fire TV Stick 4K"
# Example: Service with different regions per profile
SERVICE_NAME:
profiles:
us_account:
region: "US"
api_endpoint: "https://api.us.service.com"
uk_account:
region: "GB"
api_endpoint: "https://api.uk.service.com"
# External proxy provider services
proxy_providers:
nordvpn:
username: username_from_service_credentials
password: password_from_service_credentials
server_map:
us: 12 # force US server #12 for US proxies
surfsharkvpn:
username: your_surfshark_service_username # Service credentials from https://my.surfshark.com/vpn/manual-setup/main/openvpn
password: your_surfshark_service_password # Service credentials (not your login password)
server_map:
us: 3844 # force US server #3844 for US proxies
gb: 2697 # force GB server #2697 for GB proxies
au: 4621 # force AU server #4621 for AU proxies
basic:
GB:
- "socks5://username
assword@bhx.socks.ipvanish.com:1080" # 1 (Birmingham)
- "socks5://username
assword@gla.socks.ipvanish.com:1080" # 2 (Glasgow)
AU:
- "socks5://username
assword@syd.socks.ipvanish.com:1080" # 1 (Sydney)
- "https://username
assword@au-syd.prod.surfshark.com" # 2 (Sydney)
- "https://username
assword@au-bne.prod.surfshark.com" # 3 (Brisbane)
BG: "https://username
assword@bg-sof.prod.surfshark.com"
-
I swapped out the version of shaka-packager to v2.6.1 from, as suggested by this Github page (https://github.com/stabbedbybrick/services). The previous error message is now gone, but now it has been replaced by the following one.
I looked through the thread and couldn't find the same error. Suggestions are welcome╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ C:\Windows\System32\unshackle\unshackle\commands\d l.py:1009 in result │
│ │
│ 1006 │ │ │ │ │ │ │ │ for i, track in enumerate(title.track │
│ 1007 │ │ │ │ │ │ │ ) │
│ 1008 │ │ │ │ │ │ ): │
│ ❱ 1009 │ │ │ │ │ │ │ download.result() │
│ 1010 │ │ │ except KeyboardInterrupt: │
│ 1011 │ │ │ │ console.print(Padding("
: Download Cancelled...", (0 │
│ 1012 │ │ │ │ return │
│ │
│ C:\Users\dasilva\AppData\Roaming\uv\python\cpython-3.12.12-windows-x86_64-no │
│ ne\Lib\concurrent\futures\_base.py:449 in result │
│ │
│ 446 │ │ │ │ if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: │
│ 447 │ │ │ │ │ raise CancelledError() │
│ 448 │ │ │ │ elif self._state == FINISHED: │
│ ❱ 449 │ │ │ │ │ return self.__get_result() │
│ 450 │ │ │ │ │
│ 451 │ │ │ │ self._condition.wait(timeout) │
│ 452 │
│ │
│ C:\Users\dasilva\AppData\Roaming\uv\python\cpython-3.12.12-windows-x86_64-no │
│ ne\Lib\concurrent\futures\_base.py:401 in __get_result │
│ │
│ 398 │ def __get_result(self): │
│ 399 │ │ if self._exception: │
│ 400 │ │ │ try: │
│ ❱ 401 │ │ │ │ raise self._exception │
│ 402 │ │ │ finally: │
│ 403 │ │ │ │ # Break a reference cycle with the exception in self._ │
│ 404 │ │ │ │ self = None │
│ │
│ C:\Users\dasilva\AppData\Roaming\uv\python\cpython-3.12.12-windows-x86_64-no │
│ ne\Lib\concurrent\futures\thread.py:59 in run │
│ │
│ 56 │ │ │ return │
│ 57 │ │ │
│ 58 │ │ try: │
│ ❱ 59 │ │ │ result = self.fn(*self.args, **self.kwargs) │
│ 60 │ │ except BaseException as exc: │
│ 61 │ │ │ self.future.set_exception(exc) │
│ 62 │ │ │ # Break a reference cycle with the exception 'exc' │
│ │
│ C:\Windows\System32\unshackle\unshackle\core\track s\track.py:249 in download │
│ │
│ 246 │ │ │ │ │ cdm=cdm, │
│ 247 │ │ │ │ ) │
│ 248 │ │ │ elif self.descriptor == self.Descriptor.DASH: │
│ ❱ 249 │ │ │ │ DASH.download_track( │
│ 250 │ │ │ │ │ track=self, │
│ 251 │ │ │ │ │ save_path=save_path, │
│ 252 │ │ │ │ │ save_dir=save_dir, │
│ │
│ C:\Windows\System32\unshackle\unshackle\core\manif ests\dash.py:564 in │
│ download_track │
│ │
│ 561 │ │ │
│ 562 │ │ if drm: │
│ 563 │ │ │ progress(downloaded="Decrypting", completed=0, total=100) │
│ ❱ 564 │ │ │ drm.decrypt(save_path) │
│ 565 │ │ │ track.drm = None │
│ 566 │ │ │ events.emit(events.Types.TRACK_DECRYPTED, track=track, drm │
│ 567 │ │ │ progress(downloaded="Decrypting", advance=100) │
│ │
│ C:\Windows\System32\unshackle\unshackle\core\drm\w idevine.py:267 in decrypt │
│ │
│ 264 │ │ if decrypter == "mp4decrypt": │
│ 265 │ │ │ return self._decrypt_with_mp4decrypt(path) │
│ 266 │ │ else: │
│ ❱ 267 │ │ │ return self._decrypt_with_shaka_packager(path) │
│ 268 │ │
│ 269 │ def _decrypt_with_mp4decrypt(self, path: Path) -> None: │
│ 270 │ │ """Decrypt using mp4decrypt""" │
│ │
│ C:\Windows\System32\unshackle\unshackle\core\drm\w idevine.py:374 in │
│ _decrypt_with_shaka_packager │
│ │
│ 371 │ │ │ p.wait() │
│ 372 │ │ │ │
│ 373 │ │ │ if p.returncode != 0 or had_error: │
│ ❱ 374 │ │ │ │ raise subprocess.CalledProcessError(p.returncode, argu │
│ 375 │ │ │ │
│ 376 │ │ │ path.unlink() │
│ 377 │ │ │ if not stream_skipped: │
╰───────────────────────────────────────────────── ─────────────────────────────╯
CalledProcessError: Command
'['input=E:\\Unshackle\\Temp\\Audio_f9bc085b.mp4,str eam=0,output=E:\\Unshackle\\
Temp\\Audio_f9bc085b_decrypted.mp4,output_format=M P4',
'--enable_raw_key_decryption', '--keys',
'label=0:key_id=00000000000000000000000004122381:k ey=c42487fc7bb540c70d2c7f691f8
578a8,label=1:key_id=00000000000000000000000000000 000:key=c42487fc7bb540c70d2c7f
691f8578a8', '--temp_dir', WindowsPath('E:/Unshackle/Temp')]' returned non-zero
exit status 1.
❌ Download Failed...
An unexpected error occurred in one of the download workers.
Binary call failed, Process exit code: 1
See the error trace above for more information.
Edit: After looking in the older Devine thread, I saw someone suggest v3.2.0 around a year ago, that finally one fixed the issue. All of the shaka-packager versions that came out afterwards crash for some reason.Last edited by TGreatOne; 29th Oct 2025 at 09:10.
-
I thought I already have them ?
Hoe do I install them ? What does it mean Add folder to devine.yaml or unshackle.yaml
[Attachment 89437 - Click to enlarge]
[Attachment 89438 - Click to enlarge] -
If someone can please answer me thanks. I don't get how you can add a folder to file like unshackle.yaml, makes no sense
-
So you have a folder in Unshackle called Services. You right click that folder and select "copy as path". The you go to your .yaml file and look for this line:
# Override default directories used across unshackle
directories:
services: C:\unshackle\services
Whatever your path is you put a space after services: and paste that path and you save it. Do the same for the cache and cookie folder. I hope that helps. It has been a while since I set up Unshackle so I am a bit fuzzy and I tend to forget. I hope you continue to get the help you need to get Unshackle set up and working. It is a terrific program and I am grateful for it.
Similar Threads
-
Devine - Modular Movie, TV, and Music Archival Software
By billybanana in forum Video Streaming DownloadingReplies: 1859Last Post: 14th Oct 2025, 15:23 -
Bitrate confusion: HD vs. DV archival
By taigi in forum Capturing and VCRReplies: 3Last Post: 9th Nov 2024, 04:38 -
How do I completely remove the music and sound effects from a movie?
By cns00 in forum EditingReplies: 1Last Post: 15th Jan 2024, 13:11 -
Which software can remove music from show but keep character dialogue?
By Mohamed61020 in forum AudioReplies: 6Last Post: 2nd Jul 2023, 22:32 -
Software for simple music videos?
By dewiclements in forum Software PlayingReplies: 3Last Post: 26th Jul 2022, 02:21


Quote

