Skip to content

All-in-one media downloader and converter with Web UI, desktop builds, and powerful ffmpeg automation. Built on yt-dlp · Supports YouTube & Spotify sources · Self-hosted

License

Notifications You must be signed in to change notification settings

G-grbz/Gharmonize

Repository files navigation

Gharmonize Logo

Gharmonize

1.mp4

Download • Convert • Rip • Tag — with a Web UI + Desktop builds (AppImage/EXE)

Fast, modular media processing powered by yt-dlp and ffmpeg: YouTube downloads, Spotify-based metadata matching, disc ripping (DRM-free), and GPU-accelerated conversions — all driven by a reliable job engine.

Spotify note: Spotify is used for metadata + matching (track/playlist/album info). Gharmonize does not claim DRM bypass.

ss

⚡ Quick Start

Docker Compose (recommended)

git clone https://github.com/G-grbz/Gharmonize
cd Gharmonize

# prepare folders (default: /opt/gharmonize)
sudo mkdir -p /opt/gharmonize/{uploads,outputs,temp,cookies,local-inputs}
sudo touch /opt/gharmonize/.env /opt/gharmonize/cookies/cookies.txt
sudo chmod -R a+rw /opt/gharmonize

# set at least ADMIN_PASSWORD + APP_SECRET in /opt/gharmonize/.env
# start
docker compose up -d --build

Open:

  • http://localhost:5174

Local (Node & npm)

git clone https://github.com/G-grbz/Gharmonize
cd Gharmonize

# Linux
BUILD_ELECTRON=1 npm i
npm start

✅ What you get (at a glance)

  • YouTube / YouTube Music downloads (single, playlist, mixes) via yt-dlp
  • Spotify integration for metadata + mapping to YouTube (track / playlist / album)
  • Audio & video conversion powered by ffmpeg, with reliability-first presets
  • Fix A/V sync issues using FPS adjustment presets for AC3 / EAC3 / AAC
  • GPU acceleration for local video transcoding: NVENC, VAAPI, Intel QSV
  • Disc ripping (DRM-free only) using ffmpeg + MKVToolNix, with stream selection in Web UI
  • Job engine for batch processing, progress, and reliability

📘 Table of Contents


Overview

Gharmonize is a media automation toolkit running as a Node.js server with an optional Electron desktop shell. It bundles multiple third‑party utilities (FFmpeg, MKVToolNix, yt-dlp, deno etc.) to provide:

  • High‑reliability downloading
  • Disc/media processing
  • Transcoding with GPU acceleration
  • Smart metadata extraction and automatic tagging

License details are available in Third-Party Licenses and LICENSES.md.


Features

  • YouTube & YouTube Music

    • yt-dlp integration with SABR / 403 workarounds
    • Support for single videos, playlists, and mixes
    • Customizable yt-dlp arguments via environment variables
  • Spotify Integration

    • Spotify Web API support (track / playlist / album)
    • Automatic mapping from Spotify items to YouTube
    • Optional preference for Spotify metadata when tagging
  • Disc Ripping (DRM-free only)

    • Rip non-DRM optical discs (e.g., DVD/Blu-ray) into audio/video files
    • Uses ffmpeg and MKVToolNix tools under the hood
    • Disc analysis and stream selection via the web UI
  • Audio & Video Conversion

    • ffmpeg-based conversion with focus on reliability

    • Convert to mp3 / flac / wav / ogg, or pass through mp4 without re-encoding when possible

    • Ready-made FPS adjustment presets for AC3 / EAC3 / AAC audio to fix or prevent sync issues

    • Transcode arbitrary local video files with hardware acceleration:

      • NVIDIA NVENC
      • VAAPI
      • Intel Quick Sync (QSV)
  • Local & Uploaded Media

    • File uploads handled via Multer
    • Optional local media directory (LOCAL_INPUT_DIR) for selecting files without uploading
    • Admin-only access for local inputs
  • Deployment & Config

    • Docker image & Docker Compose setup
    • Settings API for runtime configuration from the UI
    • Electron builds for Windows/Linux
    • .env-driven configuration for server, YouTube, Spotify and processing behavior

