mirror of
https://github.com/harry0703/MoneyPrinterTurbo.git
synced 2026-02-21 16:37:21 +08:00
refactor: Streaming MP4 files in the browser using video html element instead of waiting for the entire file to download before playing
This commit is contained in:
parent
0550e433d1
commit
d13a3cf6e9
@ -3,7 +3,7 @@ import glob
|
||||
import shutil
|
||||
|
||||
from fastapi import Request, Depends, Path, BackgroundTasks, UploadFile
|
||||
from fastapi.responses import FileResponse
|
||||
from fastapi.responses import FileResponse, StreamingResponse
|
||||
from fastapi.params import File
|
||||
from loguru import logger
|
||||
|
||||
@ -137,7 +137,37 @@ def upload_bgm_file(request: Request, file: UploadFile = File(...)):
|
||||
async def stream_video(request: Request, file_path: str):
|
||||
tasks_dir = utils.task_dir()
|
||||
video_path = os.path.join(tasks_dir, file_path)
|
||||
if os.path.isfile(video_path):
|
||||
return FileResponse(video_path, media_type="video/mp4", filename=file_path)
|
||||
else:
|
||||
return {"message": "File not found."}
|
||||
range_header = request.headers.get('Range')
|
||||
video_size = os.path.getsize(video_path)
|
||||
start, end = 0, video_size - 1
|
||||
|
||||
length = video_size
|
||||
if range_header:
|
||||
range_ = range_header.split('bytes=')[1]
|
||||
start, end = [int(part) if part else None for part in range_.split('-')]
|
||||
if start is None:
|
||||
start = video_size - end
|
||||
end = video_size - 1
|
||||
if end is None:
|
||||
end = video_size - 1
|
||||
length = end - start + 1
|
||||
|
||||
def file_iterator(file_path, offset=0, bytes_to_read=None):
|
||||
with open(file_path, 'rb') as f:
|
||||
f.seek(offset, os.SEEK_SET)
|
||||
remaining = bytes_to_read or video_size
|
||||
while remaining > 0:
|
||||
bytes_to_read = min(4096, remaining)
|
||||
data = f.read(bytes_to_read)
|
||||
if not data:
|
||||
break
|
||||
remaining -= len(data)
|
||||
yield data
|
||||
|
||||
response = StreamingResponse(file_iterator(video_path, start, length), media_type='video/mp4')
|
||||
response.headers['Content-Range'] = f'bytes {start}-{end}/{video_size}'
|
||||
response.headers['Accept-Ranges'] = 'bytes'
|
||||
response.headers['Content-Length'] = str(length)
|
||||
response.status_code = 206 # Partial Content
|
||||
|
||||
return response
|
||||
|
||||
Loading…
Reference in New Issue
Block a user