lljz66 commited on
Commit
3cafa5f
·
verified ·
1 Parent(s): 5591f3c

root app imports core

Browse files
Files changed (1) hide show
  1. app.py +1 -104
app.py CHANGED
@@ -1,104 +1 @@
1
- import os, re, uuid, subprocess
2
- from fastapi import FastAPI, HTTPException
3
- from fastapi.responses import FileResponse, StreamingResponse
4
- import yt_dlp
5
-
6
- app = FastAPI()
7
- os.makedirs("videos", exist_ok=True)
8
-
9
- def name_from_url(url: str, fallback: str) -> str:
10
- # kick.com/streamer/videos/ID -> streamer_ID
11
- # twitch.tv/videos/ID -> twitch_ID
12
- # youtube.com/watch?v=ID -> youtube_ID
13
- m = re.findall(r"/videos/([^/?]+)", url)
14
- if m:
15
- parts = url.split("/")
16
- streamer = parts[-3] if len(parts) >= 3 and parts[-2] == "videos" else ("twitch" if "twitch" in url else "stream")
17
- return f"{streamer}_{m[0][:12]}"
18
- m = re.findall(r"[?&]v=([^&]+)", url)
19
- if m:
20
- return f"youtube_{m[0]}"
21
- return fallback
22
-
23
- @app.get("/formats")
24
- def formats(url: str):
25
- try:
26
- with yt_dlp.YoutubeDL({"quiet": True, "no_warnings": True}) as y:
27
- info = y.extract_info(url, download=False)
28
- except Exception as e:
29
- try:
30
- r = subprocess.run(
31
- ["streamlink", "--json", url],
32
- capture_output=True, text=True, timeout=60
33
- )
34
- import json
35
- data = json.loads(r.stdout)
36
- return [{"id": k, "quality": k, "ext": "mp4", "size_mb": 0, "vcodec": "h264"}
37
- for k in data.get("streams", {}).keys()]
38
- except Exception:
39
- raise HTTPException(400, str(e))
40
- out = []
41
- for f in info.get("formats", []):
42
- if f.get("vcodec") != "none" and f.get("height"):
43
- out.append({
44
- "id": f["format_id"],
45
- "quality": f"{f['height']}p",
46
- "ext": f.get("ext"),
47
- "size_mb": round((f.get("filesize") or f.get("filesize_approx") or 0) / 1e6, 1),
48
- "vcodec": f.get("vcodec"),
49
- })
50
- return out
51
-
52
- @app.post("/download")
53
- def download(url: str, format_id: str):
54
- name = name_from_url(url, uuid.uuid4().hex[:8])
55
- outtmpl = f"videos/{name}.%(ext)s"
56
- try:
57
- with yt_dlp.YoutubeDL({
58
- "format": format_id,
59
- "outtmpl": outtmpl,
60
- "quiet": True,
61
- "no_warnings": True,
62
- }) as y:
63
- info = y.extract_info(url, download=True)
64
- ext = info.get("ext", "mp4")
65
- return {"status": "ok", "file": f"{name}.{ext}"}
66
- except Exception:
67
- try:
68
- out = f"videos/{name}.mp4"
69
- subprocess.run(
70
- ["streamlink", url, format_id, "-o", out],
71
- capture_output=True, text=True, timeout=3600, check=True
72
- )
73
- return {"status": "ok", "file": f"{name}.mp4"}
74
- except Exception as e2:
75
- raise HTTPException(400, str(e2))
76
-
77
- @app.get("/stream")
78
- def stream(url: str, format_id: str):
79
- name = name_from_url(url, uuid.uuid4().hex[:8])
80
- sl = subprocess.Popen(
81
- ["streamlink", url, format_id, "--stdout"],
82
- stdout=subprocess.PIPE
83
- )
84
- ff = subprocess.Popen(
85
- ["ffmpeg", "-i", "pipe:0", "-c", "copy",
86
- "-bsf:a", "aac_adtstoasc",
87
- "-movflags", "frag_keyframe+empty_moov",
88
- "-f", "mp4", "pipe:1"],
89
- stdin=sl.stdout,
90
- stdout=subprocess.PIPE,
91
- stderr=None
92
- )
93
- return StreamingResponse(
94
- ff.stdout,
95
- media_type="video/mp4",
96
- headers={"Content-Disposition": f'attachment; filename="{name}.mp4"'}
97
- )
98
-
99
- @app.get("/files/{name}")
100
- def get_file(name: str):
101
- path = f"videos/{name}"
102
- if not os.path.exists(path):
103
- raise HTTPException(404, "not found")
104
- return FileResponse(path)
 
1
+ from core.app import app