Requirements

Requirement Version Description
Node.js >= 20 Required
ffmpeg Any Included in Docker
yt-dlp Latest Included in Docker
Spotify API Keys Optional Enables Spotify metadata

Quick Start (Local – Node & npm)

1. Clone the Repository and Enter the Directory

git clone https://github.com/G-grbz/Gharmonize
cd Gharmonize

2. Create the .env File

To enable UI configuration, fill in ADMIN_PASSWORD and APP_SECRET. You can generate a secure APP_SECRET using the following command:

openssl rand -hex 32

3. Installation Commands

Linux

BUILD_ELECTRON=1 npm i

Windows (CMD)

set BUILD_ELECTRON=1
npm i

Default .env Locations (AppImage or .exe only)

These paths are not general application directories. They are created automatically only when running AppImage or Windows .exe builds, and store the default-generated .env file:

  • Windows: %appdata%\Gharmonize
  • Linux: ~/.config/Gharmonize/
  • Default Password: 123456

You can edit environment variables in the Settings panel. Windows users should add the file paths for ffmpeg and yt-dlp to their environment variables.


Run Without Building

To run the application without building:

Optional: If you do not want to use ffmpeg, ffprobe, yt-dlp, and mkvmerge tools from your host system — or if you prefer using the tested, verified versions — you can run:

npm run download:binaries

This command downloads the required third‑party binaries into the app directory so the application can use them internally.

Note: While this step is optional when using Run Without Building (npm start), it is strongly recommended for AppImage and Windows .exe builds to ensure consistent, validated binary versions.

Important: If you use npm run download:binaries, you must remove or clear any manually set binary paths in your .env file (FFMPEG_PATH, FFPROBE_PATH, YTDLP_PATH, etc.). Otherwise, the app will try to use the system tools instead of the downloaded ones.

npm start

Build Commands

Build AppImage (Linux only):

npm run desktop:build:appimage

Build NSIS (Windows Installer):

npm run desktop:build:nsis

Note: If you choose Install for all users (which installs under Program Files), you must manually create the temp, outputs, and uploads folders inside the installation directory and grant read/write permissions.

Alternatively, install to a custom directory outside Program Files or Program Files (x86).

Build Portable (Windows standalone):

npm run desktop:build:portable

Build both Windows versions (NSIS + Portable):

npm run desktop:build:all

Quick Start (Docker Compose)

1. Clone the Repository and Enter the Directory

git clone https://github.com/G-grbz/Gharmonize
cd Gharmonize

2. Create Required Folders and Files

The commands below assume the default directory /opt/gharmonize. If you want to use a different one, update the paths in the commands and under the volumes: section of your docker-compose.yml file. You can also switch the Docker image branch to either latest or testing if you prefer.

sudo mkdir -p /opt/gharmonize/{uploads,outputs,temp,cookies}
sudo touch /opt/gharmonize/.env /opt/gharmonize/cookies/cookies.txt
sudo chmod -R a+rw /opt/gharmonize

3. Configure Environment Variables

In the .env file, you only need to set ADMIN_PASSWORD and APP_SECRET. All other settings can be adjusted later via the settings panel.

To generate a random APP_SECRET:

openssl rand -hex 32

⚡ Optional: Enable NVIDIA NVENC (hardware-accelerated video encoding)

If you have an NVIDIA GPU and want to use hardware-accelerated encoding (NVENC) inside the container:

  1. Install the proprietary NVIDIA driver on the host.
  2. Install the NVIDIA Container Toolkit so Docker can access your GPU.
  3. Update your docker-compose.yml service like this:
