🚀 FastAPI、Redis、PostgreSQL、Docker で構築された高機能ビデオ/オーディオダウンロード API
日本語版。このプロジェクトは yt-dlp を活用した、プロダクション対応の非同期ダウンロードシステムです。
- ✅ 複数フォーマット対応: MP3、MP4、WebM、WAV、FLAC、AAC、高品質、音声のみ、映像のみ
- ✅ 非同期処理:
asyncio.create_subprocess_execによる非ブロッキングダウンロード - ✅ リアルタイム進捗追跡: WebSocket またはポーリング API での進捗確認
- ✅ キュー管理: Redis を活用した同時ダウンロード数の制限
- ✅ レート制限: IP ベースのレート制限(
.envで設定可能) - ✅ 自動クリーンアップ: 古い完了タスクの自動削除
- ✅ MP3 タグ編集: MP3 ファイルへのタイトルとサムネイル埋め込み
- ✅ タスク キャンセル: 実行中のダウンロードを停止
- ✅ 字幕ダウンロード: 複数言語での字幕抽出
- ✅ ビデオ情報 API: ダウンロードなしでメタデータ取得
- ✅ GPU エンコーディング対応: NVENC / Intel QSV / VAAPI ハードウェアアクセラレーション
- ✅ aria2 統合: 高速外部ダウンローダー対応
- ✅ Deno JavaScript ランタイム: yt-dlp-ejs と Deno による拡張 JS エンジン対応
| コンポーネント | 説明 |
|---|---|
| バックエンド | FastAPI(非同期フレームワーク) |
| データベース | PostgreSQL(タスク永続化) |
| キャッシュ/キュー | Redis(レート制限、キュー管理) |
| ダウンローダー | yt-dlp + ffmpeg / GPU + aria2 |
| コンテナ化 | Docker + Docker Compose |
ytdlp-api/
├── app/ # FastAPI アプリケーション
│ ├── main.py # FastAPI の初期化とルータ登録
│ ├── endpoints.py # ダウンロード関連エンドポイント
│ ├── auth_endpoints.py # 認証・API キー管理エンドポイント
│ ├── progress_endpoints.py # 進捗追跡エンドポイント
│ ├── metrics_endpoints.py # メトリクス・統計エンドポイント
│ ├── performance_endpoints.py # パフォーマンスモニタリング
│ ├── error_responses.py # エラーハンドリング
│ ├── models.py # Pydantic モデル定義
│ └── routes/ # ルータ定義
├── core/ # コア機能
│ ├── config.py # 環境変数と設定管理
│ └── ... # その他のコア機能
├── services/ # ビジネスロジック層
│ ├── download_service.py # ダウンロード処理
│ ├── queue_service.py # キュー管理
│ └── ... # その他のサービス
├── infrastructure/ # インフラストラクチャ
│ ├── database.py # データベース接続
│ ├── redis.py # Redis クライアント
│ └── ... # その他のインフラ
├── examples/ # 使用例とクライアント実装
├── wiki/ # ドキュメンテーション
├── main.py # エントリーポイント
├── requirements.txt # Python 依存パッケージ
├── Dockerfile # Docker イメージ定義
├── docker-compose.yml # Docker Compose 設定
├── .env.example # 環境変数テンプレート
└── README.md # このファイル
- Docker と Docker Compose
- または Python 3.10+、PostgreSQL、Redis
- リポジトリをクローン
git clone https://github.com/yunfie-twitter/ytdlp-api.git
cd ytdlp-api- 環境変数を設定
cp .env.example .env
# .env ファイルを編集して必要な設定を行う- Docker Compose で起動
docker-compose up -d- API にアクセス
http://localhost:8000
Swagger UI ドキュメント: http://localhost:8000/docs
- Python 依存パッケージをインストール
pip install -r requirements.txt- Redis と PostgreSQL を起動
# Redis
redis-server
# PostgreSQL(別ターミナル)
# インストール済みの PostgreSQL サーバーを起動- .env ファイルを設定
cp .env.example .env
# 開発環境に合わせて編集- API を起動
python main.pyHOST=0.0.0.0 # バインドするホスト
PORT=8000 # バインドするポート
RELOAD=false # 開発時に true で自動リロードCORS_ORIGINS=http://localhost:3000,http://localhost:8000# SQLite(開発用)
DATABASE_URL=sqlite:///./download_tasks.db
# PostgreSQL(本番用)
DATABASE_URL=postgresql://user:password@localhost:5432/ytdlp_apiREDIS_URL=redis://localhost:6379DOWNLOAD_DIR=./downloads # ダウンロード保存先
MAX_CONCURRENT_DOWNLOADS=3 # 同時ダウンロード数
AUTO_DELETE_AFTER=604800 # 自動削除間隔(秒、デフォルト 7 日)RATE_LIMIT_PER_MINUTE=60 # 1分あたりのリクエスト数制限SECRET_KEY=your-secret-key-change-in-productionGET /api/video-info?url={video_url}動画のメタデータをダウンロードなしで取得します。
クエリパラメータ:
url(required): 動画の URLlanguage(optional): 字幕言語(例: ja, en)
レスポンス例:
{
"url": "https://example.com/video",
"title": "動画タイトル",
"duration": 3600,
"thumbnail": "https://example.com/thumb.jpg",
"formats": [
{"format_id": "18", "format": "video/mp4", "resolution": "360p"},
{"format_id": "22", "format": "video/mp4", "resolution": "720p"}
]
}POST /api/download新しいダウンロードタスクを作成します。
リクエストボディ:
{
"url": "https://www.youtube.com/watch?v=...",
"format": "mp3",
"quality": "best",
"include_subtitles": true,
"subtitle_languages": ["ja", "en"],
"custom_format_id": null,
"embed_metadata": true,
"embed_thumbnail": true
}パラメータ説明:
url(required): ダウンロード対象の URLformat(optional):mp3,mp4,webm,wav,flac,aac,audio_only,video_only、デフォルト:mp3quality(optional):best,audio_best、デフォルト:bestinclude_subtitles(optional): 字幕を含めるか、デフォルト:falsesubtitle_languages(optional): 字幕言語リスト、デフォルト:["auto"]custom_format_id(optional): yt-dlp のカスタム format_idembed_metadata(optional): MP3 にメタデータを埋め込むか、デフォルト:trueembed_thumbnail(optional): サムネイルを埋め込むか、デフォルト:true
レスポンス:
{
"task_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"status": "queued",
"created_at": "2024-01-15T10:30:00Z",
"estimated_duration": "00:05:30"
}GET /api/status/{task_id}レスポンス:
{
"task_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
"status": "downloading",
"progress": {
"percentage": 45.5,
"downloaded_bytes": 45000000,
"total_bytes": 100000000,
"speed": 1000000,
"eta": "00:01:30"
},
"filename": "video_title.mp3",
"created_at": "2024-01-15T10:30:00Z"
}WS /ws/progress/{task_id}
WebSocket で接続するとリアルタイム進捗情報が配信されます。
GET /api/download/{task_id}完了したタスクのファイルをダウンロード。
POST /api/cancel/{task_id}実行中のダウンロードをキャンセルします。
DELETE /api/delete/{task_id}タスクと関連ファイルを削除します。
GET /api/tasks?status=completed&limit=20&offset=0すべてのタスクを一覧表示します。
クエリパラメータ:
status(optional):queued,downloading,completed,failed,cancelledlimit(optional): 1 ページあたりのアイテム数、デフォルト: 20offset(optional): オフセット、デフォルト: 0
GET /api/queue/statsレスポンス:
{
"queued": 5,
"downloading": 2,
"completed": 150,
"failed": 3,
"total_completed_today": 45,
"average_speed": 2500000,
"estimated_wait_time": "00:15:30"
}GET /api/metrics/performanceCPU、メモリ、ディスク使用率などのメトリクスを取得。
.env で以下を設定:
ENABLE_JWT_AUTH=true
API_KEY_ISSUE_PASSWORD=your-secure-password
JWT_ALGORITHM=HS256
JWT_EXPIRATION_DAYS=30POST /auth/issue-keyリクエストボディ:
{
"password": "your-secure-password"
}レスポンス:
{
"api_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": "2024-02-14T10:30:00Z"
}すべてのリクエストの Authorization ヘッダーに含めます:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...または、クエリパラメータ:
GET /api/status/task_id?api_key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...POST /auth/toggle-key/{key_id}GET /auth/keys.env で個別機能の有効化・無効化が可能です:
# ビデオ情報エンドポイント
ENABLE_FEATURE_VIDEO_INFO=true
# ダウンロードエンドポイント
ENABLE_FEATURE_DOWNLOAD=true
# ステータス確認エンドポイント
ENABLE_FEATURE_STATUS=true
# ファイルダウンロードエンドポイント
ENABLE_FEATURE_FILE_DOWNLOAD=true
# タスクキャンセル
ENABLE_FEATURE_CANCEL=true
# タスク削除
ENABLE_FEATURE_DELETE=true
# タスク一覧表示
ENABLE_FEATURE_LIST_TASKS=true
# 字幕ダウンロード
ENABLE_FEATURE_SUBTITLES=true
# サムネイル取得
ENABLE_FEATURE_THUMBNAIL=true
# キュー統計
ENABLE_FEATURE_QUEUE_STATS=true
# WebSocket サポート
ENABLE_FEATURE_WEBSOCKET=true
# MP3 メタデータ埋め込み
ENABLE_FEATURE_MP3_METADATA=true
# サムネイル埋め込み
ENABLE_FEATURE_THUMBNAIL_EMBED=true
# GPU エンコーディング
ENABLE_FEATURE_GPU_ENCODING=true
# aria2 ダウンローダー
ENABLE_FEATURE_ARIA2=true
# カスタムフォーマット選択
ENABLE_FEATURE_CUSTOM_FORMAT=true
# 画質選択
ENABLE_FEATURE_QUALITY_SELECTION=true
# プロキシサポート
ENABLE_FEATURE_PROXY=true
# Cookie サポート
ENABLE_FEATURE_COOKIES=true不要な機能を無効化することで、攻撃面を減らせます。
ビデオをハードウェアアクセラレーションでエンコードし、CPU 使用率を大幅削減します。
ENABLE_GPU_ENCODING=true
GPU_ENCODER_TYPE=auto # auto / nvenc / vaapi / qsv
GPU_ENCODER_PRESET=fast # ultrafast / superfast / veryfast / faster / fast / medium / slow / slower| エンコーダー | 対応 GPU |
|---|---|
| nvenc | NVIDIA(GeForce RTX など) |
| vaapi | AMD、Intel 統合 GPU |
| qsv | Intel Quick Sync Video |
| auto | 自動検出 |
# リクエスト時にパラメータで指定
POST /api/download
{
"url": "https://youtube.com/...",
"format": "mp4",
"use_gpu_encoding": true
}大規模ファイルを高速ダウンロードするため、aria2 統合が利用可能です。
aria2c がインストールされていること:
# Ubuntu/Debian
sudo apt-get install aria2
# macOS
brew install aria2
# Docker イメージには自動的に含まれますENABLE_ARIA2=true
ARIA2_MAX_CONNECTIONS=4 # 並列接続数(推奨: 4-8)
ARIA2_SPLIT=4 # 同時分割ダウンロード数(推奨: 4)- 高速化: 複数接続による並列ダウンロード
- 低レイテンシ: 効率的な帯域幅利用
- レジューム機能: 中断したダウンロードを再開
yt-dlp-ejs を使用した拡張 JavaScript エンジンで、複雑なサイト対応を実現。
ENABLE_DENO=true
DENO_PATH=/usr/local/bin/deno # Deno のパス(デフォルト値)# Linux/macOS
curl -fsSL https://deno.land/install.sh | sh
# Docker イメージには自動的に含まれます- JavaScript 互換性向上: yt-dlp-ejs で拡張サイト対応
- エラー耐性: Deno の強い型チェック
- 安全性: サンドボックス化された実行環境
同時ダウンロード数は MAX_CONCURRENT_DOWNLOADS で制限されます。
MAX_CONCURRENT_DOWNLOADS=3超過分は Redis キューで管理され、順番に処理されます。
古い完了タスクは自動削除されます:
AUTO_DELETE_AFTER=604800 # 7 日(秒単位)すべてのタスクは PostgreSQL に永続化され、サーバー再起動後も復旧可能です。
docker build -t ytdlp-api .
docker run -d \
-p 8000:8000 \
-v ./downloads:/app/downloads \
-e DATABASE_URL=sqlite:///./download_tasks.db \
ytdlp-apidocker-compose up -ddocker-compose.yml の例:
version: '3.8'
services:
api:
build: .
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://user:password@postgres:5432/ytdlp
REDIS_URL: redis://redis:6379
volumes:
- ./downloads:/app/downloads
depends_on:
- postgres
- redis
postgres:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: ytdlp
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:- SECRET_KEY を変更
SECRET_KEY=$(openssl rand -hex 32)- CORS_ORIGINS を制限
CORS_ORIGINS=https://yourdomain.com- API キーを有効化
ENABLE_JWT_AUTH=true
API_KEY_ISSUE_PASSWORD=your-secure-password- 不要な機能を無効化
セキュリティのため、不要な機能フラグを false に設定。
- ログレベルを設定
LOG_LEVEL=info # debug / info / warning / erroryt-dlp に対応したすべてのサイトでダウンロード可能です。
主要サイト:
- YouTube
- Bilibili
- Twitter/X
- TikTok
- Vimeo
- Dailymotion
- 他数百のサイト
完全なサポートサイト一覧は公式ドキュメントを参照。
このプロジェクトは Apache 2.0 ライセンスの下で公開されています。
詳細は LICENSE ファイルを参照してください。
問題や機能リクエストは GitHub Issues で報告してください。