Spaces:
Paused
Paused
Upload app.py
Browse files
app.py
CHANGED
|
@@ -317,6 +317,68 @@ async def vkmovie_search(q: str, kp: str = "", year: str = ""):
|
|
| 317 |
)
|
| 318 |
|
| 319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 320 |
@app.get("/vkmovie/stream")
|
| 321 |
async def vkmovie_stream(url: str, request: Request):
|
| 322 |
"""Стримит VK MP4 через прокси (IP-привязка — нужен тот же IP что получил токен)"""
|
|
|
|
| 317 |
)
|
| 318 |
|
| 319 |
|
| 320 |
+
@app.get("/vkmovie/hls")
|
| 321 |
+
async def vkmovie_hls(url: str, request: Request):
|
| 322 |
+
"""Проксує VK HLS m3u8 з правильними заголовками і переписує сегменти"""
|
| 323 |
+
if not url:
|
| 324 |
+
return Response(content="no url", status_code=400)
|
| 325 |
+
|
| 326 |
+
req_headers = {
|
| 327 |
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
| 328 |
+
"Referer": "https://vkvideo.ru/",
|
| 329 |
+
"Origin": "https://vkvideo.ru",
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
async with httpx.AsyncClient(timeout=15, follow_redirects=True) as client:
|
| 333 |
+
try:
|
| 334 |
+
r = await client.get(url, headers=req_headers)
|
| 335 |
+
text = r.text
|
| 336 |
+
except Exception as e:
|
| 337 |
+
return Response(content=f"error: {e}", status_code=500)
|
| 338 |
+
|
| 339 |
+
content_type = r.headers.get("content-type", "")
|
| 340 |
+
# Якщо це не m3u8 — повертаємо як є
|
| 341 |
+
if "mpegurl" not in content_type and not text.strip().startswith("#EXTM3U"):
|
| 342 |
+
return Response(content=text, status_code=r.status_code,
|
| 343 |
+
media_type=content_type,
|
| 344 |
+
headers={"Access-Control-Allow-Origin": "*"})
|
| 345 |
+
|
| 346 |
+
# Переписуємо URL сегментів через /vkmovie/stream
|
| 347 |
+
hf = str(request.base_url).rstrip("/").replace("http://", "https://")
|
| 348 |
+
base = url.rsplit("/", 1)[0] + "/"
|
| 349 |
+
|
| 350 |
+
def rewrite_vk_url(seg: str) -> str:
|
| 351 |
+
seg = seg.strip()
|
| 352 |
+
if not seg:
|
| 353 |
+
return seg
|
| 354 |
+
if seg.startswith("http://") or seg.startswith("https://"):
|
| 355 |
+
abs_url = seg
|
| 356 |
+
elif seg.startswith("//"):
|
| 357 |
+
abs_url = "https:" + seg
|
| 358 |
+
else:
|
| 359 |
+
abs_url = urljoin(base, seg)
|
| 360 |
+
return f"{hf}/vkmovie/stream?url={quote(abs_url, safe='')}"
|
| 361 |
+
|
| 362 |
+
lines = text.splitlines()
|
| 363 |
+
out = []
|
| 364 |
+
for line in lines:
|
| 365 |
+
stripped = line.strip()
|
| 366 |
+
if not stripped:
|
| 367 |
+
out.append(line)
|
| 368 |
+
elif stripped.startswith("#"):
|
| 369 |
+
# Переписуємо URI= в тегах (субтитри, аудіо)
|
| 370 |
+
rewritten = re.sub(r'URI="([^"]+)"', lambda m: f'URI="{rewrite_vk_url(m.group(1))}"', line)
|
| 371 |
+
out.append(rewritten)
|
| 372 |
+
else:
|
| 373 |
+
out.append(rewrite_vk_url(stripped))
|
| 374 |
+
|
| 375 |
+
return Response(
|
| 376 |
+
content="\n".join(out),
|
| 377 |
+
media_type="application/vnd.apple.mpegurl",
|
| 378 |
+
headers={"Access-Control-Allow-Origin": "*"}
|
| 379 |
+
)
|
| 380 |
+
|
| 381 |
+
|
| 382 |
@app.get("/vkmovie/stream")
|
| 383 |
async def vkmovie_stream(url: str, request: Request):
|
| 384 |
"""Стримит VK MP4 через прокси (IP-привязка — нужен тот же IP что получил токен)"""
|