yt-dl/app.py

101 lines
2.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask import Flask, render_template, request, jsonify
import yt_dlp
import os
import threading
app = Flask(__name__)
DOWNLOAD_DIR = os.path.join(os.path.dirname(__file__), "downloads")
os.makedirs(DOWNLOAD_DIR, exist_ok=True)
download_status = {}
def do_download(task_id, url, artist, title, album):
try:
download_status[task_id] = {"status": "running", "message": "Download läuft..."}
ydl_opts = {
"format": "bestaudio/best",
"outtmpl": os.path.join(DOWNLOAD_DIR, "%(title)s.%(ext)s"),
"postprocessors": [
{
"key": "FFmpegExtractAudio",
"preferredcodec": "mp3",
"preferredquality": "192",
},
{
"key": "FFmpegMetadata",
"add_metadata": True,
},
],
# Scoped to FFmpegMetadata so tags are set correctly
"postprocessor_args": {
"ffmpegmetadata": [
"-metadata", f"artist={artist}",
"-metadata", f"title={title}",
"-metadata", f"album={album}",
]
},
"quiet": True,
"no_warnings": True,
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=True)
# extract_info kann eine Playlist zurückgeben dann erstes Entry nehmen
if info is None:
raise RuntimeError("yt-dlp hat keine Informationen zurückgegeben. Bitte URL prüfen.")
if "entries" in info:
info = info["entries"][0]
filename = ydl.prepare_filename(info)
mp3_name = os.path.splitext(os.path.basename(filename))[0] + ".mp3"
download_status[task_id] = {
"status": "done",
"message": f"Fertig! Gespeichert als: {mp3_name}",
"filename": mp3_name,
}
except Exception as e:
download_status[task_id] = {
"status": "error",
"message": f"Fehler: {str(e)}",
}
@app.route("/")
def index():
return render_template("index.html")
@app.route("/download", methods=["POST"])
def download():
data = request.get_json()
url = data.get("url", "").strip()
artist = data.get("artist", "").strip()
title = data.get("title", "").strip()
album = data.get("album", "").strip()
if not url:
return jsonify({"error": "URL fehlt"}), 400
import uuid
task_id = str(uuid.uuid4())
thread = threading.Thread(target=do_download, args=(task_id, url, artist, title, album))
thread.daemon = True
thread.start()
return jsonify({"task_id": task_id})
@app.route("/status/<task_id>")
def status(task_id):
result = download_status.get(task_id, {"status": "unknown", "message": "Unbekannte Task-ID"})
return jsonify(result)
if __name__ == "__main__":
app.run(debug=True, port=5000)