icdd-vsumm/main.py

67 lines
2.2 KiB
Python

import os
import uvicorn
from pathlib import Path
from fastapi import FastAPI, UploadFile, File, Header
from fastapi.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from config import ServerConfig
app = FastAPI()
app.mount('/home', StaticFiles(directory='static', html=True), name='static')
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=True,
allow_methods=['*'],
allow_headers=['*'],
)
@app.post('/upload')
async def upload_file(file: UploadFile = File(...)):
video_path = os.path.join(ServerConfig.video_upload_path, file.filename + '.mp4')
with open(video_path, 'wb') as video:
video.write(await file.read())
return {'status': 200, 'id': os.path.splitext(file.filename)[0]}
@app.get("/fetch/{id}")
async def fetch_file(id: str, range: str = Header(None)) -> StreamingResponse:
video_path = Path(os.path.join(ServerConfig.video_play_path, id + '.mp4'))
video_size = video_path.stat().st_size
start = 0
end = video_size - 1
chunk_size = min(video_size, ServerConfig.video_chunk_size)
headers = {
'Content-Type': 'video/mp4',
'Content-Disposition': f'attachment; filename="{id}.mp4"',
}
if range:
start, end = range.replace('bytes=', '').split('-')
start = int(start)
end = int(end) if end else video_size - 1
chunk_size = min(end - start + 1, ServerConfig.video_chunk_size)
headers['Content-Range'] = f'bytes {start}-{end}/{video_size}'
headers['Accept-Ranges'] = 'bytes'
headers['Content-Disposition'] = 'inline'
def file_reader():
with open(video_path, 'rb') as video:
video.seek(start)
while True:
data = video.read(chunk_size)
if not data:
break
yield data
return StreamingResponse(file_reader(), status_code=206, headers=headers, media_type='video/mp4')
if __name__ == "__main__":
uvicorn.run(app=app)