auto-save 2026-05-27 23:01 (~5)
This commit is contained in:
@@ -1,32 +1,5 @@
|
|||||||
{
|
{
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"files_changed": 6,
|
|
||||||
"hash": "92a7f2f",
|
|
||||||
"message": "auto-save 2026-05-20 20:00 (+1, ~2)",
|
|
||||||
"ts": "2026-05-20T20:00:28+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 2,
|
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 2 项未提交变更 · 最近提交:auto-save 2026-05-20 20:00 (+1, ~2)",
|
|
||||||
"ts": "2026-05-20T12:05:32Z",
|
|
||||||
"type": "session-heartbeat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 2,
|
|
||||||
"hash": "2544e09",
|
|
||||||
"message": "auto-save 2026-05-20 20:05 (~2)",
|
|
||||||
"ts": "2026-05-20T20:05:54+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 2,
|
|
||||||
"hash": "f0f567b",
|
|
||||||
"message": "fix: center scaled workbench vertically",
|
|
||||||
"ts": "2026-05-20T20:09:39+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"files_changed": 1,
|
"files_changed": 1,
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:fix: center scaled workbench vertically",
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:fix: center scaled workbench vertically",
|
||||||
@@ -3198,6 +3171,34 @@
|
|||||||
"message": "auto-save 2026-05-27 18:08 (~2)",
|
"message": "auto-save 2026-05-27 18:08 (~2)",
|
||||||
"hash": "13d9057",
|
"hash": "13d9057",
|
||||||
"files_changed": 2
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-27T18:13:45+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-27 18:13 (~3)",
|
||||||
|
"hash": "0c30fb9",
|
||||||
|
"files_changed": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-27T22:14:19+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "chore: exclude local artifacts from production deploy",
|
||||||
|
"hash": "c6258e4",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-27T22:17:29+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "chore: exclude local artifacts from production deploy",
|
||||||
|
"hash": "bf85f00",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-27T22:20:48+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "chore: harden production deploy scripts",
|
||||||
|
"hash": "b6a7e7b",
|
||||||
|
"files_changed": 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
74
api/main.py
74
api/main.py
@@ -259,6 +259,11 @@ VIDEO_SIZE_CHOICES = [
|
|||||||
"description": "适合更接近图文卡片的竖版素材",
|
"description": "适合更接近图文卡片的竖版素材",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
VIDEO_RESOLUTION_CHOICES = [
|
||||||
|
{"id": "480p", "label": "480p", "value": "480p", "description": "低清预览,生成更快"},
|
||||||
|
{"id": "720p", "label": "720p", "value": "720p", "description": "日常短视频默认清晰度"},
|
||||||
|
{"id": "1080p", "label": "1080p 高清", "value": "1080p", "description": "Seedance 2.0 标准版高清输出"},
|
||||||
|
]
|
||||||
SubjectModelBundle = Literal["gpt", "gemini"]
|
SubjectModelBundle = Literal["gpt", "gemini"]
|
||||||
SubjectAgentMode = Literal["realistic", "cartoon", "elements", "custom"]
|
SubjectAgentMode = Literal["realistic", "cartoon", "elements", "custom"]
|
||||||
SUBJECT_AGENT_GPT_MODEL = gpt_model_env("SUBJECT_AGENT_GPT_MODEL", VISION_MODEL)
|
SUBJECT_AGENT_GPT_MODEL = gpt_model_env("SUBJECT_AGENT_GPT_MODEL", VISION_MODEL)
|
||||||
@@ -324,6 +329,7 @@ def env_video_model(name: str, default: str) -> str:
|
|||||||
|
|
||||||
VIDEO_MODEL_ALIASES = {
|
VIDEO_MODEL_ALIASES = {
|
||||||
"seedance": env_video_model("VIDEO_MODEL_SEEDANCE", "seedance-2-fast"),
|
"seedance": env_video_model("VIDEO_MODEL_SEEDANCE", "seedance-2-fast"),
|
||||||
|
"seedance_hd": env_video_model("VIDEO_MODEL_SEEDANCE_HD", "doubao-seedance-2-0-260128"),
|
||||||
"kling": env_video_model("VIDEO_MODEL_KLING", "kling-omni"),
|
"kling": env_video_model("VIDEO_MODEL_KLING", "kling-omni"),
|
||||||
"veo3": env_video_model("VIDEO_MODEL_VEO3", "veo-3.1-fast"),
|
"veo3": env_video_model("VIDEO_MODEL_VEO3", "veo-3.1-fast"),
|
||||||
"veo": env_video_model("VIDEO_MODEL_VEO3", "veo-3.1-fast"),
|
"veo": env_video_model("VIDEO_MODEL_VEO3", "veo-3.1-fast"),
|
||||||
@@ -554,6 +560,7 @@ class GeneratedVideo(BaseModel):
|
|||||||
url: str = ""
|
url: str = ""
|
||||||
poster_url: str = ""
|
poster_url: str = ""
|
||||||
duration: float = 4.0
|
duration: float = 4.0
|
||||||
|
resolution: str = "720p"
|
||||||
progress: int = 0
|
progress: int = 0
|
||||||
error: str = ""
|
error: str = ""
|
||||||
created_at: float = 0.0
|
created_at: float = 0.0
|
||||||
@@ -4875,6 +4882,52 @@ def video_size_options() -> list[dict]:
|
|||||||
return VIDEO_SIZE_CHOICES
|
return VIDEO_SIZE_CHOICES
|
||||||
|
|
||||||
|
|
||||||
|
def _video_resolution_choice(value: str) -> dict:
|
||||||
|
return next(
|
||||||
|
(item for item in VIDEO_RESOLUTION_CHOICES if item["value"] == value),
|
||||||
|
{"id": value, "label": value, "value": value, "description": ""},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _video_resolution_values_for_model(model: str | None) -> list[str]:
|
||||||
|
concrete = (model or "").strip().lower()
|
||||||
|
if video_uses_ark():
|
||||||
|
if "seedance-2-0-fast" in concrete:
|
||||||
|
return ["480p", "720p"]
|
||||||
|
if "seedance-2-0" in concrete or "seedance-1-5-pro" in concrete or "seedance-1-0-pro" in concrete:
|
||||||
|
return ["480p", "720p", "1080p"]
|
||||||
|
return ["720p"]
|
||||||
|
|
||||||
|
|
||||||
|
def video_resolution_options(model: str | None = None) -> list[dict]:
|
||||||
|
return [_video_resolution_choice(value) for value in _video_resolution_values_for_model(model or resolve_video_model(VIDEO_MODEL))]
|
||||||
|
|
||||||
|
|
||||||
|
def default_video_resolution(model: str | None = None) -> str:
|
||||||
|
values = _video_resolution_values_for_model(model or resolve_video_model(VIDEO_MODEL))
|
||||||
|
return "1080p" if "1080p" in values and "fast" not in (model or "").lower() else (values[-1] if values else "720p")
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_video_resolution(raw: str | None, model: str | None = None) -> str:
|
||||||
|
value = (raw or default_video_resolution(model)).strip().lower().replace(" ", "")
|
||||||
|
aliases = {
|
||||||
|
"sd": "480p",
|
||||||
|
"ld": "480p",
|
||||||
|
"low": "480p",
|
||||||
|
"standard": "720p",
|
||||||
|
"std": "720p",
|
||||||
|
"hd": "1080p",
|
||||||
|
"high": "1080p",
|
||||||
|
"高清": "1080p",
|
||||||
|
}
|
||||||
|
value = aliases.get(value, value)
|
||||||
|
allowed = set(_video_resolution_values_for_model(model or resolve_video_model(VIDEO_MODEL)))
|
||||||
|
if value not in allowed:
|
||||||
|
label = model or VIDEO_MODEL
|
||||||
|
raise HTTPException(400, f"unsupported video resolution for {label}: {raw}")
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def _normalize_video_size(raw: str | None) -> str:
|
def _normalize_video_size(raw: str | None) -> str:
|
||||||
value = (raw or "720x1280").strip().lower().replace(" ", "")
|
value = (raw or "720x1280").strip().lower().replace(" ", "")
|
||||||
aliases = {
|
aliases = {
|
||||||
@@ -4901,6 +4954,7 @@ def _normalize_video_size(raw: str | None) -> str:
|
|||||||
def video_model_options() -> list[dict]:
|
def video_model_options() -> list[dict]:
|
||||||
label_map = {
|
label_map = {
|
||||||
"seedance": "Seedance 2.0 Fast",
|
"seedance": "Seedance 2.0 Fast",
|
||||||
|
"seedance_hd": "Seedance 2.0 高清",
|
||||||
"kling": "Kling",
|
"kling": "Kling",
|
||||||
"veo3": "Veo 3",
|
"veo3": "Veo 3",
|
||||||
"veo": "Veo",
|
"veo": "Veo",
|
||||||
@@ -4908,10 +4962,11 @@ def video_model_options() -> list[dict]:
|
|||||||
}
|
}
|
||||||
concrete_label_map = {
|
concrete_label_map = {
|
||||||
"doubao-seedance-2-0-fast-260128": "Seedance 2.0 Fast",
|
"doubao-seedance-2-0-fast-260128": "Seedance 2.0 Fast",
|
||||||
|
"doubao-seedance-2-0-260128": "Seedance 2.0 高清",
|
||||||
}
|
}
|
||||||
seen_models: set[str] = set()
|
seen_models: set[str] = set()
|
||||||
options: list[dict] = []
|
options: list[dict] = []
|
||||||
for key in ["seedance", "kling", "veo3", "veo"]:
|
for key in ["seedance", "seedance_hd", "kling", "veo3", "veo"]:
|
||||||
if key not in VIDEO_MODEL_ALIASES:
|
if key not in VIDEO_MODEL_ALIASES:
|
||||||
continue
|
continue
|
||||||
model = VIDEO_MODEL_ALIASES[key]
|
model = VIDEO_MODEL_ALIASES[key]
|
||||||
@@ -4925,6 +4980,8 @@ def video_model_options() -> list[dict]:
|
|||||||
"description": f"当前视频网关可选模型;单次时长最高 {max(video_duration_options())} 秒",
|
"description": f"当前视频网关可选模型;单次时长最高 {max(video_duration_options())} 秒",
|
||||||
"duration_options": video_duration_options(),
|
"duration_options": video_duration_options(),
|
||||||
"size_options": video_size_options(),
|
"size_options": video_size_options(),
|
||||||
|
"resolution_options": video_resolution_options(model),
|
||||||
|
"default_resolution": default_video_resolution(model),
|
||||||
"max_duration_seconds": max(video_duration_options()),
|
"max_duration_seconds": max(video_duration_options()),
|
||||||
"available": bool(video_api_key()),
|
"available": bool(video_api_key()),
|
||||||
})
|
})
|
||||||
@@ -4937,6 +4994,8 @@ def video_model_options() -> list[dict]:
|
|||||||
"description": "默认视频模型",
|
"description": "默认视频模型",
|
||||||
"duration_options": video_duration_options(),
|
"duration_options": video_duration_options(),
|
||||||
"size_options": video_size_options(),
|
"size_options": video_size_options(),
|
||||||
|
"resolution_options": video_resolution_options(default_model),
|
||||||
|
"default_resolution": default_video_resolution(default_model),
|
||||||
"max_duration_seconds": max(video_duration_options()),
|
"max_duration_seconds": max(video_duration_options()),
|
||||||
"available": bool(video_api_key()),
|
"available": bool(video_api_key()),
|
||||||
})
|
})
|
||||||
@@ -6420,6 +6479,7 @@ def health() -> dict:
|
|||||||
"video_duration_options": video_duration_options(),
|
"video_duration_options": video_duration_options(),
|
||||||
"video_max_duration_seconds": max(video_duration_options()),
|
"video_max_duration_seconds": max(video_duration_options()),
|
||||||
"video_size_options": video_size_options(),
|
"video_size_options": video_size_options(),
|
||||||
|
"video_resolution_options": video_resolution_options(),
|
||||||
"video_provider": video_provider_name(),
|
"video_provider": video_provider_name(),
|
||||||
"video_base_url": video_api_base(),
|
"video_base_url": video_api_base(),
|
||||||
"video_configured": bool(video_api_key()),
|
"video_configured": bool(video_api_key()),
|
||||||
@@ -8473,6 +8533,7 @@ class GenerateStoryboardVideoReq(BaseModel):
|
|||||||
source_ref: VideoSourceRef | None = None
|
source_ref: VideoSourceRef | None = None
|
||||||
model: str = ""
|
model: str = ""
|
||||||
size: str = "720x1280"
|
size: str = "720x1280"
|
||||||
|
resolution: str = ""
|
||||||
|
|
||||||
|
|
||||||
class QuickStoryboardPlanReq(BaseModel):
|
class QuickStoryboardPlanReq(BaseModel):
|
||||||
@@ -8499,6 +8560,7 @@ class BatchGenerateStoryboardReq(BaseModel):
|
|||||||
concurrency: int = 1
|
concurrency: int = 1
|
||||||
model: str = ""
|
model: str = ""
|
||||||
size: str = "720x1280"
|
size: str = "720x1280"
|
||||||
|
resolution: str = ""
|
||||||
|
|
||||||
|
|
||||||
def _quick_field_en(en: str, zh: str) -> str:
|
def _quick_field_en(en: str, zh: str) -> str:
|
||||||
@@ -8906,7 +8968,7 @@ def submit_video_create(
|
|||||||
"ratio": size_to_video_ratio(str(payload.get("size", ""))),
|
"ratio": size_to_video_ratio(str(payload.get("size", ""))),
|
||||||
"duration": int(float(str(payload.get(VIDEO_DURATION_FIELD, 5)))),
|
"duration": int(float(str(payload.get(VIDEO_DURATION_FIELD, 5)))),
|
||||||
"watermark": False,
|
"watermark": False,
|
||||||
"resolution": "720p",
|
"resolution": _normalize_video_resolution(str(payload.get("resolution") or ""), str(payload.get("model") or "")),
|
||||||
}
|
}
|
||||||
return client.post(url, headers={**headers, "Content-Type": "application/json"}, json=data)
|
return client.post(url, headers={**headers, "Content-Type": "application/json"}, json=data)
|
||||||
|
|
||||||
@@ -8934,6 +8996,7 @@ def render_storyboard_video(
|
|||||||
model: str,
|
model: str,
|
||||||
seconds: str,
|
seconds: str,
|
||||||
size: str,
|
size: str,
|
||||||
|
resolution: str = "",
|
||||||
source_ref: VideoSourceRef | None = None,
|
source_ref: VideoSourceRef | None = None,
|
||||||
last_ref_path: Path | None = None,
|
last_ref_path: Path | None = None,
|
||||||
product_ref_paths: list[Path] | None = None,
|
product_ref_paths: list[Path] | None = None,
|
||||||
@@ -8962,7 +9025,7 @@ def render_storyboard_video(
|
|||||||
prepared_product_imgs.append(product_img)
|
prepared_product_imgs.append(product_img)
|
||||||
update_generated_video(job_id, local_id, status="in_progress", progress=5, queue_message="准备素材…")
|
update_generated_video(job_id, local_id, status="in_progress", progress=5, queue_message="准备素材…")
|
||||||
with httpx.Client(timeout=120) as client:
|
with httpx.Client(timeout=120) as client:
|
||||||
payload = {"model": model, "prompt": prompt, "size": size}
|
payload = {"model": model, "prompt": prompt, "size": size, "resolution": resolution}
|
||||||
payload[VIDEO_DURATION_FIELD] = seconds
|
payload[VIDEO_DURATION_FIELD] = seconds
|
||||||
create = None
|
create = None
|
||||||
create_errors: list[str] = []
|
create_errors: list[str] = []
|
||||||
@@ -9150,6 +9213,7 @@ def _enqueue_storyboard_videos(job: Job, frame: KeyFrame, req: GenerateStoryboar
|
|||||||
model = resolve_video_model(req.model)
|
model = resolve_video_model(req.model)
|
||||||
seconds = video_seconds(float(req.duration or 4))
|
seconds = video_seconds(float(req.duration or 4))
|
||||||
video_size = _normalize_video_size(req.size)
|
video_size = _normalize_video_size(req.size)
|
||||||
|
video_resolution = _normalize_video_resolution(req.resolution, model)
|
||||||
source_ref = req.source_ref
|
source_ref = req.source_ref
|
||||||
if source_ref and source_ref.kind == "source_video" and not source_ref.url:
|
if source_ref and source_ref.kind == "source_video" and not source_ref.url:
|
||||||
source_ref = None
|
source_ref = None
|
||||||
@@ -9174,11 +9238,12 @@ def _enqueue_storyboard_videos(job: Job, frame: KeyFrame, req: GenerateStoryboar
|
|||||||
url="",
|
url="",
|
||||||
poster_url=poster,
|
poster_url=poster,
|
||||||
duration=float(seconds),
|
duration=float(seconds),
|
||||||
|
resolution=video_resolution,
|
||||||
progress=0,
|
progress=0,
|
||||||
created_at=time.time(),
|
created_at=time.time(),
|
||||||
queue_message="排队中…",
|
queue_message="排队中…",
|
||||||
))
|
))
|
||||||
task_args = (job.id, local_id, "", ref_path, variant_prompt, model, seconds, video_size, source_ref, last_ref_path, reference_ref_paths, primary_role)
|
task_args = (job.id, local_id, "", ref_path, variant_prompt, model, seconds, video_size, video_resolution, source_ref, last_ref_path, reference_ref_paths, primary_role)
|
||||||
queued_tasks.append((local_id, task_args))
|
queued_tasks.append((local_id, task_args))
|
||||||
update(job, generated_videos=items + job.generated_videos, message=f"视频候选已提交 · 分镜 {frame.index + 1} · {count} 条")
|
update(job, generated_videos=items + job.generated_videos, message=f"视频候选已提交 · 分镜 {frame.index + 1} · {count} 条")
|
||||||
for local_id, task_args in queued_tasks:
|
for local_id, task_args in queued_tasks:
|
||||||
@@ -9239,6 +9304,7 @@ def _batch_generate_worker(job_id: str, req: BatchGenerateStoryboardReq) -> None
|
|||||||
action_image=scene.action_image,
|
action_image=scene.action_image,
|
||||||
model=req.model,
|
model=req.model,
|
||||||
size=req.size,
|
size=req.size,
|
||||||
|
resolution=req.resolution,
|
||||||
)
|
)
|
||||||
_enqueue_storyboard_videos(job, frame, video_req, None)
|
_enqueue_storyboard_videos(job, frame, video_req, None)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -123,10 +123,27 @@ export const VIDEO_MODELS = [
|
|||||||
{ label: '12 秒', key: 12 },
|
{ label: '12 秒', key: 12 },
|
||||||
{ label: '15 秒', key: 15 }
|
{ label: '15 秒', key: 15 }
|
||||||
],
|
],
|
||||||
resolutions: ['720p'],
|
resolutions: ['480p', '720p'],
|
||||||
defaultResolution: '720p',
|
defaultResolution: '720p',
|
||||||
defaultParams: { ratio: '720x1280', duration: 10, resolution: '720p' }
|
defaultParams: { ratio: '720x1280', duration: 10, resolution: '720p' }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Seedance 2.0 高清',
|
||||||
|
key: 'seedance_hd',
|
||||||
|
provider: ['chatfire'],
|
||||||
|
type: 't2v+i2v',
|
||||||
|
ratios: ['720x1280', '1280x720', '1024x1024', '960x1280'],
|
||||||
|
durs: [
|
||||||
|
{ label: '5 秒', key: 5 },
|
||||||
|
{ label: '8 秒', key: 8 },
|
||||||
|
{ label: '10 秒', key: 10 },
|
||||||
|
{ label: '12 秒', key: 12 },
|
||||||
|
{ label: '15 秒', key: 15 }
|
||||||
|
],
|
||||||
|
resolutions: ['480p', '720p', '1080p'],
|
||||||
|
defaultResolution: '1080p',
|
||||||
|
defaultParams: { ratio: '720x1280', duration: 10, resolution: '1080p' }
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
// Chat/LLM models | 对话模型
|
// Chat/LLM models | 对话模型
|
||||||
|
|||||||
@@ -149,7 +149,10 @@ export const getModelDurationOptions = (modelKey) => {
|
|||||||
* Returns options based on model's resolutions array
|
* Returns options based on model's resolutions array
|
||||||
*/
|
*/
|
||||||
export const getModelResolutionOptions = (modelKey) => {
|
export const getModelResolutionOptions = (modelKey) => {
|
||||||
const model = VIDEO_MODELS.find(m => m.key === modelKey)
|
const model = getModelConfig(modelKey) || VIDEO_MODELS.find(m => m.key === modelKey)
|
||||||
|
if (model?.resolutionOptions) {
|
||||||
|
return model.resolutionOptions
|
||||||
|
}
|
||||||
if (!model?.resolutions) return SEEDANCE_RESOLUTION_OPTIONS
|
if (!model?.resolutions) return SEEDANCE_RESOLUTION_OPTIONS
|
||||||
|
|
||||||
return model.resolutions.map(res => {
|
return model.resolutions.map(res => {
|
||||||
|
|||||||
@@ -153,11 +153,28 @@ const normalizeRuntimeDurationOptions = (items = []) => {
|
|||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const normalizeRuntimeResolutionOptions = (items = []) => {
|
||||||
|
if (!Array.isArray(items)) return []
|
||||||
|
return items
|
||||||
|
.map(item => {
|
||||||
|
const key = typeof item === 'object' ? item?.value || item?.key || item?.id : item
|
||||||
|
if (!key) return null
|
||||||
|
return {
|
||||||
|
label: typeof item === 'object' ? item.label || key : key,
|
||||||
|
key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
const normalizeRuntimeVideoModel = (item) => {
|
const normalizeRuntimeVideoModel = (item) => {
|
||||||
const key = item?.id || item?.model
|
const key = item?.id || item?.model
|
||||||
if (!key) return null
|
if (!key) return null
|
||||||
const sizeOptions = normalizeRuntimeSizeOptions(item.size_options)
|
const sizeOptions = normalizeRuntimeSizeOptions(item.size_options)
|
||||||
const durationOptions = normalizeRuntimeDurationOptions(item.duration_options)
|
const durationOptions = normalizeRuntimeDurationOptions(item.duration_options)
|
||||||
|
const resolutionOptions = normalizeRuntimeResolutionOptions(item.resolution_options)
|
||||||
|
const resolutions = resolutionOptions.map(option => option.key)
|
||||||
|
const defaultResolution = item.default_resolution || resolutions[0] || '720p'
|
||||||
return {
|
return {
|
||||||
label: item.label || item.model || key,
|
label: item.label || item.model || key,
|
||||||
key,
|
key,
|
||||||
@@ -166,12 +183,13 @@ const normalizeRuntimeVideoModel = (item) => {
|
|||||||
model: item.model,
|
model: item.model,
|
||||||
ratios: sizeOptions.map(option => option.key),
|
ratios: sizeOptions.map(option => option.key),
|
||||||
durs: durationOptions,
|
durs: durationOptions,
|
||||||
resolutions: ['720p'],
|
resolutions,
|
||||||
defaultResolution: '720p',
|
resolutionOptions,
|
||||||
|
defaultResolution,
|
||||||
defaultParams: {
|
defaultParams: {
|
||||||
ratio: sizeOptions[0]?.key || '720x1280',
|
ratio: sizeOptions[0]?.key || '720x1280',
|
||||||
duration: durationOptions[0]?.key || 5,
|
duration: durationOptions[0]?.key || 5,
|
||||||
resolution: '720p'
|
resolution: defaultResolution
|
||||||
},
|
},
|
||||||
available: item.available !== false,
|
available: item.available !== false,
|
||||||
isRuntime: true
|
isRuntime: true
|
||||||
|
|||||||
Reference in New Issue
Block a user