version: "3.9"
services:
  web:
    image: ggrbz/gharmonize:latest
    container_name: Gharmonize
    user: "${PUID:-1000}:${PGID:-1000}"
    # Enable access to the NVIDIA GPU
    gpus: all
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=compute,video,utility
      - NODE_ENV=production
      - PORT=${PORT:-5174}
      - YT_FORCE_IPV4=1
      - YT_APPLY_403_WORKAROUNDS=1
      - YTDLP_EXTRA=--force-ipv4
      - PUID=${PUID:-1000}
      - PGID=${PGID:-1000}
      - DATA_DIR=/usr/src/app
    ports:
      - "${PORT:-5174}:${PORT:-5174}"
    volumes:
      - /opt/gharmonize/uploads:/usr/src/app/uploads
      - /opt/gharmonize/outputs:/usr/src/app/outputs
      - /opt/gharmonize/temp:/usr/src/app/temp
      - /opt/gharmonize/local-inputs:/usr/src/app/local-inputs
      - /opt/gharmonize/cookies:/usr/src/app/cookies
      - /opt/gharmonize/.env:/usr/src/app/.env
      - /home:/home:ro
      - /run/media:/run/media:ro
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:${PORT:-5174}/ || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 5

4. Start with Docker Compose

docker compose up -d --build

5. Open in Browser

http://localhost:5174

6. If You Encounter Permission Errors

Run the following command to reapply read/write permissions:

sudo chmod -R a+rw /opt/gharmonize

🐳 Alternative Installation Using Docker Run

1. Prepare Folders and Permissions

sudo mkdir -p /opt/gharmonize/{uploads,outputs,temp,cookies,local-inputs}
sudo touch /opt/gharmonize/.env /opt/gharmonize/cookies/cookies.txt
sudo chmod -R a+rw /opt/gharmonize

2. Run the Container

docker run -d \
  --name Gharmonize \
  -p 5174:5174 \
  -e NODE_ENV=production \
  -e PORT=5174 \
  -e YT_FORCE_IPV4=1 \
  -e YT_APPLY_403_WORKAROUNDS=1 \
  -e YTDLP_EXTRA="--force-ipv4" \
  -e PUID=1000 \
  -e PGID=1000 \
  -v /opt/gharmonize/uploads:/usr/src/app/uploads \
  -v /opt/gharmonize/outputs:/usr/src/app/outputs \
  -v /opt/gharmonize/temp:/usr/src/app/temp \
  -v /opt/gharmonize/local-inputs:/usr/src/app/local-inputs \
  -v /opt/gharmonize/cookies/:/usr/src/app/cookies/cookies.txt:ro \
  -v /opt/gharmonize/.env:/usr/src/app/.env \
  -v /home:/home:ro \
  -v /run/media:/run/media:ro \
  ggrbz/gharmonize:latest

With NVIDIA NVENC (optional)

If you want to run the container with NVENC enabled:

docker run -d \
  --name Gharmonize \
  --gpus all \
  -e NVIDIA_VISIBLE_DEVICES=all \
  -e NVIDIA_DRIVER_CAPABILITIES=compute,video,utility \
  -p 5174:5174 \
  -e NODE_ENV=production \
  -e PORT=5174 \
  -e YT_FORCE_IPV4=1 \
  -e YT_APPLY_403_WORKAROUNDS=1 \
  -e YTDLP_EXTRA="--force-ipv4" \
  -e PUID=1000 \
  -e PGID=1000 \
  -v /opt/gharmonize/uploads:/usr/src/app/uploads \
  -v /opt/gharmonize/outputs:/usr/src/app/outputs \
  -v /opt/gharmonize/temp:/usr/src/app/temp \
  -v /opt/gharmonize/cookies:/usr/src/app/cookies/cookies.txt:ro \
  -v /opt/gharmonize/.env:/usr/src/app/.env \
  -v /home:/home:ro \
  -v /run/media:/run/media:ro \
  ggrbz/gharmonize:latest

Note: Don’t forget to add ADMIN_PASSWORD and APP_SECRET values to the .env file located in /opt/gharmonize/ directory.


Docker vs Local Usage Notes

This section explains the differences between Docker and non-Docker setups.


