auto-save 2026-05-13 20:56 (~7)

This commit is contained in:
2026-05-13 20:56:56 +08:00
parent a8d09010b6
commit 5bb24487d3
7 changed files with 53 additions and 56 deletions

View File

@@ -14,6 +14,7 @@ VIDEO_MODEL_VEO3=veo3
VIDEO_API_BASE_URL=
VIDEO_API_KEY=
VIDEO_CREATE_PATH=/videos
VIDEO_CREATE_PATHS=/videos,/videos/generations,/video/generations
VIDEO_STATUS_PATH=/videos/{id}
VIDEO_CONTENT_PATH=/videos/{id}/content
VIDEO_DURATION_FIELD=seconds

View File

@@ -35,10 +35,17 @@ VIDEO_MODEL_ALIASES = {
"seedance": os.getenv("VIDEO_MODEL_SEEDANCE", "seedance").strip() or "seedance",
"kling": os.getenv("VIDEO_MODEL_KLING", "kling").strip() or "kling",
"veo3": os.getenv("VIDEO_MODEL_VEO3", "veo3").strip() or "veo3",
"veo": os.getenv("VIDEO_MODEL_VEO3", "veo3").strip() or "veo3",
"voe": os.getenv("VIDEO_MODEL_VEO3", "veo3").strip() or "veo3",
}
VIDEO_API_BASE_URL = os.getenv("VIDEO_API_BASE_URL", "").strip()
VIDEO_API_KEY = os.getenv("VIDEO_API_KEY", "").strip()
VIDEO_CREATE_PATH = os.getenv("VIDEO_CREATE_PATH", "/videos").strip() or "/videos"
VIDEO_CREATE_PATHS = [
p.strip()
for p in os.getenv("VIDEO_CREATE_PATHS", f"{VIDEO_CREATE_PATH},/videos/generations,/video/generations").split(",")
if p.strip()
]
VIDEO_STATUS_PATH = os.getenv("VIDEO_STATUS_PATH", "/videos/{id}").strip() or "/videos/{id}"
VIDEO_CONTENT_PATH = os.getenv("VIDEO_CONTENT_PATH", "/videos/{id}/content").strip() or "/videos/{id}/content"
VIDEO_DURATION_FIELD = os.getenv("VIDEO_DURATION_FIELD", "seconds").strip() or "seconds"
@@ -210,14 +217,6 @@ def video_path(template: str, **values: str) -> str:
def ensure_video_api_configured() -> None:
base = video_api_base()
# 已探测SKG ezlink 当前只开了 chat/images/videos 返回 404。
# 没有显式 VIDEO_API_BASE_URL 时,不再把这个 404 伪装成一次“生成失败”。
if not VIDEO_API_BASE_URL and "ai.skg.com/ezlink" in base:
raise HTTPException(
503,
"当前 SKG ezlink baseurl 已连通,但这把 key 未开通生视频 /videos 端点;需要 IT 给该分组开通视频端点,或改用真实 Seedance/Kling/Veo 3 视频 API。",
)
if not video_api_key():
raise HTTPException(503, "VIDEO_API_KEY 或 LLM_API_KEY 未配置,无法调用生视频 API")
@@ -790,7 +789,8 @@ def health() -> dict:
"video": VIDEO_MODEL,
"video_aliases": VIDEO_MODEL_ALIASES,
"video_base_url": video_api_base() if VIDEO_API_BASE_URL else "",
"video_configured": bool(VIDEO_API_BASE_URL and video_api_key()),
"video_configured": bool(video_api_key()),
"video_create_paths": VIDEO_CREATE_PATHS,
},
}
@@ -1694,14 +1694,24 @@ def render_storyboard_video(job_id: str, local_id: str, provider_id: str, ref_pa
with httpx.Client(timeout=120) as client:
payload = {"model": model, "prompt": prompt, "size": size}
payload[VIDEO_DURATION_FIELD] = seconds
with ref_img.open("rb") as fh:
create = client.post(
f"{base}{video_path(VIDEO_CREATE_PATH)}",
headers=headers,
data=payload,
files={"input_reference": ("reference.jpg", fh, "image/jpeg")},
)
create.raise_for_status()
create = None
create_errors: list[str] = []
for create_path in VIDEO_CREATE_PATHS:
with ref_img.open("rb") as fh:
resp = client.post(
f"{base}{video_path(create_path)}",
headers=headers,
data=payload,
files={"input_reference": ("reference.jpg", fh, "image/jpeg")},
)
if resp.status_code < 400:
create = resp
break
create_errors.append(f"{video_path(create_path)} -> HTTP {resp.status_code}: {resp.text[:160]}")
if resp.status_code not in {400, 404, 405}:
resp.raise_for_status()
if create is None:
raise RuntimeError("视频模型已选择,但当前网关视频生成入口不可用;已尝试 " + " | ".join(create_errors))
data = create.json()
video_api_id = data.get("id") or provider_id or local_id
status = normalize_video_status(data.get("status"))