|
|
from flask import Flask, render_template_string, request, send_file, after_this_request |
|
|
import yt_dlp |
|
|
import os |
|
|
import uuid |
|
|
|
|
|
app = Flask(__name__) |
|
|
|
|
|
|
|
|
HTML_CODE = """ |
|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Universal Video Downloader</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> |
|
|
<style> |
|
|
body { background:#0f172a; color:white; font-family:sans-serif; } |
|
|
.glass { background:rgba(30,41,59,.85); backdrop-filter:blur(12px); |
|
|
border-radius:16px; border:1px solid rgba(255,255,255,.1); } |
|
|
.loader { border:3px solid #f3f3f3; border-top:3px solid #3498db; |
|
|
border-radius:50%; width:18px; height:18px; |
|
|
animation:spin 1s linear infinite; display:none; } |
|
|
@keyframes spin {100%{transform:rotate(360deg)}} |
|
|
</style> |
|
|
</head> |
|
|
|
|
|
<body class="flex items-center justify-center min-h-screen p-4"> |
|
|
<div class="glass w-full max-w-md p-6"> |
|
|
<h1 class="text-3xl text-center font-bold text-blue-400 mb-6"> |
|
|
UniLoader <span class="text-xs text-gray-400">HF Edition</span> |
|
|
</h1> |
|
|
|
|
|
<form method="POST" action="/download" |
|
|
onsubmit="document.getElementById('sp').style.display='inline-block'" |
|
|
class="space-y-4"> |
|
|
<input name="url" required |
|
|
class="w-full bg-gray-900 border border-gray-700 p-3 rounded-lg" |
|
|
placeholder="Paste YouTube / TikTok link"> |
|
|
|
|
|
<button class="w-full bg-blue-600 hover:bg-blue-700 p-3 rounded-lg |
|
|
font-bold flex items-center justify-center gap-2"> |
|
|
Download Best Quality |
|
|
<div id="sp" class="loader"></div> |
|
|
</button> |
|
|
</form> |
|
|
|
|
|
{% if error %} |
|
|
<div class="mt-4 bg-red-900/50 p-3 rounded text-center text-sm"> |
|
|
{{ error }} |
|
|
</div> |
|
|
{% endif %} |
|
|
|
|
|
<p class="text-xs text-gray-400 mt-4 text-center"> |
|
|
Note: TikTok HD on Hugging Face is limited by platform. |
|
|
</p> |
|
|
</div> |
|
|
</body> |
|
|
</html> |
|
|
""" |
|
|
|
|
|
|
|
|
@app.route("/", methods=["GET"]) |
|
|
def index(): |
|
|
return render_template_string(HTML_CODE) |
|
|
|
|
|
@app.route("/download", methods=["POST"]) |
|
|
def download(): |
|
|
url = request.form.get("url") |
|
|
filename = f"video_{uuid.uuid4().hex[:6]}.mp4" |
|
|
|
|
|
try: |
|
|
ydl_opts = { |
|
|
|
|
|
"format": ( |
|
|
"bv*[ext=mp4][height<=720]/" |
|
|
"bv*[height<=720]/" |
|
|
"best[height<=720]/best" |
|
|
), |
|
|
|
|
|
"outtmpl": filename, |
|
|
"merge_output_format": "mp4", |
|
|
|
|
|
|
|
|
"http_headers": { |
|
|
"User-Agent": |
|
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)", |
|
|
"Accept-Language": "en-US,en;q=0.9", |
|
|
}, |
|
|
|
|
|
"quiet": True, |
|
|
"no_warnings": True, |
|
|
"nocheckcertificate": True, |
|
|
} |
|
|
|
|
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl: |
|
|
ydl.download([url]) |
|
|
|
|
|
@after_this_request |
|
|
def cleanup(resp): |
|
|
try: |
|
|
if os.path.exists(filename): |
|
|
os.remove(filename) |
|
|
except: |
|
|
pass |
|
|
return resp |
|
|
|
|
|
return send_file(filename, as_attachment=True) |
|
|
|
|
|
except Exception as e: |
|
|
return render_template_string(HTML_CODE, error=str(e)) |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
app.run(host="0.0.0.0", port=7860) |