Celeskry commited on
Commit
1ab8b1e
·
verified ·
1 Parent(s): f0106eb

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +73 -79
main.py CHANGED
@@ -165,8 +165,8 @@ async def hentai_random(apikey: Optional[str] = Query(None), limit: str = Query(
165
  key = x_api_key or apikey
166
  return await ht_random_app.get_random(key, API_KEY, limit)
167
 
168
- @app.get("/api/v1/tiktok/download")
169
- async def tiktok_download(
170
  url: str = Query(...),
171
  hd: int = Query(1),
172
  apikey: Optional[str] = Query(None),
@@ -181,92 +181,86 @@ async def tiktok_download(
181
  raise HTTPException(status_code=400, detail=res["error"])
182
  return res
183
 
184
- @app.get("/api/v1/tiktok/dl-direct")
185
- async def tiktok_direct(
186
- url: str = Query(None),
187
- token: str = Query(None),
188
- type: str = Query("mp4"),
189
  apikey: Optional[str] = Query(None),
190
  x_api_key: Optional[str] = Header(None, alias="X-API-Key")
191
  ):
192
  if url:
193
  key = x_api_key or apikey
194
  if not API_KEY or key != API_KEY:
195
- raise HTTPException(status_code=403, detail="API key required to generate token")
196
-
197
- res = await tik_direct.generate_token(url, type)
198
- if not res["ok"]:
199
- raise HTTPException(status_code=400, detail=res["error"])
200
- return res
201
-
202
- if token:
203
  data = tik_direct.consume_token(token)
204
  if not data:
205
- raise HTTPException(status_code=404, detail="Token invalid, expired hoặc đã dùng quá 3 lần")
206
-
207
- if data["type"] in ["mp3_convert", "wav_convert"]:
208
- is_wav = data["type"] == "wav_convert"
209
- ext = "wav" if is_wav else "mp3"
210
- acodec = "pcm_s16le" if is_wav else "libmp3lame"
211
- fmt = "wav" if is_wav else "mp3"
212
- media_type = "audio/wav" if is_wav else "audio/mpeg"
213
- filename = f"Celeskry_Audio_{int(time.time())}.{ext}"
214
-
215
- try:
216
- process = (
217
- ffmpeg
218
- .input(data["url"])
219
- .output('pipe:', format=fmt, acodec=acodec, ar='44100')
220
- .run_async(pipe_stdout=True, pipe_stderr=True)
221
- )
222
-
223
- async def stream_ffmpeg():
224
- try:
225
- while True:
226
- chunk = await asyncio.to_thread(process.stdout.read, 4096)
227
- if not chunk:
228
- break
229
- yield chunk
230
- finally:
231
- try:
232
- process.kill()
233
- except:
234
- pass
235
-
236
- return StreamingResponse(
237
- stream_ffmpeg(),
238
- media_type=media_type,
239
- headers={"Content-Disposition": f"attachment; filename={filename}"}
240
- )
241
- except Exception as e:
242
- raise HTTPException(status_code=500, detail=f"Lỗi convert {ext}: {str(e)}")
243
-
244
- async def stream_file():
245
- async with httpx.AsyncClient(follow_redirects=True, timeout=30.0) as client:
246
- async with client.stream("GET", data["url"]) as r:
247
- if r.status_code != 200:
248
- yield b"Error: Could not fetch file from provider"
249
- return
250
- async for chunk in r.aiter_bytes(chunk_size=1024*1024):
251
  yield chunk
252
-
253
- ext = data["type"]
254
- if ext == "mp4":
255
- media_type = "video/mp4"
256
- elif ext == "mp3":
257
- media_type = "audio/mpeg"
258
- elif ext in ["jpg", "jpeg", "png"]:
259
- media_type = f"image/{ext}"
260
- else:
261
- media_type = "application/octet-stream"
262
-
263
- filename = f"Celeste_{int(time.time())}.{ext}"
264
-
265
- return StreamingResponse(
266
- stream_file(),
267
- media_type=media_type,
268
- headers={"Content-Disposition": f"attachment; filename={filename}"}
269
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
 
271
  raise HTTPException(status_code=400, detail="Provide either 'url' or 'token'")
272
 
 
165
  key = x_api_key or apikey
166
  return await ht_random_app.get_random(key, API_KEY, limit)
167
 
168
+ @app.get("/api/v1/tiktok/dl")
169
+ async def tiktok_dl(
170
  url: str = Query(...),
171
  hd: int = Query(1),
172
  apikey: Optional[str] = Query(None),
 
181
  raise HTTPException(status_code=400, detail=res["error"])
182
  return res
183
 
184
+ @app.get("/api/v1/tiktok/cdn")
185
+ async def tiktok_cdn(
186
+ token: str = Query(None, description="Token generated from /dl endpoint"),
187
+ url: str = Query(None, description="Direct URL to proxy (Requires API Key)"),
188
+ type: str = Query("mp4", description="File extension type"),
189
  apikey: Optional[str] = Query(None),
190
  x_api_key: Optional[str] = Header(None, alias="X-API-Key")
191
  ):
192
  if url:
193
  key = x_api_key or apikey
194
  if not API_KEY or key != API_KEY:
195
+ raise HTTPException(status_code=403, detail="Proxying via URL requires a valid API Key")
196
+ data = {"url": url, "type": type}
197
+
198
+ elif token:
 
 
 
 
199
  data = tik_direct.consume_token(token)
200
  if not data:
201
+ raise HTTPException(status_code=404, detail="Token invalid, expired or limit reached")
202
+
203
+ else:
204
+ raise HTTPException(status_code=400, detail="Either 'token' or 'url' must be provided")
205
+
206
+ target_url = data["url"]
207
+ media_type_req = data["type"]
208
+
209
+ if media_type_req in ["mp3_convert", "wav_convert"]:
210
+ is_wav = media_type_req == "wav_convert"
211
+ ext = "wav" if is_wav else "mp3"
212
+ acodec = "pcm_s16le" if is_wav else "libmp3lame"
213
+ fmt = "wav" if is_wav else "mp3"
214
+ media_header = "audio/wav" if is_wav else "audio/mpeg"
215
+
216
+ try:
217
+ process = (
218
+ ffmpeg
219
+ .input(target_url)
220
+ .output('pipe:', format=fmt, acodec=acodec, ar='44100')
221
+ .run_async(pipe_stdout=True, pipe_stderr=True)
222
+ )
223
+
224
+ async def stream_ffmpeg():
225
+ try:
226
+ while True:
227
+ chunk = await asyncio.to_thread(process.stdout.read, 8192)
228
+ if not chunk: break
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  yield chunk
230
+ finally:
231
+ try: process.kill()
232
+ except: pass
233
+
234
+ return StreamingResponse(
235
+ stream_ffmpeg(),
236
+ media_type=media_header,
237
+ headers={"Content-Disposition": f"attachment; filename=Celeskry_{int(time.time())}.{ext}"}
238
+ )
239
+ except Exception as e:
240
+ raise HTTPException(status_code=500, detail=f"Conversion Error: {str(e)}")
241
+
242
+ async def stream_file():
243
+ async with httpx.AsyncClient(follow_redirects=True, timeout=60.0) as client:
244
+ async with client.stream("GET", target_url) as r:
245
+ if r.status_code != 200:
246
+ yield b"Error: Resource not found"
247
+ return
248
+ async for chunk in r.aiter_bytes(chunk_size=1024*1024):
249
+ yield chunk
250
+
251
+ content_types = {
252
+ "mp4": "video/mp4",
253
+ "mp3": "audio/mpeg",
254
+ "jpg": "image/jpeg",
255
+ "png": "image/png"
256
+ }
257
+ final_type = content_types.get(media_type_req, "application/octet-stream")
258
+
259
+ return StreamingResponse(
260
+ stream_file(),
261
+ media_type=final_type,
262
+ headers={"Content-Disposition": f"attachment; filename=Celeste_{int(time.time())}.{media_type_req}"}
263
+ )
264
 
265
  raise HTTPException(status_code=400, detail="Provide either 'url' or 'token'")
266