🍪 Cookie Usage Notes

Cookie support improves YouTube–Gharmonize matching accuracy and allows downloading age-restricted or similar content.

  • Docker users: Only cookies.txt is supported.

  • Windows users:

    • Chrome cannot provide cookies while the browser is running due to platform limitations.
    • Sign in to YouTube using Firefox or another supported browser, then configure cookie access accordingly.
    • Set the YTDLP_COOKIES_FROM_BROWSER environment variable via the environment configuration or the settings panel.
  • Outside of Docker (and when correctly configured on Windows as described above), a cookies.txt file is not required.

🍪 Cookie & Browser Behavior

Outside Docker

Setting:

YTDLP_COOKIES_FROM_BROWSER=chrome

allows Gharmonize to extract YouTube cookies directly from your browser, enabling:

  • Age-restricted content downloads
  • No need for cookies.txt

You must be logged into YouTube on the same server/machine where Gharmonize is installed (in a supported browser profile).

Inside Docker

Browser cookie extraction cannot work (Docker cannot access host browser profiles). Keep it empty:

YTDLP_COOKIES_FROM_BROWSER=

📦 Docker Usage

When using Docker, leave all binary paths in .env empty:

YTDLP_BIN=
FFMPEG_BIN=
DATA_DIR=

Docker images include:

  • yt-dlp
  • ffmpeg
  • deno
  • mkvmerge suite

Docker is fully self‑contained. No manual binary installation is required.


🖥️ Local Usage (Node.js / AppImage / EXE / Electron)

Outside Docker, install the required binaries:

npm run download:binaries

This installs into:

build/bin/

including:

  • yt-dlp
  • ffmpeg
  • deno (required for age‑restricted YouTube content)

This step is mandatory for desktop builds.


🔞 Age‑Restricted YouTube Content

To download age‑restricted content, you need:

  • Cookies (browser or cookies.txt), AND
  • deno in build/bin/ (Linux → deno, Windows → deno.exe)

Cookies alone are not sufficient.

Docker already bundles deno, so no extra setup is needed.


📊 Environment Comparison Table

Environment cookies.txt Required? Browser Extraction Binaries Needed? Notes
Docker Optional ❌ Disabled ❌ Included Leave binary paths empty
Local (Node.js) Optional ✅ Yes ✅ Required Run npm run download:binaries
AppImage / EXE / Electron Optional ✅ Yes ✅ Required Must bundle binaries; deno required
Age‑restricted videos Not enough Helps deno required Docker includes it

Environment Variables (.env)

Create a .env file in the project root:

########################################
# Preview / Fetch Limits
########################################

PREVIEW_MAX_ENTRIES=
# Maximum number of entries shown in Automix / playlist preview.
# Higher value → more entries → more processing time.
# Acts as a safety limit in case YouTube returns extremely long lists.
# Example:
#   PREVIEW_MAX_ENTRIES=1000


AUTOMIX_ALL_TIMEOUT_MS=
# Timeout (in ms) for fetching the entire Automix list in a single request.
# If this timeout is hit, the system falls back to paginated mode.
# Example:
#   AUTOMIX_ALL_TIMEOUT_MS=45000


AUTOMIX_PAGE_TIMEOUT_MS=
# Timeout (in ms) for each paginated Automix request (e.g., 50 items per page).
# Used when flat/one-shot mode times out.
# Example:
#   AUTOMIX_PAGE_TIMEOUT_MS=45000


PLAYLIST_ALL_TIMEOUT_MS=
# Timeout (in ms) for fetching a full playlist using --flat-playlist.
# Large playlists or slow YouTube may cause a fallback to page mode.
# Example:
#   PLAYLIST_ALL_TIMEOUT_MS=35000


PLAYLIST_PAGE_TIMEOUT_MS=
# Timeout (in ms) for each paginated playlist fetch (e.g., 50 items per page).
# Example:
#   PLAYLIST_PAGE_TIMEOUT_MS=25000


