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/") 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)