Files
ViGent2/backend/app/modules/videos/service.py
Kevin Wong be6a3436bb 更新
2026-02-05 12:03:55 +08:00

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)}")