diff --git a/app.py b/app.py new file mode 100644 index 00000000..0adb55b3 --- /dev/null +++ b/app.py @@ -0,0 +1,73 @@ +from flask import Flask, render_template, request, redirect, url_for, send_from_directory, flash +from pytube import YouTube +import os +import re # Für das Bereinigen von Dateinamen + +app = Flask(__name__) +app.secret_key = 'dein_super_geheimer_schlüssel' # Wichtig für Flash-Nachrichten + +DOWNLOAD_FOLDER = 'downloads' +if not os.path.exists(DOWNLOAD_FOLDER): + os.makedirs(DOWNLOAD_FOLDER) + +def sanitize_filename(filename): + """Entfernt ungültige Zeichen aus Dateinamen.""" + return re.sub(r'[\\/*?:"<>|]', "", filename) + +@app.route('/') +def index(): + try: + # Liste nur .mp4 Dateien auf + downloaded_files = [f for f in os.listdir(DOWNLOAD_FOLDER) if f.endswith('.mp4')] + except FileNotFoundError: + downloaded_files = [] + return render_template('index.html', files=downloaded_files) + +@app.route('/download', methods=['POST']) +def download_video(): + video_url = request.form.get('youtube_url') + if not video_url: + flash('Bitte gib eine YouTube URL ein.', 'error') + return redirect(url_for('index')) + + try: + yt = YouTube(video_url) + + # Wähle den Stream mit der höchsten Auflösung, der progressiv ist (Audio+Video) und mp4 ist + stream = yt.streams.filter(progressive=True, file_extension='mp4')\ + .order_by('resolution')\ + .desc()\ + .first() + + if not stream: + flash(f'Kein passender MP4 Stream für {yt.title} gefunden.', 'error') + return redirect(url_for('index')) + + # Bereinige den Titel für den Dateinamen + filename = sanitize_filename(yt.title) + ".mp4" + filepath = os.path.join(DOWNLOAD_FOLDER, filename) + + # Überprüfen, ob die Datei bereits existiert + if os.path.exists(filepath): + flash(f'Video "{yt.title}" wurde bereits heruntergeladen.', 'info') + return redirect(url_for('index')) + + flash(f'Starte Download für: {yt.title}...', 'info') + # Wichtig: Um Flask nicht zu blockieren, könnte man hier Threading/Async verwenden, + # aber für ein "einfaches" Skript ist dies der direkteste Weg. + # Bei langen Downloads kann der Browser einen Timeout anzeigen, obwohl der Download im Hintergrund läuft. + stream.download(output_path=DOWNLOAD_FOLDER, filename=filename) + flash(f'Video "{yt.title}" erfolgreich heruntergeladen!', 'success') + + except Exception as e: + flash(f'Ein Fehler ist aufgetreten: {str(e)}', 'error') + + return redirect(url_for('index')) + +@app.route('/play/') +def play_video(filename): + # send_from_directory ermöglicht das direkte Abspielen/Herunterladen der Datei + return send_from_directory(DOWNLOAD_FOLDER, filename, as_attachment=False) # as_attachment=False versucht, es im Browser abzuspielen + +if __name__ == '__main__': + app.run(debug=True, host='0.0.0.0', port=5555) # host='0.0.0.0' macht es im lokalen Netzwerk erreichbar \ No newline at end of file