PLAYLIST_META_TIMEOUT_MS=
# Timeout (in ms) for fetching playlist metadata (title, total item count, etc.).
# Example:
#   PLAYLIST_META_TIMEOUT_MS=30000


PLAYLIST_META_FALLBACK_TIMEOUT_MS=
# Timeout (in ms) for the fallback metadata attempt
# (e.g., "if full metadata fails, try using only the first item").
# Example:
#   PLAYLIST_META_FALLBACK_TIMEOUT_MS=20000


########################################
# yt-dlp Binary & Download Behavior
########################################

YTDLP_BIN=
# Absolute path to the yt-dlp executable.
# If left empty, the app may try to resolve it from PATH or built-in locations.
# Examples:
#   YTDLP_BIN=/usr/local/bin/yt-dlp
#   YTDLP_BIN=C:\\tools\\yt-dlp.exe


YTDLP_EXTRA=
# Extra yt-dlp arguments applied to all audio downloads
# (downloadSelectedIds, downloadSelectedIdsParallel, downloadStandard in audio mode).
# Space-separated string; each token becomes an argument.
# Example:
#   YTDLP_EXTRA=--some-yt-dlp-flag --another-flag=1


YTDLP_ARGS_EXTRA=
# Alternative name used when YTDLP_EXTRA is not defined.
# Priority order:
#   1) YTDLP_EXTRA
#   2) YTDLP_ARGS_EXTRA
#   3) no extra args
# Example:
#   YTDLP_ARGS_EXTRA=--some-yt-dlp-flag --another-flag=1


YTDLP_AUDIO_LIMIT_RATE=
# Rate limit for single-video audio downloads (not playlist mode).
# Passed as --limit-rate to yt-dlp.
# Examples:
#   YTDLP_AUDIO_LIMIT_RATE=500K
#   YTDLP_AUDIO_LIMIT_RATE=1M
#   YTDLP_AUDIO_LIMIT_RATE=2M


########################################
# Preview Cache
########################################

PREVIEW_CACHE_TTL_MS=
# Time-to-live (in ms) for playlist/automix preview results stored in memory.
# After this duration:
#   - getCache(url) treats the entry as expired,
#   - the record is removed,
#   - metadata/preview is fetched again.
# Example (30 minutes):
#   PREVIEW_CACHE_TTL_MS=1800000


########################################
# Upload Limits
########################################

UPLOAD_MAX_BYTES=
# Maximum allowed upload file size.
# Supported formats:
#   - pure number → treated as bytes          (e.g., 104857600)
#   - "<number>mb" → number * 1024 * 1024    (e.g., 100mb → ~104 MB)
# Used by multer as limits.fileSize.
# If invalid, the app logs a warning and falls back to ~1000 MB.
# Examples:
#   UPLOAD_MAX_BYTES=104857600
#   UPLOAD_MAX_BYTES=100mb


########################################
# Data Directories
########################################

DATA_DIR=
# Root directory for all application data.
# Typical structure:
#   DATA_DIR/outputs/       → exported / processed files
#   DATA_DIR/uploads/       → uploaded files / merged chunks
#   DATA_DIR/local-inputs/  → source directory for /api/local-files (if enabled)
# If empty, defaults to process.cwd() (the app’s working directory).
# Examples:
#   DATA_DIR=/var/lib/gharmonize
#   DATA_DIR=/home/youruser/gharmonize-data


LOCAL_INPUT_DIR=
# Relative directory under DATA_DIR for local file browsing.
# Resolved as: path.resolve(DATA_DIR || process.cwd(), LOCAL_INPUT_DIR)
# Used by:
#   - /api/local-files → recursively lists supported media
#   - /api/probe/local → only accepts files under this directory (security check)
# Default (when empty) is usually "local-inputs".
# Examples:
#   LOCAL_INPUT_DIR=local-inputs
#   LOCAL_INPUT_DIR=my-local-media


########################################
# Spotify API
########################################

