Commit
·
87c7342
1
Parent(s):
dc50e93
serve video
Browse files
app.py
CHANGED
|
@@ -4,6 +4,7 @@ from threading import Thread
|
|
| 4 |
from Instance import Instance
|
| 5 |
from api import LoadBalancerAPI
|
| 6 |
import os
|
|
|
|
| 7 |
# Constants and Configuration
|
| 8 |
CACHE_DIR = os.getenv("CACHE_DIR")
|
| 9 |
TOKEN = os.getenv("TOKEN")
|
|
@@ -17,6 +18,39 @@ instance = Instance(id=ID, url=URL, cache_dir=CACHE_DIR, token=TOKEN, repo=REPO,
|
|
| 17 |
|
| 18 |
app = FastAPI()
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
@app.get("/")
|
| 21 |
async def index():
|
| 22 |
return instance.version
|
|
@@ -36,9 +70,16 @@ async def get_film_store_api():
|
|
| 36 |
"""Endpoint to get the TV store JSON."""
|
| 37 |
return JSONResponse(instance.FILM_STORE)
|
| 38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
@app.get("/api/get/film/{title}")
|
| 40 |
-
async def get_movie_api(title: str):
|
| 41 |
-
"""Endpoint to get the movie by title."""
|
| 42 |
if not title:
|
| 43 |
raise HTTPException(status_code=400, detail="Title parameter is required")
|
| 44 |
|
|
@@ -46,7 +87,7 @@ async def get_movie_api(title: str):
|
|
| 46 |
if title in instance.FILM_STORE:
|
| 47 |
cache_path = instance.FILM_STORE[title]
|
| 48 |
if os.path.exists(cache_path):
|
| 49 |
-
return
|
| 50 |
|
| 51 |
movie_path = instance.find_movie_path(title)
|
| 52 |
|
|
|
|
| 4 |
from Instance import Instance
|
| 5 |
from api import LoadBalancerAPI
|
| 6 |
import os
|
| 7 |
+
import re
|
| 8 |
# Constants and Configuration
|
| 9 |
CACHE_DIR = os.getenv("CACHE_DIR")
|
| 10 |
TOKEN = os.getenv("TOKEN")
|
|
|
|
| 18 |
|
| 19 |
app = FastAPI()
|
| 20 |
|
| 21 |
+
async def serve_video(file_path: str, request: Request):
|
| 22 |
+
"""Serve video file with support for range requests."""
|
| 23 |
+
if not os.path.isfile(file_path):
|
| 24 |
+
raise HTTPException(status_code=404, detail="Video file not found")
|
| 25 |
+
|
| 26 |
+
file_size = os.path.getsize(file_path)
|
| 27 |
+
range_header = request.headers.get('range', None)
|
| 28 |
+
|
| 29 |
+
if range_header:
|
| 30 |
+
match = re.match(r'bytes=(\d+)-(\d*)', range_header)
|
| 31 |
+
if match:
|
| 32 |
+
start, end = match.groups()
|
| 33 |
+
start = int(start)
|
| 34 |
+
end = int(end) if end else file_size - 1
|
| 35 |
+
|
| 36 |
+
if start >= file_size or end >= file_size or start > end:
|
| 37 |
+
raise HTTPException(status_code=416, detail="Requested range not satisfiable")
|
| 38 |
+
|
| 39 |
+
headers = {
|
| 40 |
+
'Content-Range': f'bytes {start}-{end}/{file_size}',
|
| 41 |
+
'Accept-Ranges': 'bytes',
|
| 42 |
+
'Content-Length': str(end - start + 1),
|
| 43 |
+
'Content-Type': 'video/mp4' # Change as per your video format
|
| 44 |
+
}
|
| 45 |
+
with open(file_path, 'rb') as f:
|
| 46 |
+
f.seek(start)
|
| 47 |
+
data = f.read(end - start + 1)
|
| 48 |
+
return Response(content=data, status_code=206, headers=headers)
|
| 49 |
+
|
| 50 |
+
# Fallback for serving the whole file if no range requested
|
| 51 |
+
return FileResponse(file_path)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
@app.get("/")
|
| 55 |
async def index():
|
| 56 |
return instance.version
|
|
|
|
| 70 |
"""Endpoint to get the TV store JSON."""
|
| 71 |
return JSONResponse(instance.FILM_STORE)
|
| 72 |
|
| 73 |
+
from fastapi import FastAPI, HTTPException, Request, Response
|
| 74 |
+
from fastapi.responses import FileResponse
|
| 75 |
+
import os
|
| 76 |
+
from threading import Thread
|
| 77 |
+
|
| 78 |
+
app = FastAPI()
|
| 79 |
+
|
| 80 |
@app.get("/api/get/film/{title}")
|
| 81 |
+
async def get_movie_api(request: Request, title: str):
|
| 82 |
+
"""Endpoint to get the movie by title with support for range requests."""
|
| 83 |
if not title:
|
| 84 |
raise HTTPException(status_code=400, detail="Title parameter is required")
|
| 85 |
|
|
|
|
| 87 |
if title in instance.FILM_STORE:
|
| 88 |
cache_path = instance.FILM_STORE[title]
|
| 89 |
if os.path.exists(cache_path):
|
| 90 |
+
return await serve_video(cache_path, request)
|
| 91 |
|
| 92 |
movie_path = instance.find_movie_path(title)
|
| 93 |
|