Download content from streaming platforms
Project description
📖 Table of Contents
- Installation
- Quick Start
- Login
- Service
- Downloaders
- Configuration
- Usage Examples
- Global Search
- Advanced Features
- Docker
- GUI
- Related Projects
Installation
Manual Clone
git clone https://github.com/AstraeLabs/VibraVid.git
cd VibraVid
PyPI
# Install dependencies
pip install -r requirements.txt
# Run
python manual.py
# Update
python update.py
# Sync dependencies
pip install -r requirements.txt --upgrade
Uv
# Install dependencies
uv sync
# Run
uv run manual.py
# Update
uv run update.py
# Sync dependencies
uv sync --upgrade
Additional Documentation
- 📝 Login Guide - Authentication for supported services
Quick Start
# If installed via PyPI
pip install VibraVid
VibraVid
# If installed via uv
uv tool install VibraVid
VibraVid
# If cloned manually
python manual.py
Downloaders
| Type | Description | Example |
|---|---|---|
| HLS | HTTP Live Streaming (m3u8) | View example |
| MP4 | Direct MP4 download | View example |
| DASH | MPEG-DASH with DRM bypass* | View example |
*DASH with DRM bypass: Requires a valid L3 CDM (Content Decryption Module). This project does not provide or facilitate obtaining CDMs. Users must ensure compliance with applicable laws.
Configuration
Key configuration parameters in config.json:
Output Directories
{
"OUTPUT": {
"root_path": "Video",
"movie_folder_name": "Movie",
"serie_folder_name": "Serie",
"anime_folder_name": "Anime",
"movie_format": "%(title_name) (%(title_year))/%(title_name) (%(title_year))",
"episode_format": "%(series_name)/S%(season:02d)/%(episode_name) S%(season:02d)E%(episode:02d)"
}
}
-
root_path: Base directory where videos are saved- Windows:
C:\\MyLibrary\\Folderor\\\\MyServer\\Share - Linux/MacOS:
Desktop/MyLibrary/Folder
- Windows:
-
movie_folder_name: Subfolder name for movies (default:"Movie")- Supports
%{site_name}placeholder:"Movie/%{site_name}"→"Movie/Crunchyroll" - Example with year:
"Movie (%{site_name})"
- Supports
-
serie_folder_name: Subfolder name for TV series (default:"Serie")- Supports
%{site_name}placeholder:"Serie/%{site_name}"→"Serie/Crunchyroll" - Example with year:
"Series by %{site_name}"
- Supports
-
anime_folder_name: Subfolder name for anime (default:"Anime")- Supports
%{site_name}placeholder:"Anime/%{site_name}"→"Anime/Crunchyroll"
- Supports
Movie Format Configuration
Default format: "%(title_name) (%(title_year))/%(title_name) (%(title_year))"
Results in:
%(title_name) (%(title_year))/ → Movie folder (Inception (2010))
%(title_name) (%(title_year)) → Filename (Inception (2010).mkv)
Format variables:
%(title_name): Movie title%(title_name_slug): Movie title as slug%(title_year): Movie release year (optional, removed if not available)%(quality): Video resolution%(language): Audio languages%(video_codec): Video codec%(audio_codec): Audio codec
Episode Format Configuration
Default format: "%(series_name)/S%(season:02d)/%(episode_name) S%(season:02d)E%(episode:02d)"
Results in:
%(series_name)/ → Series folder (Breaking Bad)
S%(season:02d)/ → Season folder (S01, S02, ...)
%(episode_name)... → Filename (Pilot S01E05.mkv)
Format variables:
%(series_name): Series name%(series_name_slug): Series name as slug%(series_year): Series release year%(season:FORMAT): Season number — padding controlled inline (see table below)%(episode:FORMAT): Episode number — padding controlled inline (see table below)%(episode_name): Episode title (sanitized)%(episode_name_slug): Episode title as slug%(quality): Video resolution%(language): Audio languages%(video_codec): Video codec%(audio_codec): Audio codec
Inline Padding Syntax:
| Token | Result (n=1) | Description |
|---|---|---|
%(season:02d) |
01 |
Zero-pad to 2 digits |
%(season:03d) |
001 |
Zero-pad to 3 digits |
%(season:d) |
1 |
No padding |
Note: The legacy add_siteName option has been removed. Use %{site_name} placeholder in folder names instead:
"movie_folder_name": "Movie/%{site_name}",
"serie_folder_name": "Serie/%{site_name}"
Download Settings
{
"DOWNLOAD": {
"auto_select": true,
"delay_after_download": 1,
"skip_download": false,
"thread_count": 12,
"concurrent_download": true,
"max_speed": "30MB",
"select_video": "1920",
"select_audio": "ita|Ita",
"select_subtitle": "ita|eng|Ita|Eng",
"cleanup_tmp_folder": true
}
}
Performance Settings
auto_select: Automatically select streams based on filters (default:true). Whenfalse, enables interactive stream selection mode where user can manually choose video/audio/subtitle tracks before download.delay_after_download: Set a delay applied after finishing the download of a movie or episode.skip_download: Skip the download step and process existing files (default:false)thread_count: Number of parallel download threads (default:12)concurrent_download: Enable parallel download queue for films and series episodes (default:true). Whentrue, downloads are queued and processed by a thread pool with a live Download Monitor table. Whenfalse, downloads run sequentially. When only one item is in the queue, it will download immediately regardless of this setting.max_speed: Speed limit per stream (e.g.,"30MB","10MB")cleanup_tmp_folder: Remove temporary files after download (default:true)
Stream Selection Filters
Control which streams are downloaded using select_video, select_audio, and select_subtitle:
Video Filter Syntax (select_video):
| Format | Description |
|---|---|
"best" |
Best available resolution |
"worst" |
Worst available resolution |
"1080" |
Exact height (fallback to worst if not found) |
"1080,H265" |
Height + codec constraint |
"1080|best" |
Height with fallback to best |
"1080|best,H265" |
Height + codec with fallback to best |
"false" |
Skip video (download) |
Audio Filter Syntax (select_audio):
| Format | Description | Behavior if not found |
|---|---|---|
"best" |
Best available bitrate per language | Selects best across all languages |
"worst" |
Worst available bitrate per language | Selects worst across all languages |
"all" |
All audio tracks | Downloads all |
"default" |
Only streams marked as default | DROP if no default stream exists |
"non-default" |
Only streams NOT marked as default | DROP if no non-default streams exist |
"ita" |
Find Italian audio | DROP (no download) |
"ita|it" |
Find specified languages (pipe-separated) | DROP if none found |
"ita,MP4A" |
Find Italian + MP4A codec | DROP if combination not found |
"ita|best" |
Language with fallback to best if not found | Fallback to best available |
"ita|best,AAC" |
Language + codec with fallback to best | Fallback to best available |
"false" |
Skip audio | Does not download |
Subtitle Filter Syntax (select_subtitle):
| Format | Description |
|---|---|
"all" |
All subtitles |
"default" |
Only streams marked as default |
"non-default" |
Only streams NOT marked as default |
"ita|eng" |
Language tokens (pipe-separated) |
"ita_forced" |
Language with flag (forced/cc/sdh) |
"ita_forced|eng_cc" |
Multiple languages with flags |
"false" |
Skip subtitles |
Native passthrough syntax (
res=...:codecs=...:for=...andid=...:for=...) is passed directly to N_m3u8DL-RE without further processing and is available for all three track types. Use it when you need precise control over manifest-level stream selection.
Processing Settings
{
"PROCESS": {
"use_gpu": false,
"param_video": ["-c:v", "libx265", "-crf", "28", "-preset", "medium"],
"param_audio": ["-c:a", "libopus", "-b:a", "128k"],
"param_final": ["-c", "copy"],
"audio_order": ["ita", "eng"],
"subtitle_order": ["ita", "eng"],
"merge_audio": true,
"merge_subtitle": true,
"subtitle_disposition_language": "ita_forced",
"extension": "mkv"
}
}
use_gpu: Enable hardware acceleration (default:false). When enabled, the GPU type is detected automatically at runtime:cudafor NVIDIA,qsvfor Intel,vaapifor AMD. No manual configuration is needed.param_video: FFmpeg video encoding parameters- Example:
["-c:v", "libx265", "-crf", "28", "-preset", "medium"](H.265/HEVC encoding)
- Example:
param_audio: FFmpeg audio encoding parameters- Example:
["-c:a", "libopus", "-b:a", "128k"](Opus audio at 128kbps)
- Example:
param_final: Final FFmpeg parameters (default:["-c", "copy"]for stream copy). When set, it takes full precedence overparam_videoandparam_audio.audio_order: List of strings to order audio tracks (e.g.,["ita", "eng"])subtitle_order: List of strings to order subtitle tracks (e.g.,["ita", "eng"])merge_audio: Merge all audio tracks into a single output file (default:true)merge_subtitle: Merge all subtitle tracks into a single output file (default:true)subtitle_disposition_language: Mark a specific subtitle as default/forcedforce_subtitle: How subtitles are handled before remuxing"auto"(default): subtitles are renamed/converted according to their detected format; VTT files are also sanitized (unmatched<replaced) to avoid data loss when muxed as SRT."copy": do not convert or rename, just mux the original file as-is (useful if you want to preserve VTT output). This also skips the VTT sanitization step, so any problematic<characters remain untouched."srt","vtt","ass": force-convert all subtitle tracks to the specified format using ffmpeg, applying sanitization forvttas needed.- See
VibraVid/core/processors/helper/ex_sub.pyfor conversion logic.
extension: Output file format ("mkv"or"mp4")
Request Settings
{
"REQUESTS": {
"timeout": 30,
"max_retry": 10,
"use_proxy": false,
"proxy": {
"http": "http://localhost:8888",
"https": "http://localhost:8888"
}
}
}
timeout: Request timeout in seconds (default:30)max_retry: Maximum retry attempts for failed requests (default:10)use_proxy: Enable proxy support for HTTP requests (default:false)proxy: Proxy configuration for HTTP and HTTPS connectionshttp: HTTP proxy URL (e.g.,"http://localhost:8888")https: HTTPS proxy URL (e.g.,"http://localhost:8888")
Default Settings
{
"DEFAULT": {
"close_console": true,
"show_message": false,
"fetch_domain_online": true,
"auto_update_check": true,
"imp_service": ["default"]
}
}
-
close_console: Automatically close console after download completion (default:true) -
show_message: Display debug messages (default:false) -
fetch_domain_online: Automatically fetch latest domains from GitHub (default:true) -
auto_update_check: Check for new VibraVid updates automatically at startup (default:true). If enabled, notifies you when a new version is available. -
imp_service: List of service source paths to load site modules from (default:["default"]). The"default"entry loads all built-in sites bundled with VibraVid. You can add absolute paths to external directories containing custom site modules — each directory must follow the standard module structure (a folder with__init__.pydefiningindiceand_useFor). Modules from custom paths take precedence over built-in ones if they share the same name."imp_service": ["default", "/home/user/my_custom_sites"]
DRM Configuration
{
"DRM": {
"use_cdm": true,
"prefer_remote_cdm": true,
"vault": {
"supa": {
"url": "https://crqczuxpqjmrjvdvqvlx.supabase.co",
"token": ""
}
}
}
}
use_cdm: Enable/disable CDM-based key extraction (default:true). When disabled, only database lookups are attempted.prefer_remote_cdm: Prefer remote CDM services over local devices (default:true). Whentrue, remote CDM API credentials are used; whenfalse, local CDM device files are prioritized.
Adding Remote CDM Services
When remote CDM services are back online, add the following to your config.json:
Widevine Remote CDM:
"widevine": {
"device_type": "ANDROID",
"system_id": 22590,
"security_level": 3,
"host": "https://cdrm-project.com/remotecdm/widevine",
"secret": "CDRM",
"device_name": "public"
}
device_type: Device model ("ANDROID","CHROME")system_id: Widevine system ID (default:22590for Android)security_level: Security level (1-3, where 3 = L3)host: Remote CDM server URLsecret: Authentication secret for the remote CDM servicedevice_name: Device identifier registered on the remote CDM service
PlayReady Remote CDM:
"playready": {
"device_name": "public",
"security_level": 3000,
"host": "https://cdrm-project.com/remotecdm/playready",
"secret": "CDRM"
}
device_name: Device identifier registered on the remote CDM servicesecurity_level: Security level (e.g.,3000for SL3000)host: Remote CDM server URLsecret: Authentication secret for the remote CDM service
Using Local CDM Devices
To use local CDM device files instead of remote services, place them in the project root and ensure they're discoverable by the system:
- Widevine:
.wvddevice file (from pywidevine) - PlayReady:
.prddevice file (from pyplayready)
When local devices are found, they will be automatically used if prefer_remote_cdm is set to false.
Usage Examples
Basic Commands
# Show help and available sites
python manual.py -h
# Search and download
python manual.py --site streamingcommunity --search "interstellar"
# Auto-download first result
python manual.py --site streamingcommunity --search "interstellar" --auto-first
# Use site by index
python manual.py --site 0 --search "interstellar"
Series Selection
Use --season and --episode to bypass interactive prompts when downloading series:
# Download a specific episode
python manual.py --site streamingcommunity --search "breaking bad" --season 1 --episode 3
# Download a range of episodes
python manual.py --site streamingcommunity --search "breaking bad" --season 1 --episode "1-5"
# Download all episodes of a season
python manual.py --site streamingcommunity --search "breaking bad" --season 1 --episode "*"
# Download all episodes of all seasons
python manual.py --site streamingcommunity --search "breaking bad" --season "*"
# Download multiple seasons
python manual.py --site streamingcommunity --search "breaking bad" --season "1-3"
Year Filter
Use --year to narrow search results to a specific release year or range:
# Exact year
python manual.py --site streamingcommunity --search "dune" --year 2021
# Year range
python manual.py --site streamingcommunity --search "batman" --year "1990-2015"
Stream Track Overrides
Override the default audio/video/subtitle selection from config for a single run:
# Select a different video resolution
python manual.py --site streamingcommunity --search "interstellar" -sv 1080
# Select audio language
python manual.py --site streamingcommunity --search "interstellar" -sa "eng"
# Select subtitles
python manual.py --site streamingcommunity --search "interstellar" -ss "eng"
Console Behaviour Override
Override the close_console config value for a single run without editing config.json:
# Keep console open after download (loop mode)
python manual.py --close-console false
# Close console after download
python manual.py --site streamingcommunity --search "interstellar" --close-console true
Proxy
# Enable proxy for this run (uses proxy settings from config.json)
python manual.py --site streamingcommunity --search "interstellar" --use_proxy
Show Dependency Paths
Display all resolved paths for config files, loaded services, external binaries (FFmpeg, N_m3u8DL-RE, Shaka Packager, Bento4) and DRM device files:
python manual.py --dep
Global Search
Search across multiple streaming sites simultaneously:
# Global search
python manual.py --global -s "cars"
# Search by category
python manual.py --category 1 # Anime
python manual.py --category 2 # Movies & Series
python manual.py --category 3 # Series only
Results display title, media type, and source site in a consolidated table.
Advanced Features
Hook System
Execute custom scripts before/after downloads. Configure in config.json:
{
"HOOKS": {
"pre_run": [
{
"name": "prepare-env",
"type": "python",
"path": "scripts/prepare.py",
"args": ["--clean"],
"env": { "MY_FLAG": "1" },
"cwd": "~",
"os": ["linux", "darwin"],
"timeout": 60,
"enabled": true,
"continue_on_error": true
}
],
"post_download": [
{
"name": "post-download-env",
"type": "python",
"path": "/app/script.py",
"args": ["{download_path}"],
"env": {
"MY_FLAG": "1"
},
"cwd": "~",
"os": ["linux"],
"timeout": 60,
"enabled": true,
"continue_on_error": true
}
],
"post_run": [
{
"name": "notify",
"type": "bash",
"command": "echo 'Download completed'"
}
]
}
}
Hook Configuration Options
- Stages available:
pre_run,post_download,post_run name: Descriptive name for the hooktype: Script type -python,bash,sh,shell,bat,cmdpath: Path to script file (alternative tocommand)command: Inline command to execute (alternative topath)args: List of arguments passed to the scriptenv: Additional environment variables as key-value pairscwd: Working directory for script execution (supports~and environment variables)os: Optional OS filter -["windows"],["darwin"](macOS),["linux"], or combinationstimeout: Maximum execution time in seconds (hook fails if exceeded)enabled: Enable/disable the hook without removing configurationcontinue_on_error: Iffalse, stops execution when hook fails
Hook Types
- Python hooks: Run with current Python interpreter
- Bash/sh/shell hooks: All three types execute via
/bin/bash -con macOS/Linux - Bat/cmd/shell hooks: Execute via
cmd /con Windows - Inline commands: Use
commandinstead ofpathfor simple one-liners. Note:argsare ignored when usingcommand; they only apply when usingpath.
Hook Context Placeholders
Hooks can interpolate download context in path, command, args, env, and cwd.
{download_path}: Absolute path of the downloaded file{download_dir}: Directory containing the downloaded file{download_filename}: Filename of the downloaded file{download_id}: Internal download identifier{download_title}: Download title{download_site}: Source site name{download_media_type}: Media type{download_status}: Final download status{download_error}: Error message, if present{download_success}:1on success,0on failure{stage}: Current hook stage
The same values are also exposed as environment variables with the SC_ prefix, such as SC_DOWNLOAD_PATH, SC_DOWNLOAD_FILENAME, SC_DOWNLOAD_SUCCESS, and SC_HOOK_STAGE.
Hooks are automatically executed before the main flow (pre_run), after each completed download (post_download), and at the end of the main execution flow (post_run). In the GUI, post_download runs for every individual completed item, while post_run is triggered once when the overall execution ends.
Source Code Update (update.py)
When running from a manual clone, update.py downloads and applies the latest commit from GitHub. It includes safety checks to avoid accidental deletion of user data.
# Interactive update (prompts for confirmation)
python update.py
# Skip the first confirmation prompt (still requires typing the confirmation phrase)
python update.py -y
# Cancel automatically without prompting
python update.py -n
# Preview what would be deleted without actually deleting anything
python update.py --dry-run
# Combine: skip first prompt and run in dry-run mode
python update.py -y --dry-run
The following folders and files are always preserved during an update and never deleted:
- Folders:
Video,Conf,.git - Files:
update.py
To preserve additional items, edit the KEEP_FOLDERS and KEEP_FILES sets at the top of update.py.
Docker
Recommended: Docker Compose (Production Ready)
Use docker-compose.yml for best results with persistent data:
# Start the container
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the container (data persists)
docker-compose down
# Restart the container
docker-compose up -d
Private Network Deployment
For deployments with a custom domain and private IP (e.g., LAN streaming):
Edit docker-compose.yml and uncomment the environment section, then update:
environment:
DJANGO_DEBUG: "false"
ALLOWED_HOSTS: "streaming.example.local,localhost,127.0.0.1,192.168.1.50"
CSRF_TRUSTED_ORIGINS: "https://streaming.example.local"
USE_X_FORWARDED_HOST: "true"
SECURE_PROXY_SSL_HEADER_ENABLED: "true"
CSRF_COOKIE_SECURE: "true"
SESSION_COOKIE_SECURE: "true"
DJANGO_SECRET_KEY: "your-secure-secret-key-here"
Replace the domain and IP with your actual values.
Manual Docker Build & Run
If you prefer not to use docker-compose:
# Build image
docker build -t vibravid .
# Run with persistent volumes (recommended)
docker run -d \
--name vibravid \
-p 8000:8000 \
-v vibravid_db:/app/GUI \
-v vibravid_videos:/app/Video \
-v vibravid_logs:/app/logs \
-v vibravid_config:/app/Conf \
--restart unless-stopped \
vibravid
Binding Local Folders
To save downloads to a specific folder on your host machine:
# Linux/macOS
docker run -d --name vibravid -p 8000:8000 \
-v ~/Downloads/Videos:/app/Video \
vibravid
# Windows (PowerShell)
docker run -d --name vibravid -p 8000:8000 `
-v "D:\Video:/app/Video" `
vibravid
Note: Path separators differ by OS. Use / for Linux/macOS and \ for Windows paths.
Related Projects
- MammaMia - Stremio addon for Italian streaming (by UrloMythus)
- Unit3Dup - Torrent automation for Unit3D tracker (by 31December99)
- N_m3u8DL-RE - Universal downloader for HLS/DASH/ISM (by nilaoda)
- pywidevine - Widevine L3 decryption library (by devine-dl)
- pyplayready - PlayReady decryption library (by ready-dl)
Disclaimer
This software is for educational and research purposes only. The authors:
- DO NOT assume responsibility for illegal use
- DO NOT provide or facilitate DRM circumvention tools, CDMs, or decryption keys
- DO NOT endorse piracy or copyright infringement
By using this software, you agree to comply with all laws and have rights to any content you process. No warranty is provided. If you do not agree, do not use this software.
Made with ❤️ for streaming lovers
If you find this project useful, consider starring it! ⭐
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vibravid-1.1.8.tar.gz.
File metadata
- Download URL: vibravid-1.1.8.tar.gz
- Upload date:
- Size: 239.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c914c16f8c1c1778fc1be1a7d7d2923d9832f6d7e1707503dd30502ad71c8658
|
|
| MD5 |
261c3cae57b492a56da7484c1d548743
|
|
| BLAKE2b-256 |
e5899c50a653de66a0b98ad2ffaabe4a9e176960ee32e158a09320637fd99c51
|
File details
Details for the file vibravid-1.1.8-py3-none-any.whl.
File metadata
- Download URL: vibravid-1.1.8-py3-none-any.whl
- Upload date:
- Size: 307.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e47e9463c02e0d85241c3e6895a994c4382eeb1cd536fc055c7c197e7dbb621e
|
|
| MD5 |
8211444311e79f64a9df86b1732e031b
|
|
| BLAKE2b-256 |
0fd8e53cb7b4d268cf8027510ed809334c0830e74be1d11375ad9a1dc6f746dd
|