SPOTIFY_CLIENT_ID=
# Spotify Web API client ID.
# Obtain from Spotify Developer Dashboard.
# Used when requesting access tokens.
# ❗ Do NOT commit real credentials to public repositories.


SPOTIFY_CLIENT_SECRET=
# Spotify Web API client secret.
# Used together with SPOTIFY_CLIENT_ID to obtain access tokens.
# ❗ Keep this secret. Never expose in logs, frontend, or public repos.


SPOTIFY_MARKET=
# Default market (country code) for Spotify API requests.
# Affects which tracks/albums are considered available.
# Examples:
#   SPOTIFY_MARKET=US
#   SPOTIFY_MARKET=FR
#   SPOTIFY_MARKET=DE


SPOTIFY_FALLBACK_MARKETS=
# Comma-separated list of fallback markets.
# Logic example:
#   - Try SPOTIFY_MARKET first
#   - If not available there, try these markets in order.
# Examples:
#   SPOTIFY_FALLBACK_MARKETS=US,GB,DE,FR


SPOTIFY_DEBUG_MARKET=
# Enable extra debug logging related to market selection and fallbacks.
#   1 → verbose logs (good for development)
#   0 → quiet (recommended for production)
# Example:
#   SPOTIFY_DEBUG_MARKET=1


PREFER_SPOTIFY_TAGS=
# When writing tags (ID3, etc.), prefer metadata coming from Spotify.
# Behavior:
#   1 → If both YouTube and Spotify metadata exist, favor Spotify’s cleaner data.
#   0 → Favor YouTube (or other resolvers).
# Example:
#   PREFER_SPOTIFY_TAGS=1

YT_SEARCH_RESULTS=
# Number of yt-dlp search results to fetch per query (ytsearchN).
# Lower = faster mapping, but slightly higher risk of a wrong match.
# Recommended: 2 (fast) / 3 (safer).

YT_SEARCH_TIMEOUT_MS=
# Per-search timeout in milliseconds for the mapping/search step.
# If a search hangs or YouTube is slow, it will abort after this time.
# Lower = snappier UI, but may cause more "not found" on slow networks.

YT_SEARCH_STAGGER_MS=
# Stagger delay (ms) applied when starting parallel searches.
# Helps avoid burst/throttle behavior by spacing out requests across concurrency slots.
# Lower = faster burst; higher = smoother and often fewer throttles/timeouts.
# Set to 0 to disable staggering.


########################################
# Title Cleaning
########################################

TITLE_CLEAN_PIPE=
# If set to 1, when a title contains the '|' character,
# the part AFTER the last '|' is kept.
# Example:
#   "Artist Name | Official Video" → "Official Video"
# This is applied before other CLEAN_* rules.
# Example:
#   TITLE_CLEAN_PIPE=1


CLEAN_SUFFIXES=
# Comma-separated list of suffix tokens to remove from the END of titles.
# Examples of matches:
#   "Song Name (Official)" → suffix "Official"
#   "Artist - Track (Topic)" → suffix "Topic"
# Example:
#   CLEAN_SUFFIXES=topic,official


CLEAN_PHRASES=
# Phrases to completely remove when they appear in title text.
# Typical usage:
#   "Song Name (Official Video)"     → remove "Official Video"
#   "Artist - Track [official channel]" → remove "official channel"
# Example:
#   CLEAN_PHRASES="official channel,Official Video"


CLEAN_PARENS=
# Words that, when found inside parentheses, cause that whole "(...)" segment to be removed.
# Examples:
#   "Song Name (official)" → remove "(official)"
#   "Song Name (topic)"    → remove "(topic)"
# Example:
#   CLEAN_PARENS=official,topic


########################################
# Authentication & App Secret
########################################

ADMIN_PASSWORD=
# Password for admin panel / protected endpoints.
# Keep this out of logs and public repositories.
# For production, use a long, random, strong password.
# Example:
#   ADMIN_PASSWORD=change_this_in_production


