88 lines
2.7 KiB
Python
88 lines
2.7 KiB
Python
from fastapi import HTTPException
|
|
import asyncio
|
|
from pathlib import Path
|
|
from loguru import logger
|
|
|
|
from app.services.storage import storage_service
|
|
|
|
|
|
async def list_generated_videos(user_id: str) -> dict:
|
|
"""从 Storage 读取当前用户生成的视频列表"""
|
|
try:
|
|
files_obj = await storage_service.list_files(
|
|
bucket=storage_service.BUCKET_OUTPUTS,
|
|
path=user_id
|
|
)
|
|
|
|
semaphore = asyncio.Semaphore(8)
|
|
|
|
async def build_item(f):
|
|
name = f.get("name")
|
|
if not name or name == ".emptyFolderPlaceholder":
|
|
return None
|
|
|
|
if not name.endswith("_output.mp4"):
|
|
return None
|
|
|
|
video_id = Path(name).stem
|
|
full_path = f"{user_id}/{name}"
|
|
|
|
async with semaphore:
|
|
signed_url = await storage_service.get_signed_url(
|
|
bucket=storage_service.BUCKET_OUTPUTS,
|
|
path=full_path
|
|
)
|
|
|
|
metadata = f.get("metadata", {})
|
|
size = metadata.get("size", 0)
|
|
created_at_str = f.get("created_at", "")
|
|
created_at = 0
|
|
if created_at_str:
|
|
from datetime import datetime
|
|
try:
|
|
dt = datetime.fromisoformat(created_at_str.replace("Z", "+00:00"))
|
|
created_at = int(dt.timestamp())
|
|
except Exception:
|
|
pass
|
|
|
|
return {
|
|
"id": video_id,
|
|
"name": name,
|
|
"path": signed_url,
|
|
"size_mb": size / (1024 * 1024),
|
|
"created_at": created_at
|
|
}
|
|
|
|
tasks = [build_item(f) for f in files_obj]
|
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
|
|
videos = []
|
|
for item in results:
|
|
if not item:
|
|
continue
|
|
if isinstance(item, Exception):
|
|
logger.warning(f"Signed url build failed: {item}")
|
|
continue
|
|
videos.append(item)
|
|
|
|
videos.sort(key=lambda x: x.get("created_at", ""), reverse=True)
|
|
return {"videos": videos}
|
|
|
|
except Exception as e:
|
|
logger.error(f"List generated videos failed: {e}")
|
|
return {"videos": []}
|
|
|
|
|
|
async def delete_generated_video(user_id: str, video_id: str) -> dict:
|
|
"""删除生成的视频"""
|
|
try:
|
|
storage_path = f"{user_id}/{video_id}.mp4"
|
|
|
|
await storage_service.delete_file(
|
|
bucket=storage_service.BUCKET_OUTPUTS,
|
|
path=storage_path
|
|
)
|
|
return {"video_id": video_id}
|
|
except Exception as e:
|
|
raise HTTPException(500, f"删除失败: {str(e)}")
|