ChandimaPrabath commited on
Commit
36bda90
·
1 Parent(s): db46eb3
Files changed (1) hide show
  1. app.py +42 -18
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
- match = re.match(r'bytes=(\d+)-(\d*)', range_header)
33
- if match:
34
- start, end = match.groups()
 
 
35
  start = int(start)
36
  end = int(end) if end else file_size - 1
37
-
38
- if start >= file_size or end >= file_size or start > end:
39
- raise HTTPException(status_code=416, detail="Requested range not satisfiable")
40
-
41
- headers = {
42
- 'Content-Range': f'bytes {start}-{end}/{file_size}',
43
- 'Accept-Ranges': 'bytes',
44
- 'Content-Length': str(end - start + 1),
45
- 'Content-Type': 'video/mp4' # Change as per your video format
46
- }
47
- async with aiofiles.open(file_path, 'rb') as f:
48
- await f.seek(start)
49
- data = await f.read(end - start + 1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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():