auto-save 2026-05-18 00:29 (~8)
This commit is contained in:
@@ -1,18 +1,5 @@
|
|||||||
{
|
{
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"hash": "45e7401",
|
|
||||||
"message": "auto-save 2026-05-15 15:32 (~1)",
|
|
||||||
"ts": "2026-05-15T15:32:22+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 1 项未提交变更 · 最近提交:auto-save 2026-05-15 15:32 (~1)",
|
|
||||||
"ts": "2026-05-15T07:34:47Z",
|
|
||||||
"type": "session-heartbeat"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"files_changed": 1,
|
"files_changed": 1,
|
||||||
"hash": "26f5d2e",
|
"hash": "26f5d2e",
|
||||||
@@ -3258,6 +3245,19 @@
|
|||||||
"type": "session-heartbeat",
|
"type": "session-heartbeat",
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:fix: show generated subject views",
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:fix: show generated subject views",
|
||||||
"files_changed": 1
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-18T00:23:43+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-18 00:23 (~2)",
|
||||||
|
"hash": "a7b1315",
|
||||||
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-17T16:28:31Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 8 项未提交变更 · 最近提交:auto-save 2026-05-18 00:23 (~2)",
|
||||||
|
"files_changed": 8
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,18 @@
|
|||||||
"storage": "api/.env",
|
"storage": "api/.env",
|
||||||
"type": "api_key"
|
"type": "api_key"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "OpenAI-compatible GPT 图片模型 Key;未单独配置 IMAGE_API_KEY 时复用 LLM_API_KEY,本地开发只放 api/.env,不入库",
|
||||||
|
"name": "IMAGE_API_KEY",
|
||||||
|
"storage": "api/.env / deploy/.env.production",
|
||||||
|
"type": "api_key"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Azure OpenAI 协议语音/配音 Key;未单独配置 AZURE_OPENAI_API_KEY 时复用 LLM_API_KEY,本地开发只放 api/.env,不入库",
|
||||||
|
"name": "AZURE_OPENAI_API_KEY",
|
||||||
|
"storage": "api/.env / deploy/.env.production",
|
||||||
|
"type": "api_key"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "SKG 豆包 / Seedance 视频生成 API Key,生产只放服务器 deploy/.env.production 的 VIDEO_API_KEY,本地开发放 api/.env,不入库",
|
"description": "SKG 豆包 / Seedance 视频生成 API Key,生产只放服务器 deploy/.env.production 的 VIDEO_API_KEY,本地开发放 api/.env,不入库",
|
||||||
"name": "VIDEO_API_KEY",
|
"name": "VIDEO_API_KEY",
|
||||||
@@ -52,7 +64,7 @@
|
|||||||
"username": "skg"
|
"username": "skg"
|
||||||
},
|
},
|
||||||
"stack": [
|
"stack": [
|
||||||
"Next.js + Python(yt-dlp/ffmpeg) + OpenAI-compatible LLM + MiniMax T2A + nano-banana-pro/GPT Image + Seedance/Kling/Veo3"
|
"Next.js + Python(yt-dlp/ffmpeg) + OpenAI-compatible LLM + GPT Image + Azure OpenAI TTS + Seedance"
|
||||||
],
|
],
|
||||||
"status": "active",
|
"status": "active",
|
||||||
"urls": [
|
"urls": [
|
||||||
|
|||||||
9
RULES.md
9
RULES.md
@@ -50,7 +50,7 @@
|
|||||||
- 能联网和鉴权时必须 `git push origin main`;如果不能推送,最终回复必须写清楚当前分支、领先/落后数量、最新未推送 commit 和失败原因
|
- 能联网和鉴权时必须 `git push origin main`;如果不能推送,最终回复必须写清楚当前分支、领先/落后数量、最新未推送 commit 和失败原因
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
- `LLM_BASE_URL` / `LLM_API_KEY`:OpenAI 兼容网关,用于 ASR、翻译、文案改写、图像等模型调用
|
- `LLM_BASE_URL` / `LLM_API_KEY`:OpenAI 兼容网关,用于 ASR、翻译、文案改写、音频分析等文本/音频理解模型调用
|
||||||
- `ASR_MODEL`:OpenAI Audio Transcriptions 音频转写模型,默认 `whisper-1`
|
- `ASR_MODEL`:OpenAI Audio Transcriptions 音频转写模型,默认 `whisper-1`
|
||||||
- `ASR_FALLBACK_MODEL`:远端 ASR 和本机 ASR 都不可用时才尝试的多模态兜底,默认 `gemini-2.5-flash`;如果模型不能真实听到音频或返回疑似逐秒假字幕,后端必须拒绝写入时间轴
|
- `ASR_FALLBACK_MODEL`:远端 ASR 和本机 ASR 都不可用时才尝试的多模态兜底,默认 `gemini-2.5-flash`;如果模型不能真实听到音频或返回疑似逐秒假字幕,后端必须拒绝写入时间轴
|
||||||
- `ASR_TIMEOUT_SECONDS`:远端 ASR / 音频分析单次请求超时,默认 45 秒,避免第一步长时间停在转录中
|
- `ASR_TIMEOUT_SECONDS`:远端 ASR / 音频分析单次请求超时,默认 45 秒,避免第一步长时间停在转录中
|
||||||
@@ -59,8 +59,13 @@
|
|||||||
- `REWRITE_MODEL`:通用改写/分镜描述模型,默认 `gemini-2.5-pro`
|
- `REWRITE_MODEL`:通用改写/分镜描述模型,默认 `gemini-2.5-pro`
|
||||||
- `AUDIO_REWRITE_MODEL`:后续音频口播改写模型,默认跟随 `REWRITE_MODEL`;当前第一步不默认调用口播改写,只保留原文案和声音分析
|
- `AUDIO_REWRITE_MODEL`:后续音频口播改写模型,默认跟随 `REWRITE_MODEL`;当前第一步不默认调用口播改写,只保留原文案和声音分析
|
||||||
- `AUDIO_PRODUCT_BRIEF`:音频口播改写时注入的 SKG 产品卖点
|
- `AUDIO_PRODUCT_BRIEF`:音频口播改写时注入的 SKG 产品卖点
|
||||||
|
- `IMAGE_BASE_URL` / `IMAGE_API_KEY` / `IMAGE_MODEL`:OpenAI 兼容生图网关;当前生图默认走 GPT 图片模型,`IMAGE_MODEL=gpt-image-2`
|
||||||
|
- `GPT_IMAGE_MODEL` / `SUBJECT_ASSET_IMAGE_MODEL` / `SUBJECT_ASSET_IMAGE_MODELS`:主体 6 视图专用 GPT 图片模型链,默认 `gpt-image-2,gpt-image-1.5`,不要降回 Gemini 图像模型
|
||||||
|
- `VOICE_PROVIDER`:配音通道,当前固定使用 `azure_openai`
|
||||||
|
- `AZURE_OPENAI_BASE_URL` / `AZURE_OPENAI_API_KEY`:微软 Azure OpenAI 协议配音网关;本地未单独配置 Key 时回退复用 `LLM_API_KEY`
|
||||||
|
- `AZURE_TTS_MODEL` / `AZURE_TTS_VOICE_ID` / `AZURE_TTS_VOICE_POOL` / `AZURE_TTS_PATH`:Azure OpenAI TTS 模型、默认音色、音色池和 OpenAI 协议语音路径
|
||||||
- `MINIMAX_API_KEY`:MiniMax T2A 配音 Key,只能放本地 `api/.env`,不能入库;当前第一步暂不默认调用
|
- `MINIMAX_API_KEY`:MiniMax T2A 配音 Key,只能放本地 `api/.env`,不能入库;当前第一步暂不默认调用
|
||||||
- `MINIMAX_TTS_BASE_URL` / `MINIMAX_TTS_MODEL` / `MINIMAX_TTS_VOICE_ID`:MiniMax 配音端点、模型和兜底音色配置,供后续新配音阶段使用
|
- `MINIMAX_TTS_BASE_URL` / `MINIMAX_TTS_MODEL` / `MINIMAX_TTS_VOICE_ID`:MiniMax 旧配音端点、模型和兜底音色配置,仅作为保留兼容;当前不作为默认语音通道
|
||||||
- `MINIMAX_TTS_VOICE_POOL`:MiniMax 英文随机音色池;当前默认男声 `English_magnetic_voiced_man`、女声 `English_Upbeat_Woman`、成熟声 `English_MaturePartner`,供后续新配音阶段使用
|
- `MINIMAX_TTS_VOICE_POOL`:MiniMax 英文随机音色池;当前默认男声 `English_magnetic_voiced_man`、女声 `English_Upbeat_Woman`、成熟声 `English_MaturePartner`,供后续新配音阶段使用
|
||||||
- `POE_API_KEY` / `VIDEO_API_KEY`:视频生成通道 Key,只能放本地环境变量
|
- `POE_API_KEY` / `VIDEO_API_KEY`:视频生成通道 Key,只能放本地环境变量
|
||||||
- `WEB_AUTH_USERNAME` / `WEB_AUTH_PASSWORD` / `WEB_AUTH_SESSION_SECRET`:生产网页登录和会话签名配置;密码和 session secret 只放服务器环境变量,不入库
|
- `WEB_AUTH_USERNAME` / `WEB_AUTH_PASSWORD` / `WEB_AUTH_SESSION_SECRET`:生产网页登录和会话签名配置;密码和 session secret 只放服务器环境变量,不入库
|
||||||
|
|||||||
@@ -18,15 +18,29 @@ LOCAL_ASR_MODEL=mlx-community/whisper-tiny
|
|||||||
LOCAL_ASR_TIMEOUT_SECONDS=180
|
LOCAL_ASR_TIMEOUT_SECONDS=180
|
||||||
TRANSLATE_MODEL=gemini-2.5-flash
|
TRANSLATE_MODEL=gemini-2.5-flash
|
||||||
REWRITE_MODEL=gemini-2.5-pro
|
REWRITE_MODEL=gemini-2.5-pro
|
||||||
IMAGE_MODEL=gemini-3-pro-image-preview
|
IMAGE_BASE_URL=https://ai.skg.com/ezlink/v1
|
||||||
|
IMAGE_API_KEY=
|
||||||
|
IMAGE_MODEL=gpt-image-2
|
||||||
|
GPT_IMAGE_MODEL=gpt-image-2
|
||||||
|
SUBJECT_ASSET_IMAGE_MODEL=gpt-image-2
|
||||||
|
SUBJECT_ASSET_IMAGE_MODELS=gpt-image-2,gpt-image-1.5
|
||||||
VIDEO_MODEL=seedance
|
VIDEO_MODEL=seedance
|
||||||
VIDEO_MODEL_SEEDANCE=seedance-2-fast
|
VIDEO_MODEL_SEEDANCE=seedance-2-fast
|
||||||
VIDEO_MODEL_KLING=kling-omni
|
VIDEO_MODEL_KLING=kling-omni
|
||||||
VIDEO_MODEL_VEO3=veo-3.1-fast
|
VIDEO_MODEL_VEO3=veo-3.1-fast
|
||||||
|
|
||||||
# 音频文案改写 + MiniMax 配音
|
# 音频文案改写 + Azure OpenAI 配音
|
||||||
AUDIO_REWRITE_MODEL=gemini-2.5-pro
|
AUDIO_REWRITE_MODEL=gemini-2.5-pro
|
||||||
AUDIO_PRODUCT_BRIEF="SKG 智能按摩产品,主打日常肩颈、腰背、眼部、膝盖或足部放松;广告表达要高级、干净、可信,不做医疗疗效承诺。"
|
AUDIO_PRODUCT_BRIEF="SKG 智能按摩产品,主打日常肩颈、腰背、眼部、膝盖或足部放松;广告表达要高级、干净、可信,不做医疗疗效承诺。"
|
||||||
|
VOICE_PROVIDER=azure_openai
|
||||||
|
AZURE_OPENAI_BASE_URL=https://ai.skg.com/azure
|
||||||
|
AZURE_OPENAI_API_KEY=
|
||||||
|
AZURE_TTS_MODEL=gpt-4o-mini-tts
|
||||||
|
AZURE_TTS_VOICE_ID=alloy
|
||||||
|
AZURE_TTS_VOICE_POOL=alloy,verse,shimmer
|
||||||
|
AZURE_TTS_PATH=/audio/speech
|
||||||
|
|
||||||
|
# MiniMax 旧配音通道,保留兼容;默认不走
|
||||||
MINIMAX_API_KEY=
|
MINIMAX_API_KEY=
|
||||||
MINIMAX_TTS_BASE_URL=https://api.minimax.io
|
MINIMAX_TTS_BASE_URL=https://api.minimax.io
|
||||||
MINIMAX_TTS_MODEL=speech-2.8-turbo
|
MINIMAX_TTS_MODEL=speech-2.8-turbo
|
||||||
|
|||||||
15
api/main.py
15
api/main.py
@@ -624,6 +624,17 @@ def video_uses_ark() -> bool:
|
|||||||
return "ark.cn-beijing.volces.com" in base or "ai.skg.com/doubao" in base
|
return "ark.cn-beijing.volces.com" in base or "ai.skg.com/doubao" in base
|
||||||
|
|
||||||
|
|
||||||
|
def video_provider_name() -> str:
|
||||||
|
base = video_api_base()
|
||||||
|
if video_uses_poe():
|
||||||
|
return "poe"
|
||||||
|
if "ai.skg.com/doubao" in base:
|
||||||
|
return "doubao"
|
||||||
|
if "ark.cn-beijing.volces.com" in base:
|
||||||
|
return "ark"
|
||||||
|
return "custom"
|
||||||
|
|
||||||
|
|
||||||
def video_api_base() -> str:
|
def video_api_base() -> str:
|
||||||
if VIDEO_API_BASE_URL:
|
if VIDEO_API_BASE_URL:
|
||||||
return VIDEO_API_BASE_URL.rstrip("/")
|
return VIDEO_API_BASE_URL.rstrip("/")
|
||||||
@@ -2853,7 +2864,7 @@ def health() -> dict:
|
|||||||
"vision": VISION_MODEL,
|
"vision": VISION_MODEL,
|
||||||
"image": IMAGE_MODEL,
|
"image": IMAGE_MODEL,
|
||||||
"image_base_url": IMAGE_BASE_URL or LLM_BASE_URL or "openai-default",
|
"image_base_url": IMAGE_BASE_URL or LLM_BASE_URL or "openai-default",
|
||||||
"image_fallbacks": [IMAGE_MODEL, GPT_IMAGE_MODEL, "gpt-image-1.5"],
|
"image_fallbacks": list(dict.fromkeys([IMAGE_MODEL, GPT_IMAGE_MODEL, "gpt-image-1.5"])),
|
||||||
"subject_image": SUBJECT_ASSET_IMAGE_MODEL,
|
"subject_image": SUBJECT_ASSET_IMAGE_MODEL,
|
||||||
"subject_image_fallbacks": SUBJECT_ASSET_IMAGE_MODELS,
|
"subject_image_fallbacks": SUBJECT_ASSET_IMAGE_MODELS,
|
||||||
"voice_provider": VOICE_PROVIDER,
|
"voice_provider": VOICE_PROVIDER,
|
||||||
@@ -2868,7 +2879,7 @@ def health() -> dict:
|
|||||||
"minimax_configured": bool(MINIMAX_API_KEY),
|
"minimax_configured": bool(MINIMAX_API_KEY),
|
||||||
"video": VIDEO_MODEL,
|
"video": VIDEO_MODEL,
|
||||||
"video_aliases": VIDEO_MODEL_ALIASES,
|
"video_aliases": VIDEO_MODEL_ALIASES,
|
||||||
"video_provider": "poe" if video_uses_poe() else ("ark" if video_uses_ark() else "custom"),
|
"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()),
|
||||||
"video_create_paths": VIDEO_CREATE_PATHS,
|
"video_create_paths": VIDEO_CREATE_PATHS,
|
||||||
|
|||||||
@@ -23,11 +23,25 @@ ASR_MODEL=whisper-1
|
|||||||
ASR_FALLBACK_MODEL=gemini-2.5-flash
|
ASR_FALLBACK_MODEL=gemini-2.5-flash
|
||||||
TRANSLATE_MODEL=gemini-2.5-flash
|
TRANSLATE_MODEL=gemini-2.5-flash
|
||||||
REWRITE_MODEL=gemini-2.5-pro
|
REWRITE_MODEL=gemini-2.5-pro
|
||||||
IMAGE_MODEL=gemini-3-pro-image-preview
|
IMAGE_BASE_URL=https://ai.skg.com/ezlink/v1
|
||||||
|
IMAGE_API_KEY=
|
||||||
|
IMAGE_MODEL=gpt-image-2
|
||||||
|
GPT_IMAGE_MODEL=gpt-image-2
|
||||||
|
SUBJECT_ASSET_IMAGE_MODEL=gpt-image-2
|
||||||
|
SUBJECT_ASSET_IMAGE_MODELS=gpt-image-2,gpt-image-1.5
|
||||||
|
|
||||||
# Audio rewrite and MiniMax TTS
|
# Audio rewrite and Azure OpenAI TTS
|
||||||
AUDIO_REWRITE_MODEL=gemini-2.5-pro
|
AUDIO_REWRITE_MODEL=gemini-2.5-pro
|
||||||
AUDIO_PRODUCT_BRIEF="SKG smart massage products for daily neck, shoulder, back, eye, knee, and foot relaxation. Keep claims premium, clean, credible, and non-medical."
|
AUDIO_PRODUCT_BRIEF="SKG smart massage products for daily neck, shoulder, back, eye, knee, and foot relaxation. Keep claims premium, clean, credible, and non-medical."
|
||||||
|
VOICE_PROVIDER=azure_openai
|
||||||
|
AZURE_OPENAI_BASE_URL=https://ai.skg.com/azure
|
||||||
|
AZURE_OPENAI_API_KEY=
|
||||||
|
AZURE_TTS_MODEL=gpt-4o-mini-tts
|
||||||
|
AZURE_TTS_VOICE_ID=alloy
|
||||||
|
AZURE_TTS_VOICE_POOL=alloy,verse,shimmer
|
||||||
|
AZURE_TTS_PATH=/audio/speech
|
||||||
|
|
||||||
|
# Legacy MiniMax TTS fallback; not the default voice provider.
|
||||||
MINIMAX_API_KEY=
|
MINIMAX_API_KEY=
|
||||||
MINIMAX_TTS_BASE_URL=https://api.minimax.io
|
MINIMAX_TTS_BASE_URL=https://api.minimax.io
|
||||||
MINIMAX_TTS_MODEL=speech-2.8-turbo
|
MINIMAX_TTS_MODEL=speech-2.8-turbo
|
||||||
|
|||||||
@@ -743,7 +743,7 @@ api/main.py
|
|||||||
background_audio_profile,
|
background_audio_profile,
|
||||||
product_brief,
|
product_brief,
|
||||||
rewrite_model,
|
rewrite_model,
|
||||||
voice_provider: minimax,
|
voice_provider: azure_openai | minimax,
|
||||||
voice_model,
|
voice_model,
|
||||||
voice_id,
|
voice_id,
|
||||||
voice_url,
|
voice_url,
|
||||||
@@ -870,16 +870,16 @@ ProductRefStateItem {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td>网页登录</td><td><code>POST /auth/login</code>、<code>GET /auth/check</code>、<code>POST /auth/logout</code></td><td><code>web/app/login/page.tsx</code>、Nginx <code>auth_request</code></td><td>登录页提交账号密码到 <code>/api/auth/login</code>,后端设置 HttpOnly 会话 Cookie;生产 Nginx 对工作台和 <code>/api/</code> 调 <code>/auth/check</code> 做统一校验,未登录页面跳 <code>/login/</code>,API 返回 JSON 401。</td></tr>
|
<tr><td>网页登录</td><td><code>POST /auth/login</code>、<code>GET /auth/check</code>、<code>POST /auth/logout</code></td><td><code>web/app/login/page.tsx</code>、Nginx <code>auth_request</code></td><td>登录页提交账号密码到 <code>/api/auth/login</code>,后端设置 HttpOnly 会话 Cookie;生产 Nginx 对工作台和 <code>/api/</code> 调 <code>/auth/check</code> 做统一校验,未登录页面跳 <code>/login/</code>,API 返回 JSON 401。</td></tr>
|
||||||
<tr><td>运行配置 / 模型标注</td><td><code>GET /health</code></td><td><code>getRuntimeHealth</code>、<code>ModelTrace</code></td><td>返回 <code>models</code>:ASR、本机 ASR、ASR fallback、翻译、改写、Vision、通用图像模型、主体 6 视图 GPT 图像模型、MiniMax TTS、视频别名和视频服务商。前端所有当前主路径里会调用模型的按钮旁显示模型名,点击弹出小窗口查看模型链路和输入输出逻辑;不返回 API Key 或敏感凭证。</td></tr>
|
<tr><td>运行配置 / 模型标注</td><td><code>GET /health</code></td><td><code>getRuntimeHealth</code>、<code>ModelTrace</code></td><td>返回 <code>models</code>:ASR、本机 ASR、ASR fallback、翻译、改写、Vision、GPT 图像模型、主体 6 视图 GPT 图像模型、Azure OpenAI TTS、视频别名和 Seedance 服务商。前端所有当前主路径里会调用模型的按钮旁显示模型名,点击弹出小窗口查看模型链路和输入输出逻辑;不返回 API Key 或敏感凭证。</td></tr>
|
||||||
<tr><td>历史列表</td><td><code>GET /jobs</code></td><td><code>listJobs</code></td><td>所有 job 精简列表(id/url/status/thumbnail/mtime…),按 state.json mtime 倒序。前端 URL 无 <code>?job=</code> 时拉它回填全部历史;带 <code>limit</code> 可截断。</td></tr>
|
<tr><td>历史列表</td><td><code>GET /jobs</code></td><td><code>listJobs</code></td><td>所有 job 精简列表(id/url/status/thumbnail/mtime…),按 state.json mtime 倒序。前端 URL 无 <code>?job=</code> 时拉它回填全部历史;带 <code>limit</code> 可截断。</td></tr>
|
||||||
<tr><td>创建任务</td><td><code>POST /jobs</code></td><td><code>createJob</code></td><td>提交 TK 链接,后台开始下载;前端“开始”队列会在 downloaded 后自动触发音频解析。</td></tr>
|
<tr><td>创建任务</td><td><code>POST /jobs</code></td><td><code>createJob</code></td><td>提交 TK 链接,后台开始下载;前端“开始”队列会在 downloaded 后自动触发音频解析。</td></tr>
|
||||||
<tr><td>上传视频</td><td><code>POST /jobs/upload</code></td><td><code>uploadJob</code></td><td>保存 source.mp4,然后同样进入下载完成状态;当前上传后也加入第一步队列,下载完成后自动解析音频。</td></tr>
|
<tr><td>上传视频</td><td><code>POST /jobs/upload</code></td><td><code>uploadJob</code></td><td>保存 source.mp4,然后同样进入下载完成状态;当前上传后也加入第一步队列,下载完成后自动解析音频。</td></tr>
|
||||||
<tr><td>删除输入视频</td><td><code>DELETE /jobs/{id}</code></td><td><code>deleteJob</code></td><td>从任务队列、URL 和磁盘 <code>jobs/<id></code> 目录移除整个 job,包括源视频、关键帧、元素提取图和生成视频。</td></tr>
|
<tr><td>删除输入视频</td><td><code>DELETE /jobs/{id}</code></td><td><code>deleteJob</code></td><td>从任务队列、URL 和磁盘 <code>jobs/<id></code> 目录移除整个 job,包括源视频、关键帧、元素提取图和生成视频。</td></tr>
|
||||||
<tr><td>解析视频</td><td><code>POST /jobs/{id}/analyze?frames=&target=&mode=&quality=</code></td><td><code>analyzeJob</code></td><td>后续阶段保留的抽帧能力。默认 <code>frames=12</code>;<code>target</code> 支持透明骨架人、综合、清晰主体、转场变化、表情瞬间、动作峰值。当前第一步主流程不自动调用该接口;原版视频旁的“抽参考 12 帧”会显式用 <code>target=motion</code>、<code>quality=accurate</code>、<code>mode=replace</code> 重新生成全局动作/节奏参考帧池。</td></tr>
|
<tr><td>解析视频</td><td><code>POST /jobs/{id}/analyze?frames=&target=&mode=&quality=</code></td><td><code>analyzeJob</code></td><td>后续阶段保留的抽帧能力。默认 <code>frames=12</code>;<code>target</code> 支持透明骨架人、综合、清晰主体、转场变化、表情瞬间、动作峰值。当前第一步主流程不自动调用该接口;原版视频旁的“抽参考 12 帧”会显式用 <code>target=motion</code>、<code>quality=accurate</code>、<code>mode=replace</code> 重新生成全局动作/节奏参考帧池。</td></tr>
|
||||||
<tr><td>音频文案轨</td><td><code>POST /jobs/{id}/transcribe</code></td><td><code>triggerTranscribe</code></td><td>若尚未拆轨,先从 <code>source.mp4</code> 提取 <code>audio.wav</code> 并回填 <code>source_audio_url</code>;随后用 ASR 提取原始文案,翻译成中文,写入 <code>audio_script.source_text</code>、<code>source_zh</code> 和逐句 <code>transcript</code>。远端 <code>ASR_MODEL</code> 失败后先走本机 <code>LOCAL_ASR_BIN</code>/<code>LOCAL_ASR_MODEL</code>(默认 <code>mlx_whisper</code>),再尝试 <code>ASR_FALLBACK_MODEL</code>。后端会拒绝重复文本、逐秒假字幕或覆盖率过低的结果,不再把不可听的多模态输出写进时间轴。再用 <code>ASR_FALLBACK_MODEL</code> 多模态音频分析讲话人、语速节奏、停顿、背景音乐/环境声/音效,写入 <code>speaker_profile</code>、<code>rhythm_profile</code>、<code>background_audio_profile</code>。当前第一步不默认生成 SKG 新口播和 MiniMax 配音。</td></tr>
|
<tr><td>音频文案轨</td><td><code>POST /jobs/{id}/transcribe</code></td><td><code>triggerTranscribe</code></td><td>若尚未拆轨,先从 <code>source.mp4</code> 提取 <code>audio.wav</code> 并回填 <code>source_audio_url</code>;随后用 ASR 提取原始文案,翻译成中文,写入 <code>audio_script.source_text</code>、<code>source_zh</code> 和逐句 <code>transcript</code>。远端 <code>ASR_MODEL</code> 失败后先走本机 <code>LOCAL_ASR_BIN</code>/<code>LOCAL_ASR_MODEL</code>(默认 <code>mlx_whisper</code>),再尝试 <code>ASR_FALLBACK_MODEL</code>。后端会拒绝重复文本、逐秒假字幕或覆盖率过低的结果,不再把不可听的多模态输出写进时间轴。再用 <code>ASR_FALLBACK_MODEL</code> 多模态音频分析讲话人、语速节奏、停顿、背景音乐/环境声/音效,写入 <code>speaker_profile</code>、<code>rhythm_profile</code>、<code>background_audio_profile</code>。当前第一步不默认生成 SKG 新口播和 Azure OpenAI 配音。</td></tr>
|
||||||
<tr><td>分镜脚本改写</td><td><code>POST /jobs/{id}/script/rewrite</code></td><td><code>rewriteStoryboardScript</code></td><td>根据原参考文案、当前新口播、分镜角色、时间段和作者想法改写中文口播。<code>mode=segment</code> 只改一段;<code>mode=all</code> 一次改完整片,要求整片前后连贯。接口只返回 <code>items[index,text]</code>,前端暂存在当前页面状态里,生成本条视频时写入 <code>StoryboardScene.action</code>。</td></tr>
|
<tr><td>分镜脚本改写</td><td><code>POST /jobs/{id}/script/rewrite</code></td><td><code>rewriteStoryboardScript</code></td><td>根据原参考文案、当前新口播、分镜角色、时间段和作者想法改写中文口播。<code>mode=segment</code> 只改一段;<code>mode=all</code> 一次改完整片,要求整片前后连贯。接口只返回 <code>items[index,text]</code>,前端暂存在当前页面状态里,生成本条视频时写入 <code>StoryboardScene.action</code>。</td></tr>
|
||||||
<tr><td>原始音频文件</td><td><code>GET /jobs/{id}/audio.wav</code></td><td><code>sourceAudioUrl</code></td><td>返回拆轨得到的 wav;当前主界面不再渲染底部吸附音频条,右侧复刻工作表会读取该文件生成参考图式横向响度波形,并和原视频、逐句时间轴联动;波形标题栏显示当前播放秒数、总时长和鼠标指针停点秒数。</td></tr>
|
<tr><td>原始音频文件</td><td><code>GET /jobs/{id}/audio.wav</code></td><td><code>sourceAudioUrl</code></td><td>返回拆轨得到的 wav;当前主界面不再渲染底部吸附音频条,右侧复刻工作表会读取该文件生成参考图式横向响度波形,并和原视频、逐句时间轴联动;波形标题栏显示当前播放秒数、总时长和鼠标指针停点秒数。</td></tr>
|
||||||
<tr><td>改写配音文件</td><td><code>GET /jobs/{id}/audio-script.mp3</code></td><td><code>apiAssetUrl(job.audio_script.voice_url)</code></td><td>后续新配音阶段保留的 MiniMax T2A 产物。当前第一步不默认生成该文件。</td></tr>
|
<tr><td>改写配音文件</td><td><code>GET /jobs/{id}/audio-script.mp3</code></td><td><code>apiAssetUrl(job.audio_script.voice_url)</code></td><td>后续新配音阶段保留的 TTS 产物;默认走 <code>VOICE_PROVIDER=azure_openai</code>,通过 <code>AZURE_OPENAI_BASE_URL</code> 的 OpenAI 协议 <code>/audio/speech</code> 生成 mp3。当前第一步不默认生成该文件。</td></tr>
|
||||||
<tr><td>手动加帧</td><td><code>POST /jobs/{id}/frames?t=</code></td><td><code>addManualFrame</code></td><td>按视频时间戳抽一帧,index 递增但 frames 按 timestamp 排序。当前主界面会把原版视频播放器的播放秒数传给 <code>AudioIntakePanel</code> 标题栏右侧的“当前点抽帧”。</td></tr>
|
<tr><td>手动加帧</td><td><code>POST /jobs/{id}/frames?t=</code></td><td><code>addManualFrame</code></td><td>按视频时间戳抽一帧,index 递增但 frames 按 timestamp 排序。当前主界面会把原版视频播放器的播放秒数传给 <code>AudioIntakePanel</code> 标题栏右侧的“当前点抽帧”。</td></tr>
|
||||||
<tr><td>删除关键帧</td><td><code>DELETE /jobs/{id}/frames/{idx}</code></td><td><code>deleteFrame</code></td><td>删除单张关键帧并清掉对应选择态;当前主界面每张缩略图右下角提供删除入口,方便手动抽错后直接修正。</td></tr>
|
<tr><td>删除关键帧</td><td><code>DELETE /jobs/{id}/frames/{idx}</code></td><td><code>deleteFrame</code></td><td>删除单张关键帧并清掉对应选择态;当前主界面每张缩略图右下角提供删除入口,方便手动抽错后直接修正。</td></tr>
|
||||||
<tr><td>Vision 识别</td><td><code>POST /frames/{idx}/describe</code></td><td><code>describeFrame</code></td><td>写入 frame.description,后续可从 objects 加候选元素。</td></tr>
|
<tr><td>Vision 识别</td><td><code>POST /frames/{idx}/describe</code></td><td><code>describeFrame</code></td><td>写入 frame.description,后续可从 objects 加候选元素。</td></tr>
|
||||||
@@ -955,16 +955,16 @@ ProductRefStateItem {
|
|||||||
<li>主体候选确认、改名、删除和主体资产包生成能力保留在底层旧面板和接口中,当前第一步主界面不主动展示。</li>
|
<li>主体候选确认、改名、删除和主体资产包生成能力保留在底层旧面板和接口中,当前第一步主界面不主动展示。</li>
|
||||||
<li>分镜工作台 4 图槽和改造说明自动保存。</li>
|
<li>分镜工作台 4 图槽和改造说明自动保存。</li>
|
||||||
<li>音频文案轨:点击开始或提取音频后提取原文案、中文翻译、讲话人、语速节奏、背景音乐/环境声/音效;结果集中在右侧工作表展示。</li>
|
<li>音频文案轨:点击开始或提取音频后提取原文案、中文翻译、讲话人、语速节奏、背景音乐/环境声/音效;结果集中在右侧工作表展示。</li>
|
||||||
<li>nano-banana-pro image-to-image 生图。</li>
|
<li>GPT Image 生图;当前 <code>IMAGE_MODEL</code> 和主体 6 视图链路默认使用 <code>gpt-image-2</code>。</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3>阻塞 / 占位</h3>
|
<h3>阻塞 / 占位</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>ASR:优先走当前 OpenAI-compatible 音频转写入口;如果该网关没有 <code>/audio/transcriptions</code>,自动 fallback 到 <code>ASR_FALLBACK_MODEL</code>(默认 <code>gemini-2.5-flash</code>)的多模态音频识别。</li>
|
<li>ASR:优先走当前 OpenAI-compatible 音频转写入口;如果该网关没有 <code>/audio/transcriptions</code>,自动 fallback 到 <code>ASR_FALLBACK_MODEL</code>(默认 <code>gemini-2.5-flash</code>)的多模态音频识别。</li>
|
||||||
<li>MiniMax:当前接入的是官方 T2A 英文配音能力,不是 ASR;第一步暂不默认调用。默认随机音色池是 <code>English_magnetic_voiced_man</code>、<code>English_Upbeat_Woman</code>、<code>English_MaturePartner</code>。API Key 只能放本地环境变量,不能写入仓库。</li>
|
<li>Voice:当前默认语音通道是 <code>VOICE_PROVIDER=azure_openai</code>,通过 <code>AZURE_OPENAI_BASE_URL=https://ai.skg.com/azure</code> 的 OpenAI 协议生成 TTS;第一步暂不默认调用。MiniMax 仅保留为兼容旧配置。</li>
|
||||||
<li>Audio Product Brief:默认是通用 SKG 放松产品卖点;当前第一步只保留配置,后续分镜/新配音阶段再使用。</li>
|
<li>Audio Product Brief:默认是通用 SKG 放松产品卖点;当前第一步只保留配置,后续分镜/新配音阶段再使用。</li>
|
||||||
<li>Video Gen:模型层按业务保留 Seedance / Kling / Veo/Voe 选择;后端已支持 Poe、火山方舟和 SKG 豆包视频网关。Seedance 可通过 <code>VIDEO_API_BASE_URL=https://ai.skg.com/doubao</code> 走 content JSON 异步任务,提交后写入候选片段并轮询到完成。</li>
|
<li>Video Gen:当前视频通道固定优先 Seedance;<code>VIDEO_API_BASE_URL=https://ai.skg.com/doubao</code> 走 content JSON 异步任务,提交后写入候选片段并轮询到完成。</li>
|
||||||
<li>Compose:还没做本地 ffmpeg 字幕/TTS 合成。</li>
|
<li>Compose:还没做本地 ffmpeg 字幕/TTS 合成。</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -1004,6 +1004,19 @@ ProductRefStateItem {
|
|||||||
<h2>变更记录</h2>
|
<h2>变更记录</h2>
|
||||||
<p>这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。</p>
|
<p>这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。</p>
|
||||||
<div class="changelog">
|
<div class="changelog">
|
||||||
|
<article class="change">
|
||||||
|
<header>
|
||||||
|
<h3>2026-05-18 · 模型链路拆分为 GPT 生图、Azure 语音和 Seedance 视频</h3>
|
||||||
|
<span class="tag violet">API</span>
|
||||||
|
<span class="tag cyan">Workflow</span>
|
||||||
|
<span class="tag amber">Config</span>
|
||||||
|
</header>
|
||||||
|
<div class="body">
|
||||||
|
<p><strong>问题:</strong>之前图片、文本、音频分析共用 <code>LLM_BASE_URL</code>,配音默认仍是 MiniMax,视频虽然已接豆包/Seedance,但模型标注没有把“生图 GPT / 语音 Azure / 视频 Seedance”三条高优先级链路清楚拆开。</p>
|
||||||
|
<p><strong>改动:</strong><code>api/main.py</code> 新增 <code>IMAGE_BASE_URL</code>、<code>IMAGE_API_KEY</code>、<code>VOICE_PROVIDER</code>、<code>AZURE_OPENAI_BASE_URL</code>、<code>AZURE_OPENAI_API_KEY</code>、<code>AZURE_TTS_MODEL</code> 等配置;所有 <code>/images/generations</code> 调用改走图片专用 OpenAI-compatible client,默认 <code>gpt-image-2</code>;TTS 新增 Azure OpenAI 协议 <code>/audio/speech</code> 通道,默认 <code>VOICE_PROVIDER=azure_openai</code>;<code>GET /health</code> 回传图片、主体、语音和视频的实际模型与 base URL 供前端模型标注使用。</p>
|
||||||
|
<p><strong>影响:</strong><code>api/main.py</code>、<code>web/lib/api.ts</code>、<code>RULES.md</code>、<code>.project.json</code>、<code>docs/source-analysis.html</code>。真实 key 仍只写本地 <code>api/.env</code> / 生产环境变量,不能入库。</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
<article class="change">
|
<article class="change">
|
||||||
<header>
|
<header>
|
||||||
<h3>2026-05-18 · 6 视图改用 GPT 图片模型并修复前端展示</h3>
|
<h3>2026-05-18 · 6 视图改用 GPT 图片模型并修复前端展示</h3>
|
||||||
|
|||||||
@@ -143,9 +143,16 @@ export interface RuntimeModels {
|
|||||||
audio_rewrite?: string
|
audio_rewrite?: string
|
||||||
vision?: string
|
vision?: string
|
||||||
image?: string
|
image?: string
|
||||||
|
image_base_url?: string
|
||||||
image_fallbacks?: string[]
|
image_fallbacks?: string[]
|
||||||
subject_image?: string
|
subject_image?: string
|
||||||
subject_image_fallbacks?: string[]
|
subject_image_fallbacks?: string[]
|
||||||
|
voice_provider?: string
|
||||||
|
voice_base_url?: string
|
||||||
|
voice_tts?: string
|
||||||
|
voice_id?: string
|
||||||
|
voice_pool?: string[]
|
||||||
|
voice_configured?: boolean
|
||||||
minimax_tts?: string
|
minimax_tts?: string
|
||||||
minimax_voice?: string
|
minimax_voice?: string
|
||||||
minimax_voice_pool?: string[]
|
minimax_voice_pool?: string[]
|
||||||
|
|||||||
Reference in New Issue
Block a user