APP_SECRET=
# Global secret key for the application.
# May be used for JWT signing, session cookies, CSRF tokens, etc.
# Must be long, random, and kept private.
# Example (DO NOT reuse this exact string):
#   APP_SECRET=your_super_long_random_hex_or_base64_value


########################################
# Cookies & yt-dlp Cookie Behavior
########################################

YT_STRIP_COOKIES=
# Master switch that disables both YTDLP_COOKIES and YTDLP_COOKIES_FROM_BROWSER when set.
# Typical behavior:
#   1 → disable all cookie-based usage
#   0 → allow cookie configuration below to take effect
# Example:
#   YT_STRIP_COOKIES=0


YTDLP_COOKIES=
# Path to cookies.txt.
# If empty, a default "cookies" directory may be used as fallback.
# This is to keep the YouTube/Gharmonize interface behavior consistent and to allow downloading age-restricted (and similar) content.
# Examples:
#   YTDLP_COOKIES=./cookies/cookies.txt
#   YTDLP_COOKIES=/opt/gharmonize/cookies/cookies.txt


YTDLP_COOKIES_FROM_BROWSER=
# If cookies.txt is not present in the cookies directory,
# and this variable is set, yt-dlp may try to import cookies from the specified browser.
# You must be logged into YouTube on the same server/machine where Gharmonize is installed (in a supported browser profile).
# This is to keep the YouTube/Gharmonize interface behavior consistent and to allow downloading age-restricted (and similar) content.
# Examples:
#   YTDLP_COOKIES_FROM_BROWSER=chrome
#   YTDLP_COOKIES_FROM_BROWSER=firefox

YT_UI_FORCE_COOKIES=
# When YT_STRIP_COOKIES=1 is enabled, this setting is used to keep YouTube lists consistent between YouTube and the Gharmonize UI.
# This setting has no effect on downloads.
# Requires cookies.txt or YTDLP_COOKIES_FROM_BROWSER to work.
#
# Example usage:
#   YT_UI_FORCE_COOKIES=1  # enabled
#   YT_UI_FORCE_COOKIES=0  # disabled

########################################
# YouTube / yt-dlp Language & Region
########################################

YT_LANG=
# Primary UI language (locale) to emulate for YouTube requests.
# This affects:
#   • Suggested content
#   • Subtitle/metadata language
#   • Locale-based responses from YouTube
# Leave empty to let YouTube decide automatically.
# Example usage:
#   YT_LANG=en-US   # English (United States)
#   YT_LANG=de-DE   # German (Germany)


YT_FORCE_IPV4=
# Forces requests to be made over IPv4 when enabled.
# Example:
#   YT_FORCE_IPV4=1   # force IPv4
#   YT_FORCE_IPV4=0   # allow default behavior


YT_ACCEPT_LANGUAGE=
# Exact value for the HTTP "Accept-Language" header.
# Like a browser, you can specify priorities with q-values.
# This influences which language YouTube prefers for content/subtitles.
# Example:
#   YT_ACCEPT_LANGUAGE=en-US,en;q=0.9,fr;q=0.8


YT_DEFAULT_REGION=
# Region / country code (ISO 3166-1 alpha-2) used for geolocation-related behavior.
# Passed to yt-dlp as:
#   --geo-bypass-country=<code>
# Helps with region-locked videos, e.g. "pretend we are in US".
# Example:
#   YT_DEFAULT_REGION=US


ENRICH_SPOTIFY_FOR_YT=
# When converting YouTube videos, optionally enrich metadata using Spotify:
#   1 → enabled (pull extra info like genre, label, year, ISRC, etc. when possible)
#   0 → disabled (use YouTube + existing resolvers only)
# Example:
#   ENRICH_SPOTIFY_FOR_YT=1


YT_403_WORKAROUNDS=
# Toggle special handling for HTTP 403 Forbidden errors from YouTube.
#   0 = disabled
#   1 = enabled (recommended in many environments)
# Example:
#   YT_403_WORKAROUNDS=1


