实现文件上传功能

This commit is contained in:
zhangkeyang 2024-04-20 15:11:08 +08:00
parent e664e87c59
commit 74e58fd4bb
3 changed files with 36 additions and 28 deletions

51
main.py
View File

@ -1,9 +1,8 @@
import os import os
import io
import uvicorn import uvicorn
from pathlib import Path from pathlib import Path
from fastapi import FastAPI, Header from fastapi import FastAPI, UploadFile, File, Header
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
@ -11,35 +10,43 @@ from config import ServerConfig
app = FastAPI() app = FastAPI()
app.mount('/home', StaticFiles(directory="static", html=True), name="static") app.mount('/home', StaticFiles(directory='static', html=True), name='static')
app.add_middleware( app.add_middleware(
CORSMiddleware, CORSMiddleware,
allow_origins=["*"], allow_origins=['*'],
allow_credentials=True, allow_credentials=True,
allow_methods=["*"], allow_methods=['*'],
allow_headers=["*"] 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}") @app.get("/fetch/{id}")
async def fetch_file(id: str, range: str = Header(None)) -> StreamingResponse: async def fetch_file(id: str, range: str = Header(None)) -> StreamingResponse:
video_path: Path = Path(os.path.join(ServerConfig.video_play_path, id + '.mp4')) video_path = Path(os.path.join(ServerConfig.video_play_path, id + '.mp4'))
video_size: int = video_path.stat().st_size video_size = video_path.stat().st_size
start = 0 start = 0
end = video_size - 1 end = video_size - 1
chunk_size = min(video_size, ServerConfig.video_chunk_size) chunk_size = min(video_size, ServerConfig.video_chunk_size)
headers = { headers = {
'Content-Type': 'video/mp4', 'Content-Type': 'video/mp4',
'Content-Disposition': f'attachment; filename="{id}.mp4"', 'Content-Disposition': f'attachment; filename="{id}.mp4"',
} }
if range: if range:
start, end = range.replace('bytes=', '').split('-') start, end = range.replace('bytes=', '').split('-')
start = int(start) start = int(start)
end = int(end) if end else video_size - 1 end = int(end) if end else video_size - 1
chunk_size: int = min(end - start + 1, ServerConfig.video_chunk_size) chunk_size = min(end - start + 1, ServerConfig.video_chunk_size)
headers['Content-Range'] = f'bytes {start}-{end}/{video_size}' headers['Content-Range'] = f'bytes {start}-{end}/{video_size}'
headers['Accept-Ranges'] = 'bytes' headers['Accept-Ranges'] = 'bytes'
headers['Content-Disposition'] = 'inline' headers['Content-Disposition'] = 'inline'
def file_reader(): def file_reader():
with open(video_path, 'rb') as video: with open(video_path, 'rb') as video:
video.seek(start) video.seek(start)

View File

@ -6,3 +6,4 @@ opencv-python==4.9.0.80
opencv-contrib-python==4.9.0.80 opencv-contrib-python==4.9.0.80
uvicorn==0.29.0 uvicorn==0.29.0
fastapi==0.110.2 fastapi==0.110.2
python-multipart==0.0.9

View File

@ -26,7 +26,6 @@ function onSelectVideoButtonClicked() {
function onUploadVideoChanged(files) { function onUploadVideoChanged(files) {
for (var index = 0; index < files.length; index++) { for (var index = 0; index < files.length; index++) {
var file = files[index]; var file = files[index];
console.log(index);
if (file.type != 'video/mp4') { if (file.type != 'video/mp4') {
errorModal('错误', `文件${file.name}的格式错误`); errorModal('错误', `文件${file.name}的格式错误`);
return; return;
@ -70,6 +69,7 @@ function onFileUploadFinished(index, file, data) {
$(`#stat-label-${index}`).html('正在提取'); $(`#stat-label-${index}`).html('正在提取');
$(`#stat-prog-${index}`).css({'width': '0%'}); $(`#stat-prog-${index}`).css({'width': '0%'});
$(`#stat-prog-${index}`).html('0%'); $(`#stat-prog-${index}`).html('0%');
} }
/** /**
@ -114,7 +114,11 @@ function uploadFile(index, file) {
processData: false, // 不处理发送的数据 processData: false, // 不处理发送的数据
contentType: false, // 不设置内容类型 contentType: false, // 不设置内容类型
success: function(data) { success: function(data) {
onFileUploadFinished(index, file, data); if (data.status != 200) {
//TODO: 添加错误处理
} else {
onFileUploadFinished(index, file, data);
}
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
if (xhr.status == 0) { if (xhr.status == 0) {
@ -187,7 +191,3 @@ $(document).ready(function() {
onUploadVideoChanged(files); onUploadVideoChanged(files);
}); });
}); });
$(document).ready(function() {
playFile(0, null, '123');
});