Merge pull request #259 from KevinZhang19870314/main

refactor: video stream api revise
This commit is contained in:
Harry
2024-04-15 11:30:10 +08:00
committed by GitHub

View File

@@ -3,7 +3,7 @@ import glob
import shutil import shutil
from fastapi import Request, Depends, Path, BackgroundTasks, UploadFile 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 fastapi.params import File
from loguru import logger 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): async def stream_video(request: Request, file_path: str):
tasks_dir = utils.task_dir() tasks_dir = utils.task_dir()
video_path = os.path.join(tasks_dir, file_path) video_path = os.path.join(tasks_dir, file_path)
if os.path.isfile(video_path): range_header = request.headers.get('Range')
return FileResponse(video_path, media_type="video/mp4", filename=file_path) video_size = os.path.getsize(video_path)
else: start, end = 0, video_size - 1
return {"message": "File not found."}
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