perf(8502): 并行生图(6并发)+超时重试;视频URL直连预览/下载;路径隔离
This commit is contained in:
@@ -12,6 +12,7 @@ from pathlib import Path
|
||||
import config
|
||||
from modules import storage
|
||||
from modules.db_manager import db
|
||||
from modules import path_utils
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -76,15 +77,7 @@ class VideoGenerator:
|
||||
logger.info(f"Recovering task {task_id}: status={status}")
|
||||
|
||||
if status == "succeeded" and video_url:
|
||||
downloaded_path = self._download_video(video_url, os.path.basename(output_path))
|
||||
if downloaded_path:
|
||||
# 如果下载的文件名和目标路径不一致 (download_video 使用 filename 参数拼接到 TEMP_DIR),
|
||||
# 需要移动或确认。 _download_video 返回完整路径。
|
||||
# 如果 output_path 是绝对路径且不同,则移动。
|
||||
if os.path.abspath(downloaded_path) != os.path.abspath(output_path):
|
||||
import shutil
|
||||
shutil.move(downloaded_path, output_path)
|
||||
return True
|
||||
return self._download_video_to(video_url, output_path)
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to recover video task {task_id}: {e}")
|
||||
@@ -144,7 +137,15 @@ class VideoGenerator:
|
||||
if status == "succeeded":
|
||||
logger.info(f"Scene {scene_id} video generated successfully")
|
||||
# 下载视频
|
||||
video_path = self._download_video(result_url, f"scene_{scene_id}_video.mp4")
|
||||
out_dir = path_utils.project_videos_dir(project_id) if project_id else config.TEMP_DIR
|
||||
fname = path_utils.unique_filename(
|
||||
prefix="scene_video",
|
||||
ext="mp4",
|
||||
project_id=project_id,
|
||||
scene_id=scene_id,
|
||||
extra=(task_id[-8:] if isinstance(task_id, str) else None),
|
||||
)
|
||||
video_path = self._download_video(result_url, fname, output_dir=out_dir)
|
||||
if video_path:
|
||||
generated_videos[scene_id] = video_path
|
||||
# Update DB
|
||||
@@ -235,13 +236,26 @@ class VideoGenerator:
|
||||
content_url = None
|
||||
|
||||
if status == "succeeded":
|
||||
if "content" in result:
|
||||
content = result["content"]
|
||||
if isinstance(content, list) and len(content) > 0:
|
||||
item = content[0]
|
||||
content_url = item.get("video_url") or item.get("url")
|
||||
elif isinstance(content, dict):
|
||||
content_url = content.get("video_url") or content.get("url")
|
||||
# Try multiple known shapes for volcengine response
|
||||
content = result.get("content")
|
||||
# sometimes nested: data.content or data.result.content, etc.
|
||||
if not content and isinstance(result.get("result"), dict):
|
||||
content = result["result"].get("content")
|
||||
|
||||
def _extract_url(obj):
|
||||
if isinstance(obj, dict):
|
||||
return obj.get("video_url") or obj.get("url")
|
||||
return None
|
||||
|
||||
if isinstance(content, list) and content:
|
||||
# pick the first item that has a usable url
|
||||
for item in content:
|
||||
u = _extract_url(item)
|
||||
if u:
|
||||
content_url = u
|
||||
break
|
||||
elif isinstance(content, dict):
|
||||
content_url = _extract_url(content)
|
||||
|
||||
return status, content_url
|
||||
|
||||
@@ -249,8 +263,26 @@ class VideoGenerator:
|
||||
logger.error(f"Check task failed: {e}")
|
||||
return "unknown", None
|
||||
|
||||
def _download_video(self, url: str, filename: str) -> str:
|
||||
"""下载视频到临时目录"""
|
||||
def _download_video_to(self, url: str, output_path: str) -> bool:
|
||||
"""下载视频到指定路径(避免 TEMP_DIR 固定文件名导致覆盖)"""
|
||||
if not url or not output_path:
|
||||
return False
|
||||
try:
|
||||
out_p = Path(output_path)
|
||||
out_p.parent.mkdir(parents=True, exist_ok=True)
|
||||
response = requests.get(url, stream=True, timeout=60)
|
||||
response.raise_for_status()
|
||||
with open(out_p, "wb") as f:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
if chunk:
|
||||
f.write(chunk)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Download video failed: {e}")
|
||||
return False
|
||||
|
||||
def _download_video(self, url: str, filename: str, output_dir: Optional[Path] = None) -> str:
|
||||
"""下载视频到临时目录(默认使用 config.TEMP_DIR;可指定 output_dir 避免覆盖)"""
|
||||
if not url:
|
||||
return None
|
||||
|
||||
@@ -258,10 +290,13 @@ class VideoGenerator:
|
||||
response = requests.get(url, stream=True, timeout=60)
|
||||
response.raise_for_status()
|
||||
|
||||
output_path = config.TEMP_DIR / filename
|
||||
out_dir = output_dir or config.TEMP_DIR
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = out_dir / filename
|
||||
with open(output_path, "wb") as f:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
if chunk:
|
||||
f.write(chunk)
|
||||
|
||||
return str(output_path)
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user