This API offers a range of endpoints for downloading YouTube videos, retrieving video information, and managing API keys. It is designed to be user-friendly while providing robust functionality for video processing and information retrieval. The API leverages yt-dlp to handle video downloads and information retrieval efficiently on a dedicated host.
- Running the Server
- Configuration
- Authentication
- Rate Limiting
- Endpoints
- Get Video (
/get_video) - Get Audio (
/get_audio) - Get Live Video (
/get_live_video) - Get Live Audio (
/get_live_audio) - Get Info (
/get_info) - Create API Key (
/create_key) - Delete API Key (
/delete_key/<name>) - List API Keys (
/get_keys) - Get API Key (
/get_key/<name>) - Get Task Status (
/status/<task_id>) - Get File (
/files/<path:filename>)
- Get Video (
- Error Handling
- Examples
To run the server, follow these steps:
-
Clone the repository:
git clone https://github.com/Vasysik/yt-dlp-host.git cd yt-dlp-host -
Build and run the Docker container:
docker-compose up --build -
The server will be accessible at
http://localhost:5000.
The server's configuration is defined in the config.py file. Here are the default values:
DOWNLOAD_DIR: The directory where downloaded files will be stored. Default is'/app/downloads'.TASKS_FILE: The path to the JSON file that stores task information. Default is'jsons/tasks.json'.KEYS_FILE: The path to the JSON file that stores API keys and their permissions. Default is'jsons/api_keys.json'.CLEANUP_TIME_MINUTES: The time (in minutes) after which completed tasks will be removed. Default is10.REQUEST_LIMIT: The maximum number of requests allowed within theCLEANUP_TIME_MINUTESperiod. Default is60.MAX_WORKERS: The maximum number of concurrent workers for processing tasks. Default is4.DEFAULT_QUOTA_GB: Default memory quota for new API keys in GB. Default is5.QUOTA_RATE_MINUTES: Time window for quota calculation in minutes. Default is10.AVAILABLE_BYTES: Total available memory for all users in bytes. Default is20GB.
All requests to the API must include an API key in the X-API-Key header. To obtain an API key, contact the API administrator or use the /create_key endpoint if you have create_key permissions.
The API implements rate limiting to prevent abuse. Each API key is limited to 60 requests within a 10 minute window. Additionally, memory quotas are enforced to prevent excessive storage usage.
Initiates a video download task from the specified URL.
- Method: POST
- URL:
/get_video - Headers:
X-API-Key: Your API keyContent-Type: application/json
- Body:
{ "url": "https://youtu.be/1FPdtR_5KFo", "video_format": "bestvideo[height<=1080]", "audio_format": "bestaudio[abr<=129]", "output_format": "mp4", "start_time": "00:00:30", "end_time": "00:01:00", "force_keyframes": false } - Parameters:
url(required): The URL of the video to be downloaded.video_format(optional): The format of the video. Default is "bestvideo".audio_format(optional): The format of the audio. Default is "bestaudio". To download video without audio, set this tonullornone.output_format(optional): The output container format (mp4, mkv, webm, etc.). Default is "mp4".start_time(optional): Starting point for video fragment in HH:MM:SS format or seconds as number.end_time(optional): Ending point for video fragment in HH:MM:SS format or seconds as number.force_keyframes(optional): If true, ensures precise cutting but slower processing. If false, faster but less precise cutting. Default is false.
- Permissions: Requires the
get_videopermission. - Response:
{ "status": "waiting", "task_id": "abcdefgh12345678" }
Initiates an audio download task from the specified URL.
- Method: POST
- URL:
/get_audio - Headers:
X-API-Key: Your API keyContent-Type: application/json
- Body:
{ "url": "https://youtu.be/1FPdtR_5KFo", "audio_format": "bestaudio[abr<=129]", "output_format": "mp3", "start_time": "00:00:30", "end_time": "00:01:00", "force_keyframes": false } - Parameters:
url(required): The URL of the audio to be downloaded.audio_format(optional): The format of the audio. Default is "bestaudio".output_format(optional): The output audio format (mp3, m4a, opus, etc.). Default is original format.start_time(optional): Starting point for audio fragment in HH:MM:SS format or seconds as number.end_time(optional): Ending point for audio fragment in HH:MM:SS format or seconds as number.force_keyframes(optional): If true, ensures precise cutting but slower processing. If false, faster but less precise cutting. Default is false.
- Permissions: Requires the
get_audiopermission. - Response:
{ "status": "waiting", "task_id": "abcdefgh12345678" }
Initiates a live video download task from the specified URL.
- Method: POST
- URL:
/get_live_video - Headers:
X-API-Key: Your API keyContent-Type: application/json
- Body:
{ "url": "https://youtu.be/1FPdtR_5KFo", "start": 0, "duration": 300, "video_format": "bestvideo[height<=1080]", "audio_format": "bestaudio[abr<=129]", "output_format": "mp4" } - Parameters:
url(required): The URL of the live stream to be downloaded.start(optional): The starting point in seconds for the stream recording. Default is 0.duration(required): The length of the recording in seconds from the start point.video_format(optional): The format of the video. Default is "bestvideo".audio_format(optional): The format of the audio. Default is "bestaudio".output_format(optional): The output container format (mp4, mkv, webm, etc.). Default is "mp4".
- Permissions: Requires the
get_live_videopermission. - Response:
{ "status": "waiting", "task_id": "abcdefgh12345678" }
Initiates a live audio download task from the specified URL.
- Method: POST
- URL:
/get_live_audio - Headers:
X-API-Key: Your API keyContent-Type: application/json
- Body:
{ "url": "https://youtu.be/1FPdtR_5KFo", "audio_format": "bestaudio[abr<=129]", "output_format": "mp3", "start": 0, "duration": 300 } - Parameters:
url(required): The URL of the live stream to be downloaded.audio_format(optional): The format of the audio. Default is "bestaudio".output_format(optional): The output audio format (mp3, m4a, opus, etc.). Default is original format.start(optional): The starting point in seconds for the stream recording. Default is 0.duration(required): The length of the recording in seconds from the start point.
- Permissions: Requires the
get_live_audiopermission. - Response:
{ "status": "waiting", "task_id": "abcdefgh12345678" }
Retrieves information about the video from the specified URL.
- Method: POST
- URL:
/get_info - Headers:
X-API-Key: Your API keyContent-Type: application/json
- Body:
{ "url": "https://youtu.be/1FPdtR_5KFo" } - Parameters:
url(required): The URL of the video to retrieve information about.
- Permissions: Requires the
get_infopermission. - Response:
{ "status": "waiting", "task_id": "ijklmnop87654321" }
Creates a new API key with the specified permissions.
- Method: POST
- URL:
/create_key - Headers:
X-API-Key: Your admin API keyContent-Type: application/json
- Body:
{ "name": "user_key", "permissions": ["get_video", "get_audio", "get_live_video", "get_live_audio", "get_info"] } - Parameters:
name(required): The name for the new API key.permissions(required): A list of permissions for the new API key.
- Permissions: Requires the
create_keypermission. - Response:
{ "message": "API key created successfully", "key": "new_api_key_here", "name": "user_key" }
Deletes an existing API key by its name.
- Method: DELETE
- URL:
/delete_key/<name> - Headers:
X-API-Key: Your admin API key
- Permissions: Requires the
delete_keypermission. - Response:
{ "name": "user_key", "message": "API key deleted successfully" }
Retrieves a list of all existing API keys.
- Method: GET
- URL:
/get_keys - Headers:
X-API-Key: Your admin API key
- Permissions: Requires the
get_keyspermission. - Response:
{ "admin": { "key": "admin_api_key_here", "permissions": ["create_key", "delete_key", "get_key", "get_keys", "get_video", "get_audio", "get_live_video", "get_live_audio", "get_info"], "memory_quota": 5368709120, "memory_usage": [], "last_access": "2024-01-01T12:00:00" }, "user_key": { "key": "user_api_key_here", "permissions": ["get_video", "get_audio", "get_live_video", "get_live_audio", "get_info"], "memory_quota": 5368709120, "memory_usage": [], "last_access": "2024-01-01T12:00:00" } }
Gets an existing API key by its name.
- Method: GET
- URL:
/get_key/<name> - Headers:
X-API-Key: Your admin API key
- Permissions: Requires the
get_keypermission. - Response:
{ "name": "user_key", "key": "user_api_key_here" }
Checks if the current API key has the specified permissions.
- Method: POST
- URL:
/check_permissions - Headers:
X-API-Key: Your API keyContent-Type: application/json
- Body:
{ "permissions": ["get_video", "get_audio"] } - Response:
- Success (200):
{ "message": "Permissions granted" } - Insufficient permissions (403):
{ "message": "Insufficient permissions" }
- Success (200):
Retrieves the status of a specific task by its ID.
- Method: GET
- URL:
/status/<task_id> - Headers:
X-API-Key: Your API key
- Permissions: No specific permission required, but the task must be associated with the API key used.
- Response:
{ "key_name": "user_key", "status": "completed", "task_type": "get_video", "url": "https://youtu.be/1FPdtR_5KFo", "video_format": "bestvideo[height<=1080]", "audio_format": "bestaudio[abr<=129]", "output_format": "mp4", "completed_time": "2024-01-01T12:00:00", "file": "/files/abcdefgh12345678/video.mp4" }
Retrieves a file from the server.
- Method: GET
- URL:
/files/<path:filename> - Query Parameters:
raw(optional): If set to "true", forces download of the file.- Any parameter matching keys in the
info.jsonfile (for info.json files only). qualities: Returns a structured list of available video and audio qualities formats (for info.json files only).
- Response:
- For regular files: The file content with appropriate headers.
- For
info.jsonfiles:- If no query parameters: Full content of the
info.jsonfile. - If query parameters present: Filtered data based on the parameters.
- For
qualitiesparameter:{ "qualities": { "audio": { "249": { "abr": 47, "acodec": "opus", "audio_channels": 2, "filesize": 528993 }, "139": { "abr": 48, "acodec": "mp4a.40.5", "audio_channels": 2, "filesize": 549935 } }, "video": { "394": { "height": 144, "width": 256, "fps": 25, "vcodec": "av01.0.00M.08", "format_note": "144p", "dynamic_range": "SDR", "filesize": 1009634 }, "134": { "height": 360, "width": 640, "fps": 25, "vcodec": "avc1.4D401E", "format_note": "360p", "dynamic_range": "SDR", "filesize": 6648273 } } } }
- If no query parameters: Full content of the
The API uses standard HTTP status codes to indicate the success or failure of requests. In case of an error, the response will include a JSON object with an error field describing the issue.
Example error response:
{
"error": "Invalid API key"
}Common error codes:
- 400: Bad Request - Invalid request parameters
- 401: Unauthorized - Invalid or missing API key
- 403: Forbidden - Insufficient permissions
- 404: Not Found - Resource not found
- 429: Too Many Requests - Rate limit exceeded
- 500: Internal Server Error - Server-side error
import requests
api_key = "your_api_key_here"
base_url = "http://localhost:5000"
headers = {
"X-API-Key": api_key,
"Content-Type": "application/json"
}
data = {
"url": "https://youtu.be/1FPdtR_5KFo",
"video_format": "bestvideo[height<=1080]",
"audio_format": "bestaudio[abr<=129]",
"output_format": "mp4"
}
response = requests.post(f"{base_url}/get_video", json=data, headers=headers)
print(response.json())import requests
api_key = "your_api_key_here"
base_url = "http://localhost:5000"
headers = {
"X-API-Key": api_key,
"Content-Type": "application/json"
}
data = {
"url": "https://youtu.be/1FPdtR_5KFo",
"audio_format": "bestaudio",
"output_format": "mp3"
}
response = requests.post(f"{base_url}/get_audio", json=data, headers=headers)
print(response.json())import requests
api_key = "your_api_key_here"
base_url = "http://localhost:5000"
headers = {
"X-API-Key": api_key,
"Content-Type": "application/json"
}
data = {
"url": "https://youtu.be/1FPdtR_5KFo",
"video_format": "bestvideo[height<=720]",
"audio_format": "bestaudio",
"output_format": "webm",
"start_time": "00:00:30",
"end_time": "00:01:30",
"force_keyframes": True
}
response = requests.post(f"{base_url}/get_video", json=data, headers=headers)
print(response.json())import requests
import time
api_key = "your_api_key_here"
base_url = "http://localhost:5000"
task_id = "abcdefgh12345678"
headers = {
"X-API-Key": api_key
}
# Check status
while True:
response = requests.get(f"{base_url}/status/{task_id}", headers=headers)
status_data = response.json()
if status_data['status'] == 'completed':
file_url = base_url + status_data['file']
# Download the file
file_response = requests.get(file_url, headers=headers)
with open('downloaded_video.mp4', 'wb') as f:
f.write(file_response.content)
print("Download completed!")
break
elif status_data['status'] == 'error':
print(f"Error: {status_data.get('error', 'Unknown error')}")
break
else:
print(f"Status: {status_data['status']}")
time.sleep(2)import requests
api_key = "your_api_key_here"
base_url = "http://localhost:5000"
headers = {
"X-API-Key": api_key,
"Content-Type": "application/json"
}
# Start info task
data = {"url": "https://youtu.be/1FPdtR_5KFo"}
response = requests.post(f"{base_url}/get_info", json=data, headers=headers)
task_id = response.json()['task_id']
# Wait for completion and get info
time.sleep(2)
status_response = requests.get(f"{base_url}/status/{task_id}", headers=headers)
if status_response.json()['status'] == 'completed':
info_url = base_url + status_response.json()['file']
# Get full info
info = requests.get(info_url, headers=headers).json()
# Get only qualities
qualities = requests.get(f"{info_url}?qualities", headers=headers).json()
print(qualities)- mp4 - MPEG-4 Part 14 (recommended)
- mkv - Matroska
- webm - WebM
- mp3 - MPEG Audio Layer III
- m4a - MPEG-4 Audio
- opus - Opus Audio
- aac - Advanced Audio Coding
Contributions to yt-dlp-host are welcome! If you have any suggestions, bug reports, or feature requests, please open an issue on the GitHub repository. Pull requests are also encouraged.
This project is licensed under the MIT License. See the LICENSE file for details.