Commit
·
36bda90
1
Parent(s):
db46eb3
test
Browse files
app.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
from fastapi.responses import JSONResponse, FileResponse, Response
|
| 2 |
from fastapi import FastAPI, HTTPException, Request
|
|
|
|
| 3 |
from threading import Thread
|
| 4 |
from Instance import Instance
|
| 5 |
from api import LoadBalancerAPI
|
|
@@ -28,29 +29,52 @@ async def serve_video(file_path: str, request: Request):
|
|
| 28 |
file_size = os.path.getsize(file_path)
|
| 29 |
range_header = request.headers.get('range', None)
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
if range_header:
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
|
|
|
|
|
|
| 35 |
start = int(start)
|
| 36 |
end = int(end) if end else file_size - 1
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
return Response(content=data, status_code=206, headers=headers)
|
| 51 |
-
|
| 52 |
# Fallback for serving the whole file if no range requested
|
| 53 |
-
return FileResponse(file_path)
|
|
|
|
| 54 |
|
| 55 |
@app.get("/")
|
| 56 |
async def index():
|
|
|
|
| 1 |
from fastapi.responses import JSONResponse, FileResponse, Response
|
| 2 |
from fastapi import FastAPI, HTTPException, Request
|
| 3 |
+
import mimetypes
|
| 4 |
from threading import Thread
|
| 5 |
from Instance import Instance
|
| 6 |
from api import LoadBalancerAPI
|
|
|
|
| 29 |
file_size = os.path.getsize(file_path)
|
| 30 |
range_header = request.headers.get('range', None)
|
| 31 |
|
| 32 |
+
# Determine the MIME type based on the file extension
|
| 33 |
+
mime_type, _ = mimetypes.guess_type(file_path)
|
| 34 |
+
if mime_type is None:
|
| 35 |
+
mime_type = 'application/octet-stream' # Fallback MIME type
|
| 36 |
+
|
| 37 |
if range_header:
|
| 38 |
+
# Simple parsing for range values
|
| 39 |
+
start, end = None, None
|
| 40 |
+
range_specifier = range_header.replace('bytes=', '').strip()
|
| 41 |
+
if '-' in range_specifier:
|
| 42 |
+
start, end = range_specifier.split('-')
|
| 43 |
start = int(start)
|
| 44 |
end = int(end) if end else file_size - 1
|
| 45 |
+
|
| 46 |
+
# Validate range
|
| 47 |
+
if start is None or start >= file_size or (end is not None and end >= file_size) or (end is not None and start > end):
|
| 48 |
+
raise HTTPException(status_code=416, detail="Requested range not satisfiable")
|
| 49 |
+
|
| 50 |
+
headers = {
|
| 51 |
+
'Content-Range': f'bytes {start}-{end or file_size - 1}/{file_size}',
|
| 52 |
+
'Accept-Ranges': 'bytes',
|
| 53 |
+
'Content-Length': str((end - start + 1) if end is not None else file_size - start),
|
| 54 |
+
'Content-Type': mime_type
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
async with aiofiles.open(file_path, 'rb') as f:
|
| 58 |
+
await f.seek(start)
|
| 59 |
+
chunk_size = 8192 # Read in 8KB chunks
|
| 60 |
+
data = bytearray()
|
| 61 |
+
|
| 62 |
+
while start <= (end or file_size - 1):
|
| 63 |
+
remaining = (end or file_size - 1) - start + 1
|
| 64 |
+
read_size = min(chunk_size, remaining)
|
| 65 |
+
chunk = await f.read(read_size)
|
| 66 |
+
|
| 67 |
+
if not chunk: # EOF
|
| 68 |
+
break
|
| 69 |
+
|
| 70 |
+
data.extend(chunk)
|
| 71 |
+
start += read_size
|
| 72 |
+
|
| 73 |
return Response(content=data, status_code=206, headers=headers)
|
| 74 |
+
|
| 75 |
# Fallback for serving the whole file if no range requested
|
| 76 |
+
return FileResponse(file_path, media_type=mime_type)
|
| 77 |
+
|
| 78 |
|
| 79 |
@app.get("/")
|
| 80 |
async def index():
|