YT_USE_MUSIC=
# Controls whether downloads are made against youtube.com or music.youtube.com.
#   0 → normal youtube.com
#   1 → music.youtube.com (YouTube Music)
# Example:
#   YT_USE_MUSIC=1


YTDLP_UA=
# User-Agent string used by yt-dlp when talking to YouTube.
# A stable, commonly-used Chrome UA often works best.
# Example:
#   YTDLP_UA=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36


########################################
# Media Tagging / FFmpeg
########################################

MEDIA_COMMENT=
# Any text you place here will be written into the ID3 comment tag of generated files.
# Example:
#   MEDIA_COMMENT=Created with Gharmonize


FFMPEG_BIN=
# Path to the ffmpeg executable.
# If left empty, the app may attempt to find "ffmpeg" from PATH
# or use a downloaded binary if available.
# Examples:
#   FFMPEG_BIN=/usr/local/bin/ffmpeg
#   FFMPEG_BIN=C:\\ffmpeg\\bin\\ffmpeg.exe

Notes & Troubleshooting

  • yt-dlp not found → Install yt-dlp or use Docker image.
  • 403 / SABR issues → Adjust flags like --http-chunk-size, use cookies if needed.
  • Spotify personalized Mix not supported → Copy items to a normal playlist.
  • Uploads limit → 100MB max (configurable in app.js).

License

(MIT — Attribution • Fork-Only • Non-Commercial • Written Permission Required)

This project is licensed under the MIT License with mandatory attribution, fork-only redistribution, non-commercial usage restrictions, and written permission requirement for exceptions.


✔ Allowed

You are permitted to:

  • Use, copy, modify, and distribute this software for non-commercial purposes only.
  • Create derivative works.
  • Publish your changes only as a GitHub fork of the original repository.

🚫 Not Allowed

You are not permitted to:

  • Use this software or any modified version for commercial purposes.
  • Remove or alter copyright notices.
  • Remove attribution to the original author.
  • Re-upload, re-brand, or re-publish this project as a new repository.
  • Redistribute modified or unmodified copies outside of a public GitHub fork.
  • Bypass these restrictions without obtaining written permission from the original author.

✔ Redistribution Rules (Important)

If you redistribute this project (modified or unmodified):

  1. It must be done as a public GitHub fork. → Direct copy → new repo açmak → yayınlamak yasaktır.

  2. You must credit the original author: “Based on work by G-grbz”

  3. You must include a link to the original repository: https://github.com/G-grbz/Gharmonize

  4. You must clearly indicate modifications: “Modified by XYZ”

  5. You must obtain written permission from the original author (G-grbz) for:

    • Any commercial usage
    • Any redistribution outside of a GitHub fork
    • Any re-branding or re-publication under a new project name

These conditions cannot be removed, overridden, or ignored.


⚠ Disclaimer

This software is provided “as is”, without warranty of any kind. Use it at your own risk.


Third-Party Licenses

Gharmonize bundles several third-party command-line tools in its desktop and Docker builds:

  • FFmpeg / FFprobe

  • MKVToolNix tools:

    • mkvmerge
    • mkvextract
    • mkvinfo
    • mkvpropedit
  • yt-dlp

  • deno

These tools are not licensed under MIT. They keep their original licenses:

  • FFmpeg / FFprobe → GNU GPL/LGPL (depending on the specific build)
  • MKVToolNix tools → GNU General Public License v2 (GPLv2)
  • yt-dlp → The Unlicense (public domain)
  • deno → MIT License

Detailed license texts are included in the distributed builds under:

  • build/licenses/FFmpeg-LICENSE.txt
  • build/licenses/MKVToolNix-GPLv2.txt
  • build/licenses/yt-dlp-Unlicense.txt
  • build/licenses/Deno-LICENSE.txt

About

All-in-one media downloader and converter with Web UI, desktop builds, and powerful ffmpeg automation. Built on yt-dlp · Supports YouTube & Spotify sources · Self-hosted

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published