Simple Web and REST interface for downloading youtube videos onto a server.
starlette +
yt-dlp / youtube-dl
Forked from manbearwiz/youtube-dl-server.
For easier deployment, a docker image is available on dockerhub:
nbr23/youtube-dl-server:yt-dlpor simplynbr23/youtube-dl-serverto useyt-dlpnbr23/youtube-dl-server:youtube-dlto useyoutube-dl. Note that the latest release ofyoutube-dlis pretty outdated.
This example uses the docker run command to create the container to run the
app. Note the -v argument to specify the volume and its binding on the host.
This directory will be used to output the resulting videos.
docker run -d --name youtube-dl -p 8080:8080 -v $HOME/youtube-dl:/youtube-dl nbr23/youtube-dl-server:latestOR for yt-dlp:
docker run -d --name youtube-dl -p 8080:8080 -v $HOME/youtube-dl:/youtube-dl nbr23/youtube-dl-server:yt-dlpThis is an example service definition that could be put in docker-compose.yml.
youtube-dl:
image: "nbr23/youtube-dl-server:latest"
volumes:
- $HOME/youtube-dl:/youtube-dl
- ./config.yml:/app_config/config.yml:ro # Overwrite the container's config file with your own configuration
ports:
- 8080:8080
restart: alwaysConfiguration is done through the config.yml file at the root of the project.
An alternate configuration path or file path can be forced by setting the environment
variable YDL_CONFIG_PATH:
export YDL_CONFIG_PATH=/var/local/youtube-dl-server/config.ymlIn the above case, if /var/local/youtube-dl-server/config.yml does not exist, it will be created with the default options.
export YDL_CONFIG_PATH=/var/local/youtube-dl-server/In the above case, if /var/local/youtube-dl-server/config.yml does not exist, it will be created with the default options as well.
| Key | Default | Description |
|---|---|---|
port |
8080 |
Port to listen on |
host |
0.0.0.0 |
IP to bind to |
metadata_db_path |
/youtube-dl/.ydl-metadata.db |
Path to the SQLite job database |
output_playlist |
/youtube-dl/%(playlist_title)s [%(playlist_id)s]/%(title)s.%(ext)s |
Output template for playlists and multi-URL jobs |
max_log_entries |
100 |
Maximum number of job history entries to keep |
default_format |
video/best |
Default format pre-selected in the UI |
download_workers_count |
2 |
Number of parallel download worker threads |
forwarded_allow_ips |
None |
Comma-separated list of IPs to trust proxy headers from (passed to uvicorn) |
proxy_headers |
True |
Trust X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port headers (passed to uvicorn) |
debug |
False |
Enable debug mode |
Minimum required configuration:
ydl_server:
port: 8080
host: 0.0.0.0
metadata_db_path: '/youtube-dl/.ydl-metadata.db'
ydl_options:
output: '/youtube-dl/%(title)s [%(id)s].%(ext)s'
cache-dir: '/youtube-dl/.cache'Additional yt-dlp/youtube-dl parameters can be set in the ydl_options section. Add
parameters by removing the leading -- from the flag name.
For example, to write subtitles in spanish, the yt-dlp command would be:
yt-dlp --write-sub --sub-lang es URL
Which translates to:
ydl_options:
output: '/youtube-dl/%(title)s [%(id)s].%(ext)s'
cache-dir: '/youtube-dl/.cache'
write-sub: True
sub-lang: esProfiles are named configuration sets selectable in the UI. Each profile can
override any ydl_options.
profiles:
podcast:
name: 'Audio Podcasts'
ydl_options:
output: '/youtube-dl/Podcast/%(title)s [%(id)s].%(ext)s'
format: bestaudio/best
write-thumbnail: True
embed-thumbnail: True
add-metadata: True
audio-quality: 0
extract-audio: True
audio-format: mp3
philosophy_lectures:
name: 'Philosophy Lectures'
ydl_options:
output: '/youtube-dl/Lectures/Philosophy/%(title)s [%(id)s].%(ext)s'
write-thumbnail: True
embed-thumbnail: True
add-metadata: True
verbose: TrueRequires Python ^3.8.
Install dependencies:
pip install -r requirements.txtBuild the frontend:
cd front && npm install && npm run buildRun the server:
python3 -u ./youtube-dl-server.pyTo force a specific yt-dlp/youtube-dl fork, set the YOUTUBE_DL environment variable:
YOUTUBE_DL=yt-dlp python3 -u ./youtube-dl-server.pyThe following environment variables are used for version display in the UI:
| Variable | Description |
|---|---|
YOUTUBE_DL |
The yt-dlp/youtube-dl module to use (yt-dlp, youtube-dl) |
YDLS_VERSION |
Version string shown in the server info endpoint |
YDLS_RELEASE_DATE |
Release date string shown in the server info endpoint |
Navigate to http://{{host}}:8080/ and enter the URL to download.
curl -X POST \
-H 'Content-Type: application/json' \
--data-raw '{"url": "{{URL}}", "format": "video/best"}' \
http://{{host}}:8080/api/downloadsAccepted body fields:
| Field | Type | Description |
|---|---|---|
url |
string | Single URL to download |
urls |
array | Multiple URLs to download as one job |
format |
string | Format string (see formats below) |
profile |
string | Profile name from config |
audio_format |
string | Audio format (e.g. mp3, aac) |
force_generic_extractor |
bool | Force use of the generic extractor |
extra_params |
object | Extra parameters; title key overrides the output filename |
Available format values:
| Value | Description |
|---|---|
video/best |
Best video+audio (default) |
video/bestvideo |
Best video quality |
video/mp4 |
MP4 |
video/webm |
WebM |
video/mkv |
Matroska |
video/avi |
AVI |
video/flv |
Flash Video |
video/ogg |
Ogg |
bestaudio/best |
Best audio |
audio/mp3 |
MP3 |
audio/aac |
AAC |
audio/flac |
FLAC |
audio/m4a |
M4A |
audio/opus |
Opus |
audio/vorbis |
Vorbis |
audio/wav |
WAV |
curl http://{{host}}:8080/api/downloadsQuery parameters:
| Parameter | Description |
|---|---|
status |
Filter by status: Running, Completed, Failed, Pending, Aborted |
show_logs |
Include log output in response, 1 (default) or 0 |
curl http://{{host}}:8080/api/downloads/statsRemoves completed and failed entries beyond max_log_entries:
curl -X POST http://{{host}}:8080/api/downloads/cleancurl -X DELETE http://{{host}}:8080/api/downloadscurl -X POST \
-H 'Content-Type: application/json' \
--data-raw '{"url": "{{URL}}"}' \
http://{{host}}:8080/api/metadatacurl -X POST http://{{host}}:8080/api/jobs/{{job_id}}/stopcurl -X POST http://{{host}}:8080/api/jobs/{{job_id}}/retrycurl -X DELETE http://{{host}}:8080/api/jobs/{{job_id}}curl http://{{host}}:8080/api/finishedcurl -X DELETE http://{{host}}:8080/api/finished/{{filename}}curl http://{{host}}:8080/api/infocurl http://{{host}}:8080/api/formatscurl http://{{host}}:8080/api/extractorsAdd the following bookmarklet to your bookmark bar to send the current page URL to your youtube-dl-server instance.
If your youtube-dl-server is served through HTTPS (behind a reverse proxy handling HTTPS for example), you can use the following bookmarklet:
javascript:fetch("https://${host}/api/downloads",{body:JSON.stringify({url:window.location.href,format:"video/best"}),method:"POST",headers:{'Content-Type':'application/json'}});If you are hosting it without HTTPS, the previous bookmarklet will likely be blocked by your browser (mixed content when used on HTTPS sites).
Instead, you can use the following bookmarklet:
javascript:(function(){document.body.innerHTML += '<form name="ydl_form" method="POST" action="http://${host}/api/downloads"><input name="url" type="url" value="'+window.location.href+'"/></form>';document.ydl_form.submit()})();ffmpeg is required for format conversion and audio extraction in some
scenarios.
- ansible-role-youtubedl-server
- ytdl-k8s -
youtube-dl-serverHelm chart (usesyoutube-dl-serverimage for kubernetes deployment) - starlette
- youtube-dl
- yt-dlp


