icdd-vsumm/main.py

67 lines
2.2 KiB
Python
Raw Normal View History

2024-04-20 13:52:25 +08:00
import os
import uvicorn
from pathlib import Path
2024-04-20 15:11:08 +08:00
from fastapi import FastAPI, UploadFile, File, Header
2024-04-20 13:52:25 +08:00
from fastapi.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from config import ServerConfig
app = FastAPI()
2024-04-20 15:11:08 +08:00
app.mount('/home', StaticFiles(directory='static', html=True), name='static')
2024-04-20 13:52:25 +08:00
app.add_middleware(
CORSMiddleware,
2024-04-20 15:11:08 +08:00
allow_origins=['*'],
2024-04-20 13:52:25 +08:00
allow_credentials=True,
2024-04-20 15:11:08 +08:00
allow_methods=['*'],
allow_headers=['*'],
2024-04-20 13:52:25 +08:00
)
2024-04-20 15:11:08 +08:00
@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]}
2024-04-20 13:52:25 +08:00
@app.get("/fetch/{id}")
async def fetch_file(id: str, range: str = Header(None)) -> StreamingResponse:
2024-04-20 15:11:08 +08:00
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"',
}
2024-04-20 13:52:25 +08:00
if range:
2024-04-20 15:11:08 +08:00
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'
2024-04-20 13:52:25 +08:00
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)