JerryCoder commited on
Commit
2135afe
Β·
verified Β·
1 Parent(s): 1cc3704

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -0
app.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.responses import FileResponse
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ import subprocess
5
+ import uuid
6
+ import os
7
+ import requests
8
+
9
+ app = FastAPI()
10
+
11
+ # βœ… CORS ENABLED
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"],
15
+ allow_credentials=True,
16
+ allow_methods=["*"],
17
+ allow_headers=["*"],
18
+ )
19
+
20
+ TEMP_DIR = "/tmp"
21
+ os.makedirs(TEMP_DIR, exist_ok=True)
22
+
23
+ BASE_URL = "https://jerrycoder-jerrycoderapi.hf.space"
24
+
25
+
26
+ @app.get("/")
27
+ def home():
28
+ return {"status": "ok"}
29
+
30
+
31
+ # πŸ”₯ MAIN YT ENDPOINT
32
+ @app.get("/yt")
33
+ def yt(url: str, quality: str = "128"):
34
+ try:
35
+ # βœ… STEP 1: CALL NEOXR API
36
+ neoxr_url = f"https://api.neoxr.eu/api/youtube?url={url}&type=audio&quality={quality}kbps&apikey=jerrycoder"
37
+ r = requests.get(neoxr_url, timeout=20)
38
+
39
+ if r.status_code != 200:
40
+ raise Exception("Neoxr API failed")
41
+
42
+ data = r.json()
43
+
44
+ if not data.get("status"):
45
+ raise Exception("Invalid response from Neoxr")
46
+
47
+ # βœ… META
48
+ title = data.get("title")
49
+ duration = data.get("fduration") or data.get("duration")
50
+ download_url = data["data"]["url"]
51
+
52
+ # βœ… STEP 2: CALL /convert
53
+ convert_api = f"{BASE_URL}/convert?url={download_url}"
54
+ conv = requests.get(convert_api, timeout=60)
55
+
56
+ if conv.status_code != 200:
57
+ raise Exception("Convert API failed")
58
+
59
+ conv_json = conv.json()
60
+
61
+ if not conv_json.get("success"):
62
+ raise Exception(conv_json.get("error", "Conversion failed"))
63
+
64
+ final_url = conv_json.get("mp3_url")
65
+
66
+ # βœ… FINAL JSON
67
+ finalJson = {
68
+ "status": "success",
69
+ "title": title,
70
+ "duration": duration,
71
+ "quality": f"{quality} kbs",
72
+ "url": final_url,
73
+ "creator": "JerryCoder",
74
+ "telegram": "@Oggy_Workshop"
75
+ }
76
+
77
+ return finalJson
78
+
79
+ except Exception as e:
80
+ return {
81
+ "status": "error",
82
+ "error": str(e)
83
+ }
84
+
85
+
86
+ # πŸ”₯ CONVERT ENDPOINT (UNCHANGED BUT CLEANED)
87
+ @app.get("/convert")
88
+ def convert(url: str):
89
+ uid = str(uuid.uuid4())
90
+ output_template = f"{TEMP_DIR}/{uid}.%(ext)s"
91
+ final_mp3 = f"{TEMP_DIR}/{uid}.mp3"
92
+ input_file = f"{TEMP_DIR}/{uid}.input"
93
+
94
+ try:
95
+ # STEP 1: yt-dlp
96
+ cmd = [
97
+ "yt-dlp",
98
+ "-x",
99
+ "--audio-format", "mp3",
100
+ "--audio-quality", "5",
101
+ "-o", output_template,
102
+ url
103
+ ]
104
+
105
+ subprocess.run(
106
+ cmd,
107
+ stdout=subprocess.DEVNULL,
108
+ stderr=subprocess.DEVNULL,
109
+ check=True
110
+ )
111
+
112
+ if os.path.exists(final_mp3):
113
+ return {
114
+ "success": True,
115
+ "mp3_url": f"{BASE_URL}/file/{uid}",
116
+ "creator": "JerryCoder"
117
+ }
118
+
119
+ except:
120
+ pass
121
+
122
+ try:
123
+ # STEP 2: fallback download
124
+ headers = {"User-Agent": "Mozilla/5.0"}
125
+ r = requests.get(url, headers=headers, stream=True, timeout=20)
126
+
127
+ if r.status_code != 200:
128
+ raise Exception("Download failed")
129
+
130
+ with open(input_file, "wb") as f:
131
+ for chunk in r.iter_content(1024 * 1024):
132
+ if chunk:
133
+ f.write(chunk)
134
+
135
+ subprocess.run(
136
+ ["ffmpeg", "-y", "-i", input_file, "-vn", "-acodec", "libmp3lame", "-ab", "32k", final_mp3],
137
+ stdout=subprocess.DEVNULL,
138
+ stderr=subprocess.DEVNULL,
139
+ check=True
140
+ )
141
+
142
+ if os.path.exists(final_mp3):
143
+ return {
144
+ "success": True,
145
+ "mp3_url": f"{BASE_URL}/file/{uid}",
146
+ "creator": "JerryCoder"
147
+ }
148
+
149
+ raise Exception("Conversion failed")
150
+
151
+ except Exception as e:
152
+ return {"success": False, "error": str(e)}
153
+
154
+
155
+ # πŸ”₯ FILE SERVE
156
+ @app.get("/file/{file_id}")
157
+ def get_file(file_id: str):
158
+ path = f"{TEMP_DIR}/{file_id}.mp3"
159
+
160
+ if not os.path.exists(path):
161
+ raise HTTPException(status_code=404, detail="File not found")
162
+
163
+ return FileResponse(path, media_type="audio/mpeg")