@optima-chat/gen-cli 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/digital-human/SKILL.md +131 -17
- package/.claude/skills/digital-human/references/edit.md +121 -100
- package/.claude/skills/digital-human/references/generate.md +256 -124
- package/.claude/skills/digital-human/references/manage.md +28 -17
- package/.claude/skills/digital-human/references/train.md +47 -62
- package/.claude/skills/gen/SKILL.md +13 -0
- package/.claude/skills/motion-control/SKILL.md +68 -0
- package/.claude/skills/video-compose/SKILL.md +144 -0
- package/.claude/skills/video-compose/scripts/video_compose.py +290 -0
- package/.claude/skills/video-edit/SKILL.md +62 -1
- package/.claude/skills/video-gen/SKILL.md +165 -57
- package/.claude/skills/video-gen/references/cinematic-language.md +158 -0
- package/.claude/skills/video-gen/references/confirm-card.md +49 -0
- package/.claude/skills/video-gen/references/prompt-craft.md +72 -0
- package/.claude/skills/video-translate/SKILL.md +205 -69
- package/assets/video-compose/bgm-library/SOURCES.md +25 -0
- package/assets/video-compose/bgm-library/calm/calm-01.mp3 +0 -0
- package/assets/video-compose/bgm-library/calm/calm-02.mp3 +0 -0
- package/assets/video-compose/bgm-library/dramatic/dramatic-01.mp3 +0 -0
- package/assets/video-compose/bgm-library/dramatic/dramatic-02.mp3 +0 -0
- package/assets/video-compose/bgm-library/energetic/energetic-01.mp3 +0 -0
- package/assets/video-compose/bgm-library/energetic/energetic-02.mp3 +0 -0
- package/assets/video-compose/bgm-library/sad/sad-01.mp3 +0 -0
- package/assets/video-compose/bgm-library/sad/sad-02.mp3 +0 -0
- package/assets/video-compose/bgm-library/upbeat/upbeat-01.mp3 +0 -0
- package/assets/video-compose/bgm-library/upbeat/upbeat-02.mp3 +0 -0
- package/assets/video-compose/bgm-library/warm/warm-01.mp3 +0 -0
- package/assets/video-compose/bgm-library/warm/warm-02.mp3 +0 -0
- package/assets/video-compose/voice-samples/01-/346/270/251/346/232/226/345/260/221/345/245/263.mp3 +0 -0
- package/assets/video-compose/voice-samples/02-/347/224/234/347/276/216/345/245/263/345/243/260.mp3 +0 -0
- package/assets/video-compose/voice-samples/03-/347/224/234/347/276/216/345/205/203/346/260/224.mp3 +0 -0
- package/assets/video-compose/voice-samples/04-/346/270/205/347/224/234/345/260/221/345/245/263.mp3 +0 -0
- package/assets/video-compose/voice-samples/05-/345/276/241/345/247/220.mp3 +0 -0
- package/assets/video-compose/voice-samples/06-/346/210/220/347/206/237/347/237/245/346/200/247.mp3 +0 -0
- package/assets/video-compose/voice-samples/07-/345/245/263/344/270/273/346/222/255.mp3 +0 -0
- package/assets/video-compose/voice-samples/CATALOG.md +9 -0
- package/dist/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +19 -2
- package/dist/services/auth.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prompt-craft
|
|
3
|
+
purpose: "把 storyboard / 分析转成 Seedance 能拍好的 prompt —— 复刻保真的命门"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 写好生成 prompt(call-N.txt)
|
|
7
|
+
|
|
8
|
+
> 在「产出 Production Plan」给每个 Call 写 `prompts/call-N.txt` 时,**必须**照本文结构写。
|
|
9
|
+
> 默认视频路径把这段文本**原样**喂给模型,中间**没有任何改写 / 增强兜底**——文本糙 = 成片糙。复刻成败就卡在这。
|
|
10
|
+
> **结构来源**:本文五段式结构是 optima-gen 服务端 `SYSTEM_PROMPT_VIDEO` 的 **skill 端镜像**;改其一须同步另一(skill 读不到服务端,无法单一来源)。
|
|
11
|
+
|
|
12
|
+
## 为什么 prompt 决定成败
|
|
13
|
+
|
|
14
|
+
默认路径是 image-to-video,模型只吃三样:**首帧图 + 这段 prompt + 时长**。它按 prompt 把首帧「动起来」。所以:
|
|
15
|
+
|
|
16
|
+
- 首帧定「长什么样」,**prompt 定「怎么动」**。
|
|
17
|
+
- prompt 没写清动作 / 运镜 → 模型自由发挥 → 动作呆、方向乱、跟参考对不上。
|
|
18
|
+
- **复刻尤其吃这条**:参考视频好看,是因为它的**节奏 + 运镜 + 动作**好看,而这些只活在「动态」里——首帧图带不出来,**必须靠 prompt 文字补回去**。
|
|
19
|
+
|
|
20
|
+
## 五段式结构(顺序不要乱)
|
|
21
|
+
|
|
22
|
+
每个 `call-N.txt` 按这个顺序写,每段一到两句。**构图 / 机位 / 运镜 / 光线的专业术语全部查 `cinematic-language.md`**——这几段写得专不专业,直接决定模型拍得像不像导演拍的:
|
|
23
|
+
|
|
24
|
+
1. **开场构图**:主体是什么、在画面什么位置(三分 / 居中)、**景别 + 机位 + 焦段/景深**(如「ECU 大特写、略仰拍、85mm 长焦浅景深隔离主体」,不是只写「特写」)、前中后景分层。
|
|
25
|
+
2. **动作弧(最重要)**:这一镜从头到尾**发生了什么动作**——主体怎么动、状态怎么从 A 变到 B。复刻时照搬参考这一镜的动作。
|
|
26
|
+
3. **运镜**:镜头怎么动——固定 / 推 dolly in / 拉 / 摇 / 横移 / 跟 / 手持 / 环绕 arc。挑**一种**和动作匹配的,别堆;**分清 dolly(机身移、透视变)与 zoom(变焦、透视不变)**。
|
|
27
|
+
4. **光线与氛围**:写**光向 + 光质 + 色温 + 光比**(「窗户来的柔和侧逆光、暖白、半脸入暗的高光比」),不是只写「暖光、干净」。
|
|
28
|
+
5. **结束状态**:这一镜最后定格在什么画面(便于和下一镜衔接 / 链式承接末帧)。
|
|
29
|
+
|
|
30
|
+
**长度**:80–220 词(中文约 60–150 字),写满信息但不灌水。
|
|
31
|
+
|
|
32
|
+
## 四条硬禁忌
|
|
33
|
+
|
|
34
|
+
- **不写时长秒数**(如「持续 3 秒」)——时长由 `--duration` 参数控制,写进 prompt 反而干扰。
|
|
35
|
+
- **不写画幅比例**(如「9:16」)——由 `--aspect-ratio` 控制。
|
|
36
|
+
- **不写声音 / 音效 / BGM / 台词**——这段只描述画面,音频是另一条链。
|
|
37
|
+
- **复刻不要自补创意**——任务是忠于参考的动作和运镜,不是「我觉得这样更好」。要改,等用户明说。
|
|
38
|
+
|
|
39
|
+
## 从 analysis.md → prompt 的字段映射(复刻用)
|
|
40
|
+
|
|
41
|
+
| analysis.md 字段 | 写进 prompt 第几段 |
|
|
42
|
+
|---|---|
|
|
43
|
+
| 主体 / 构图 / 景别 | ① 开场构图 |
|
|
44
|
+
| 描述(发生了什么) | ② 动作弧 —— **若 analysis 只写了静态画面,回看素材补出动作** |
|
|
45
|
+
| 运镜 | ③ 运镜 |
|
|
46
|
+
| 光线 / 色调 | ④ 光线与氛围 |
|
|
47
|
+
| 下一镜首帧需要的画面 | ⑤ 结束状态 |
|
|
48
|
+
|
|
49
|
+
> 复刻链路**最常见的丢分点**:analysis 把每镜写成了「一张静态照片的描述」(主体 + 构图 + 光线),**漏了动作**。video 模型最吃动作。写 prompt 前对照素材确认:每镜的动作弧已经落到第 ② 段。
|
|
50
|
+
|
|
51
|
+
## 例子:同一镜,差 prompt vs 好 prompt
|
|
52
|
+
|
|
53
|
+
**参考镜头**:一只手把懒人拖把按进水桶、提起来甩两下、拖把头展开。
|
|
54
|
+
|
|
55
|
+
❌ **差**(静态、无动作弧、无运镜):
|
|
56
|
+
|
|
57
|
+
> 一只手拿着拖把在厨房里,旁边有个水桶,暖色灯光,干净的画面。
|
|
58
|
+
|
|
59
|
+
→ 模型不知道「要发生什么」,大概率把拖把拍成僵在原地轻微晃动,完全不是参考的「按—提—甩—展开」。
|
|
60
|
+
|
|
61
|
+
✅ **好**(五段式):
|
|
62
|
+
|
|
63
|
+
> 中景,一只手从画面右侧握住平板拖把杆,厨房台面背景虚化。手把拖把头压进左下角的水桶里浸满水,随即利落提起、向右轻甩两下甩掉余水,超细纤维拖把头随甩动展开蓬松。镜头固定,只随拖把头上下轻微跟移。清晨侧光从左侧窗户进来,暖白色调,水珠在光里有细小高光,画面干净有质感。结束时拖把头停在画面中央、纤维完全展开,准备进入下一镜的擦地动作。
|
|
64
|
+
|
|
65
|
+
→ 动作弧(压→提→甩→展开)、运镜(固定 + 轻跟)、光线、结束状态都齐了,模型能照着拍出和参考一致的节奏。
|
|
66
|
+
|
|
67
|
+
## 写完自检(4 个勾)
|
|
68
|
+
|
|
69
|
+
- [ ] 第 ② 段有没有明确的**动作弧**(从 A 变到 B),不是静态描述?
|
|
70
|
+
- [ ] 运镜只挑了**一种**且和动作匹配?
|
|
71
|
+
- [ ] 没出现秒数 / 比例 / 声音?
|
|
72
|
+
- [ ] 复刻镜:动作和运镜**忠于参考**,没自作主张改?
|
|
@@ -7,7 +7,7 @@ owner_repo: Optima-Chat/optima-gen
|
|
|
7
7
|
|
|
8
8
|
# video-translate
|
|
9
9
|
|
|
10
|
-
把口播视频本地化:
|
|
10
|
+
把口播视频本地化:MiniMax 预置明亮女声译音 + 烧录目标语字幕 + BGM ducking(默认开)。**3 步主流程**(+ Step 0 预检 + Step 4 可选清理)。
|
|
11
11
|
|
|
12
12
|
## 适用语言
|
|
13
13
|
|
|
@@ -21,20 +21,21 @@ owner_repo: Optima-Chat/optima-gen
|
|
|
21
21
|
## 前提
|
|
22
22
|
|
|
23
23
|
- 源视频 URL 公网可访问(或先让用户上传到 Optima → 拿 URL)
|
|
24
|
-
- 容器有:`gen` CLI(`@optima-chat/optima-gen` ≥ latest)、`video-translate` CLI(`@optima-chat/video-translate-tools` ≥ 1.0.
|
|
25
|
-
-
|
|
24
|
+
- 容器有:`gen` CLI(`@optima-chat/optima-gen` ≥ latest)、`video-translate` CLI(`@optima-chat/video-translate-tools` ≥ 1.0.9,`--style` 需 1.0.9)、`ffmpeg`、`curl`、`jq`
|
|
25
|
+
- 后端 2026-05 从 HeyGen 切换为 MiniMax pipeline(同接口,~100× 便宜)。CLI 接口未变,旧 `--mode` / `--dynamic-duration` flag 已无效会被忽略
|
|
26
26
|
|
|
27
27
|
## 输入
|
|
28
28
|
|
|
29
29
|
| 参数 | 必填 | 说明 |
|
|
30
30
|
|---|---|---|
|
|
31
31
|
| `URL` | ✅ | 公网可访问的源视频 URL |
|
|
32
|
-
| `LANG` | ✅ |
|
|
32
|
+
| `LANG` | ✅ | 人类可读语言名(见上面 4 语) |
|
|
33
33
|
| `TAG` | ✅ | 对应的两字母 tag(`en` / `th` / `ms` / `vi`) |
|
|
34
34
|
| `BGM` | ⬜ | 自定义 BGM 文件路径(覆盖默认)。不传则用 npm 包内置 `bgm/default.mp3`(22s clean instrumental,自动 loop)|
|
|
35
35
|
| `NO_BGM` | ⬜ | 设非空值则跳过 BGM(出片只有人声 + 原视频 BGM 残留)|
|
|
36
|
-
| `VOICE` | ⬜ |
|
|
36
|
+
| `VOICE` | ⬜ | MiniMax voice_id(从下面 ## Voice Catalog 选)。**不传 = `Portuguese_FriendlyNeighbor`** 默认(友好邻居女声,广谱适用——卖货 / 教程 / demo 都不违和)|
|
|
37
37
|
| `NAME` | ⬜ | 工作区名,默认从 URL 末段推 |
|
|
38
|
+
| `STYLE` | ⬜ | 字幕风格,**不传 = `classic`(原款)**。可选 `pop-soft` / `pop-3d` / `pop-hl` / `anton` / `luckyguy`,见 Step 0.6。需 `video-translate-tools` ≥ 1.0.9 |
|
|
38
39
|
|
|
39
40
|
## 3 步主流程(+ Step 0 预检 + Step 4 可选清理)
|
|
40
41
|
|
|
@@ -42,7 +43,7 @@ owner_repo: Optima-Chat/optima-gen
|
|
|
42
43
|
|
|
43
44
|
```bash
|
|
44
45
|
## ⚠ URL 必须是公网 https URL,不能是本地路径 /home/aiuser/...
|
|
45
|
-
## gen video-translate 只接受 https URL(
|
|
46
|
+
## gen video-translate 只接受 https URL(后端要下载源视频)
|
|
46
47
|
## 如果是本地路径,先用 chat 系统的 file API 签 URL
|
|
47
48
|
if [[ ! "$URL" =~ ^https?:// ]]; then
|
|
48
49
|
echo "INFO: 本地路径 '$URL',需要上传拿 https URL"
|
|
@@ -60,55 +61,107 @@ if [[ ! "$URL" =~ ^https?:// ]]; then
|
|
|
60
61
|
echo "URL → $URL"
|
|
61
62
|
fi
|
|
62
63
|
|
|
63
|
-
## URL 末段可能含 query string(
|
|
64
|
+
## URL 末段可能含 query string(S3 预签名 url 含 token)— 先去掉再 basename
|
|
64
65
|
NAME="${NAME:-$(echo "$URL" | cut -d'?' -f1 | xargs basename | sed 's/\.[^.]*$//' | sed 's/[^A-Za-z0-9_-]/_/g')}"
|
|
65
66
|
WORK="./videos/${NAME}.work"
|
|
66
67
|
mkdir -p "$WORK"
|
|
67
68
|
|
|
68
|
-
## 音量预检 —
|
|
69
|
+
## 音量预检 — Whisper ASR 在 < -25dB 会返回 0 segments(adapter 抛 "source audio too quiet (<-25dB)" 错误)
|
|
69
70
|
## ffmpeg 输出在 stderr,必须 2>&1
|
|
70
71
|
ffmpeg -i "$URL" -af volumedetect -f null - 2>&1 | grep mean_volume
|
|
71
72
|
```
|
|
72
73
|
|
|
73
74
|
如果 `mean_volume < -25dB`,提示用户:"源视频音量太低(< −25dB),翻译服务大概率会报无人声。建议先用 `ffmpeg -i in.mp4 -af 'volume=20dB,acompressor=threshold=-20dB:ratio=4' -c:v copy out.mp4` 放大后再翻译。"
|
|
74
75
|
|
|
75
|
-
### Step 0.5
|
|
76
|
+
### Step 0.5:音色 — 默认**自动双音色**(LLM 标注 A/B),**不问用户**
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
后端默认行为(2026-05 起):**自动双音色** — 翻译时 LLM 给每个 cue 标 speaker A 或 B:
|
|
79
|
+
- **A = `Russian_CrazyQueen`**:反应方 / 提问 / 惊呼("等等!"/ "多少钱?"/ "天哪")
|
|
80
|
+
- **B = `Portuguese_FriendlyNeighbor`**:卖家 / 介绍 / 推销("正品"/ "玻璃材质"/ "今天下单送")
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
对话型视频(赵大大式带货)→ **双女声自然对话感**。单口播视频 → LLM 全标 A,自动退回单音色,**不会瞎切**。**SKILL 不询问音色**,直接 backend 自动判断。
|
|
80
83
|
|
|
84
|
+
```bash
|
|
85
|
+
## 默认走 backend 自动双音色,不需要在 Step 1 显式传 --voice
|
|
86
|
+
VOICE=""
|
|
81
87
|
```
|
|
82
|
-
翻译到 $LANG,4 个语种共用一个音色。请回复编号(1-5)或名字:
|
|
83
88
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
4. Luca - 年轻活力(M) — preview: https://resource.heygen.ai/text_to_speech/locale=model=eleven_multilingual_v2id=FVKYscu8J8EVReBuZdPXnJ.mp3
|
|
88
|
-
5. 保留原声(克隆源说话人音色)
|
|
89
|
+
#### 仅当用户**主动要求换音色**时,才列下面备选并等回复:
|
|
90
|
+
|
|
91
|
+
**用户想全用单一音色**(关掉双音色,例如"全用一个声音"/ "我不要双音色"):
|
|
89
92
|
|
|
90
|
-
|
|
93
|
+
```bash
|
|
94
|
+
SINGLE_VOICE_FLAG="--single-voice" ## Step 1 传给 gen video-translate
|
|
91
95
|
```
|
|
92
96
|
|
|
93
|
-
|
|
97
|
+
**用户想指定具体音色**(例如"用男声"/ "换个更可爱的"):
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
你可以从这 6 个预置音色挑(传 --voice 后所有 cue 都用该 voice,关闭双音色):
|
|
101
|
+
1. Friendly - 友好邻居广谱女声(F) — 默认 B (卖家)
|
|
102
|
+
2. CrazyQueen - 充满活力 + 狂野(F) — 默认 A (反应方)
|
|
103
|
+
3. Sweet - 甜美年轻(F) — 美妆/母婴/温和卖货
|
|
104
|
+
4. Lovely - 可爱俏皮(F) — Z 世代/活泼带货
|
|
105
|
+
5. Trustworthy - 美式磁性沉稳男声(M) — 科技/汽车/正经 demo
|
|
106
|
+
6. Aussie - 澳式阳光男声(M) — 短视频/运动/快消
|
|
107
|
+
|
|
108
|
+
回复数字或名字。
|
|
109
|
+
```
|
|
94
110
|
|
|
95
111
|
| 用户回复 | VOICE 变量值 |
|
|
96
112
|
|---|---|
|
|
97
|
-
| `1` / `
|
|
98
|
-
| `2` / `
|
|
99
|
-
| `3` / `
|
|
100
|
-
| `4` / `
|
|
101
|
-
| `5` /
|
|
102
|
-
|
|
|
113
|
+
| `1` / `Friendly` | **`VOICE=Portuguese_FriendlyNeighbor`** |
|
|
114
|
+
| `2` / `CrazyQueen` / `狂野` | **`VOICE=Russian_CrazyQueen`** |
|
|
115
|
+
| `3` / `Sweet` / `甜美` | **`VOICE=Sweet_Girl`** |
|
|
116
|
+
| `4` / `Lovely` / `可爱` | **`VOICE=lovely_girl`** |
|
|
117
|
+
| `5` / `Trustworthy` / `磁性` / `沉稳` | **`VOICE=English_Trustworthy_Man`** |
|
|
118
|
+
| `6` / `Aussie` / `澳` / `阳光` | **`VOICE=English_Aussie_Bloke`** |
|
|
119
|
+
|
|
120
|
+
#### 严禁
|
|
121
|
+
|
|
122
|
+
- ❌ **主动问"你要哪个音色"** — 默认双音色够好,问了反而增加摩擦
|
|
123
|
+
- ❌ **用 AskUserQuestion 工具**(只有用户主动要求换才列文字菜单)
|
|
124
|
+
- ❌ **加 "克隆原声" 选项** — MiniMax 预置音色管线 v1 不做 voice clone
|
|
125
|
+
|
|
126
|
+
### Step 0.6:字幕风格 — 默认 `classic`(原款),**不主动问**
|
|
127
|
+
|
|
128
|
+
`render-ass` 支持 `--style`(需 `video-translate-tools` ≥ 1.0.9)。**默认不传 = `classic`,与原来的花体字幕完全一致**,默认流程零变化。
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
## 默认走原款,不显式传 --style
|
|
132
|
+
STYLE=""
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### 仅当用户**主动要求换字幕风格**时(如"字幕换个风格"/"字幕太单调"/"用 anton"),才列菜单并等回复:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
字幕风格(回复数字或名字):
|
|
139
|
+
1. classic - 原款:白字黑边 + 粉色关键词(默认)
|
|
140
|
+
2. pop-soft - 立体软影:原款 + 柔和投影,更立体
|
|
141
|
+
3. pop-3d - 立体彩影:洋红 3D 硬投影 + 亮黄关键词,最潮
|
|
142
|
+
4. pop-hl - 关键词亮填:原款 + 关键词亮黄实填
|
|
143
|
+
5. anton - 条形:高条形粗体,现代利落
|
|
144
|
+
6. luckyguy - 圆润:圆润漫画体,活泼
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
| 用户回复 | STYLE |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `1` / classic / 原款 | `STYLE=""`(=classic) |
|
|
150
|
+
| `2` / pop-soft / 立体软影 | `STYLE=pop-soft` |
|
|
151
|
+
| `3` / pop-3d / 立体彩影 / 潮 | `STYLE=pop-3d` |
|
|
152
|
+
| `4` / pop-hl / 关键词亮填 | `STYLE=pop-hl` |
|
|
153
|
+
| `5` / anton / 条形 | `STYLE=anton` |
|
|
154
|
+
| `6` / luckyguy / 圆润 | `STYLE=luckyguy` |
|
|
155
|
+
|
|
156
|
+
#### 严禁
|
|
103
157
|
|
|
104
|
-
|
|
158
|
+
- ❌ **主动问"你要哪个字幕风格"** — 默认 `classic` 够好,问了增加摩擦(同音色逻辑)
|
|
159
|
+
- ❌ **用 AskUserQuestion 工具**(只有用户主动要求换才列文字菜单)
|
|
160
|
+
- ❌ 把菜单外的名字直传 `--style` — render-ass 会 warn 回退 classic,应先在表里映射成合法值
|
|
105
161
|
|
|
106
|
-
|
|
107
|
-
- ❌ **用户选了 1-4,你设 VOICE=空走 clone** — 跟选择不一致就是 bug
|
|
108
|
-
- ❌ **不列全 5 个选项**(比如只列"用 voice / 原声"二选一,等同不让选)
|
|
109
|
-
- ❌ **不告诉用户怎么回复**(必须明确说"回复数字或名字")
|
|
162
|
+
> 风格只改配色/描边/阴影/关键词,**字体仍按语言兜底**(th=Sarabun、vi=Noto;anton 例外,越南语用 Anton)。所有风格对 4 语都安全,不会豆腐块。
|
|
110
163
|
|
|
111
|
-
### Step 1
|
|
164
|
+
### Step 1:翻译(用现成 CLI)
|
|
112
165
|
|
|
113
166
|
```bash
|
|
114
167
|
RAW_DIR="$WORK/raw"
|
|
@@ -116,14 +169,19 @@ mkdir -p "$RAW_DIR"
|
|
|
116
169
|
gen video-translate \
|
|
117
170
|
--video-url "$URL" \
|
|
118
171
|
--lang "$LANG" \
|
|
119
|
-
--mode fast \
|
|
120
|
-
--dynamic-duration \
|
|
121
172
|
${VOICE:+--voice "$VOICE"} \
|
|
173
|
+
${SINGLE_VOICE_FLAG:-} \
|
|
122
174
|
-o "$RAW_DIR" \
|
|
123
175
|
> "$WORK/gen.json"
|
|
124
176
|
```
|
|
125
177
|
|
|
126
|
-
`gen video-translate`
|
|
178
|
+
`gen video-translate` 自动轮询。**完成时间随 cue 数线性增长**(adapter 段间 1.5s sleep 防 RPM):
|
|
179
|
+
- < 30s 视频(~10 cues):2-3 min
|
|
180
|
+
- 1 min 视频(~20 cues):3-5 min
|
|
181
|
+
- 5 min 视频(~50 cues):**10-15 min**(注意 BullMQ worker slot 占用)
|
|
182
|
+
- 10 min+ 视频:**不推荐**,接近 30 min poll timeout 上限
|
|
183
|
+
|
|
184
|
+
失败 / 超时见末尾错误表。
|
|
127
185
|
|
|
128
186
|
幂等:`$WORK/gen.json` 存在则跳。
|
|
129
187
|
|
|
@@ -149,27 +207,81 @@ AUDIO="$WORK/translated_audio.wav"
|
|
|
149
207
|
SRT="$WORK/caption.srt"
|
|
150
208
|
[ -s "$SRT" ] || curl -sSL --retry 1 "$CAP_URL" -o "$SRT"
|
|
151
209
|
|
|
210
|
+
## SRT 必须非空 — 后端偶发返回 0 字节 SRT(Whisper 无语音 / 上传失败),后续 sync 检查会拿到空 end_time
|
|
211
|
+
[ -s "$SRT" ] || { echo "ERR: $SRT 空或损坏,gen.json 内 caption_url 可能已 expire,重跑 Step 1"; exit 1; }
|
|
212
|
+
|
|
152
213
|
ASS="$WORK/subs.ass"
|
|
153
214
|
TRANS="$WORK/translations.json"
|
|
154
215
|
video-translate render-ass \
|
|
155
216
|
--srt "$SRT" \
|
|
156
217
|
--lang "$TAG" \
|
|
218
|
+
${STYLE:+--style "$STYLE"} \
|
|
157
219
|
--translations "$TRANS" \
|
|
158
220
|
--out "$ASS"
|
|
159
221
|
```
|
|
160
222
|
|
|
161
223
|
用户可手编 `$TRANS`(给关键词加 `**word**` 触发粉色 KW 描边)后删 `$ASS` 重跑这步。
|
|
162
224
|
|
|
225
|
+
### Step 2.5:A/V sync 预检(必跑,挡掉调试不收敛的常见根因)
|
|
226
|
+
|
|
227
|
+
**为什么必跑**:用户反馈"字幕和配音调试多次不同频"。绝大多数情况不是字幕样式问题,而是后端 audio 时长跟 SRT 末尾时间戳本身就对不上(MiniMax adaptive-speed 调整不完美时会有 < 1s 累积漂移),或者跟原视频时长差距过大。**不在 mux 前查,用户只能盲调,改 10 次还是错。**
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
## 原视频本地化(Step 3 也需要,提前到这里让 sync 预检能算 VIDEO_DUR)
|
|
231
|
+
ORIG_VIDEO="$URL"
|
|
232
|
+
if [[ "$URL" =~ ^https?:// ]]; then
|
|
233
|
+
ORIG_VIDEO="$WORK/orig.mp4"
|
|
234
|
+
[ -f "$ORIG_VIDEO" ] || curl -sSL "$URL" -o "$ORIG_VIDEO"
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
## audio 实际时长(秒,保留 3 位小数)
|
|
238
|
+
AUDIO_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$AUDIO")
|
|
239
|
+
|
|
240
|
+
## SRT 最后一行 cue 的 end 时间(秒)
|
|
241
|
+
SRT_END=$(awk '
|
|
242
|
+
/-->/ { t=$3; gsub(",", ".", t); split(t, p, ":"); end = p[1]*3600 + p[2]*60 + p[3] }
|
|
243
|
+
END { print end }
|
|
244
|
+
' "$SRT")
|
|
245
|
+
|
|
246
|
+
## 原视频时长(用于检测 audio 超出/不足)
|
|
247
|
+
VIDEO_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$ORIG_VIDEO" 2>/dev/null || echo "0")
|
|
248
|
+
|
|
249
|
+
printf "AV-sync: audio=%.3fs srt_end=%.3fs video=%.3fs\n" "$AUDIO_DUR" "$SRT_END" "$VIDEO_DUR"
|
|
250
|
+
|
|
251
|
+
## 1. audio vs SRT — 这是字幕看起来 "晚" 或 "早" 收尾的直接原因
|
|
252
|
+
DELTA_AS=$(awk -v a="$AUDIO_DUR" -v s="$SRT_END" 'BEGIN { d=a-s; if (d<0) d=-d; print d }')
|
|
253
|
+
if awk "BEGIN { exit !($DELTA_AS > 0.5) }"; then
|
|
254
|
+
echo "ERR: audio 与 SRT 末时间差 ${DELTA_AS}s (>0.5s)。"
|
|
255
|
+
echo " 根因多半是后端本次输出 audio/SRT 不同步,继续 mux 字幕会全段漂。"
|
|
256
|
+
echo " remediation: rm $WORK/gen.json $AUDIO $SRT && 重跑 Step 1 拿新一对 audio+SRT。"
|
|
257
|
+
exit 1
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
## 2. audio vs video — 字幕和声音一致但跟画面不齐
|
|
261
|
+
if [ "$VIDEO_DUR" != "0" ]; then
|
|
262
|
+
DELTA_AV=$(awk -v a="$AUDIO_DUR" -v v="$VIDEO_DUR" 'BEGIN { d=a-v; if (d<0) d=-d; print d }')
|
|
263
|
+
if awk "BEGIN { exit !($DELTA_AV > 1.0) }"; then
|
|
264
|
+
echo "INFO: audio 与原视频时长差 ${DELTA_AV}s。mux 会按 --raw 时长裁/补,字幕跟音同步但画面可能错位。"
|
|
265
|
+
fi
|
|
266
|
+
fi
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**触发条件 + 决策**:
|
|
270
|
+
- `DELTA_AS > 0.5s` → **默认停**,提示用户重跑 Step 1。盲跑 mux 然后再调字幕样式没用,根因在后端 TTS 输出。
|
|
271
|
+
- `DELTA_AV > 1.0s` → 只是 info,不挡;但要在 Step 3 出片汇报里如实告诉用户。
|
|
272
|
+
- 两条都 ≤ 阈值 → 直通 Step 3。
|
|
273
|
+
|
|
274
|
+
幂等:这个 block 没有副作用,可以反复跑。
|
|
275
|
+
|
|
163
276
|
### Step 3:Mux 出片
|
|
164
277
|
|
|
165
278
|
```bash
|
|
166
279
|
FINAL="./videos/${NAME}_${TAG}.mp4"
|
|
167
280
|
|
|
168
|
-
## --orig-video 关键:用用户原视频画面(
|
|
169
|
-
##
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if [[ "$URL" =~ ^https?:// ]]; then
|
|
281
|
+
## --orig-video 关键:用用户原视频画面(MiniMax pipeline 不生成新视频,只换音轨,这里把原画面+新音轨合一)
|
|
282
|
+
## ORIG_VIDEO 通常已在 Step 2.5 落到本地;这里幂等兜底,允许只想换字幕样式时跳着复跑 Step 3
|
|
283
|
+
ORIG_VIDEO="${ORIG_VIDEO:-$URL}"
|
|
284
|
+
if [[ "$ORIG_VIDEO" =~ ^https?:// ]]; then
|
|
173
285
|
ORIG_VIDEO="$WORK/orig.mp4"
|
|
174
286
|
[ -f "$ORIG_VIDEO" ] || curl -sSL "$URL" -o "$ORIG_VIDEO"
|
|
175
287
|
fi
|
|
@@ -185,8 +297,8 @@ video-translate mux \
|
|
|
185
297
|
```
|
|
186
298
|
|
|
187
299
|
**关键**:管线匹配本地水杯/zhaodada 批量出片行为:
|
|
188
|
-
- `--orig-video` = 用户原视频画面(
|
|
189
|
-
- `--raw` =
|
|
300
|
+
- `--orig-video` = 用户原视频画面(MiniMax 不动画面,只换音轨)
|
|
301
|
+
- `--raw` = 后端译音(audio_url 下载的 wav)
|
|
190
302
|
- 字幕烧 + BGM ducking 走 mux 内置
|
|
191
303
|
|
|
192
304
|
**BGM + 花体字幕样式 = 默认产出的一部分,不是可选项。** 不要问用户"要不要加",不要在结尾说"如需 BGM/字幕样式可补充"。`video-translate mux` 默认就用 `bgm/default.mp3` + Path-B 描边样式;`render-ass --lang $TAG` 默认按语言选字体(Bangers / Sarabun / Noto Sans)。不要绕过 `mux` 自己手写 ffmpeg(会丢 BGM + 字幕样式 + 音轨规范化)。
|
|
@@ -211,10 +323,12 @@ rm -rf "$WORK"
|
|
|
211
323
|
**触发条件**:用户一次请求 ≥2 种目标语言("翻译成英/泰/越/马 4 国语")。
|
|
212
324
|
|
|
213
325
|
**不要按单语流程循环跑 N 次**——会有两个致命问题:
|
|
214
|
-
1. wall time = N × 单次 (~
|
|
326
|
+
1. wall time = N × 单次 (~5min/lang × 4 = 20min)
|
|
215
327
|
2. chat bash 队列被 N 条阻塞命令塞满,后续命令(mux/SFX)全卡"准备中"
|
|
216
328
|
|
|
217
|
-
改用 **单条 bash 内 N 路 subshell 并发**:chat 队列只占 1 slot
|
|
329
|
+
改用 **单条 bash 内 N 路 subshell 并发**:chat 队列只占 1 slot。
|
|
330
|
+
|
|
331
|
+
> ⚠ **MiniMax RPM 限速注意**:MiniMax 新账户 RPM 默认 1-2,4 路并发会触发后端段间 retry,实际 wall time 可能并不省 vs 串行。如果发现 batch 比单语 ×4 还慢,考虑升级 MiniMax tier 或改回串行。Phase 1 默认仍走并发(代码路径已验证)。
|
|
218
332
|
|
|
219
333
|
### Step B0:URL 预处理 + workspace + 音量预检 + 源视频下载(只跑一次)
|
|
220
334
|
|
|
@@ -242,11 +356,13 @@ ORIG_VIDEO="./videos/${NAME}.batch/orig.mp4"
|
|
|
242
356
|
[ -f "$ORIG_VIDEO" ] || curl -sSL "$URL" -o "$ORIG_VIDEO"
|
|
243
357
|
```
|
|
244
358
|
|
|
245
|
-
### Step B0.5:voice
|
|
359
|
+
### Step B0.5:voice 默认 backend 预置,不问
|
|
360
|
+
|
|
361
|
+
同单语 Step 0.5,默认 `VOICE=""` 走后端 `Portuguese_FriendlyNeighbor`。仅当用户主动要求换音色才列菜单 + 设 `VOICE`。所有语种 subshell 共用同一个 `VOICE`。
|
|
246
362
|
|
|
247
|
-
|
|
363
|
+
字幕风格同理(Step 0.6):默认 `STYLE=""`(=classic 原款),仅用户主动要求才设;所有语种共用同一个 `STYLE`,已在下方 per-lang 模板的 `render-ass` 里以 `${STYLE:+--style "$STYLE"}` 透传。
|
|
248
364
|
|
|
249
|
-
### Step B1
|
|
365
|
+
### Step B1:并发派出所有翻译(后台跑,~5 秒返回)
|
|
250
366
|
|
|
251
367
|
```bash
|
|
252
368
|
## 用户实际要的语种,从下面 4 个里选(不要的注释掉)
|
|
@@ -266,7 +382,6 @@ for entry in "${LANG_LIST[@]}"; do
|
|
|
266
382
|
## 后台启动 gen video-translate,各自写 gen.json,bash 立即继续
|
|
267
383
|
nohup gen video-translate \
|
|
268
384
|
--video-url "$URL" --lang "$LANG" \
|
|
269
|
-
--mode fast --dynamic-duration \
|
|
270
385
|
${VOICE:+--voice "$VOICE"} \
|
|
271
386
|
-o "$WORK/raw" > "$WORK/gen.json" 2>&1 &
|
|
272
387
|
|
|
@@ -275,13 +390,13 @@ done
|
|
|
275
390
|
echo "=== all submitted, returning immediately ==="
|
|
276
391
|
```
|
|
277
392
|
|
|
278
|
-
这一步 5 秒返回。**关键**:用 `nohup ... &` 后台启动,bash exit 后进程继续(尽量 survive 短暂 idle / 容器升级)。每个进程会在
|
|
393
|
+
这一步 5 秒返回。**关键**:用 `nohup ... &` 后台启动,bash exit 后进程继续(尽量 survive 短暂 idle / 容器升级)。每个进程会在 MiniMax pipeline 完成后把 audio_url/caption_url 写入对应的 gen.json。
|
|
279
394
|
|
|
280
395
|
### Step B2-B5:逐语种等结果 → 出片(每个一条独立 bash)
|
|
281
396
|
|
|
282
397
|
**重点:每个语种用单独的 bash 命令处理,不要再用 `&` 并发**。这样:
|
|
283
398
|
- chat 看到每个语种独立完成、独立报告
|
|
284
|
-
- 第 1 个 bash
|
|
399
|
+
- 第 1 个 bash 等翻译(~5-8 min),后续每个 bash 几乎瞬间完成(因为 4 个翻译是并行跑的,后续几个早已 done)
|
|
285
400
|
- 失败隔离:1 个失败不影响其他
|
|
286
401
|
|
|
287
402
|
通用 per-lang 模板(把 `$TAG` 换成 en / th / ms / vi 各跑一遍):
|
|
@@ -293,7 +408,7 @@ FINAL="./videos/${NAME}_${TAG}.mp4"
|
|
|
293
408
|
|
|
294
409
|
## 等 gen.json 写完(或失败)
|
|
295
410
|
## ⚠ gen-cli 用 outputSuccess 包装在 {success, data: {...}} 里,字段在 .data.* 下
|
|
296
|
-
DEADLINE=$(( $(date +%s) + 1800 )) ## 30min
|
|
411
|
+
DEADLINE=$(( $(date +%s) + 1800 )) ## 30min 上限,跟后端 poll timeout 对齐
|
|
297
412
|
while true; do
|
|
298
413
|
## Case 1: 成功 → .data.audio_url 非 null
|
|
299
414
|
if jq -e '.data.audio_url' "$WORK/gen.json" >/dev/null 2>&1; then
|
|
@@ -309,7 +424,7 @@ while true; do
|
|
|
309
424
|
echo "[$TAG] FAIL: $(jq -r '.error.code + \": \" + .error.message' "$WORK/gen.json")"
|
|
310
425
|
exit 1
|
|
311
426
|
fi
|
|
312
|
-
## Case 4: 30min 超时(
|
|
427
|
+
## Case 4: 30min 超时(MiniMax pipeline 一般 3-8min,30min 还没就是真挂了)
|
|
313
428
|
if [ "$(date +%s)" -gt "$DEADLINE" ]; then
|
|
314
429
|
echo "[$TAG] TIMEOUT 30min,gen.json 内容:"; cat "$WORK/gen.json"; exit 1
|
|
315
430
|
fi
|
|
@@ -323,11 +438,26 @@ CAP_URL=$(jq -r '.data.caption_url' "$WORK/gen.json")
|
|
|
323
438
|
## 下载 + render-ass
|
|
324
439
|
curl -sSL --retry 1 "$AUDIO_URL" -o "$WORK/translated_audio.wav"
|
|
325
440
|
curl -sSL --retry 1 "$CAP_URL" -o "$WORK/caption.srt"
|
|
441
|
+
[ -s "$WORK/caption.srt" ] || { echo "[$TAG] ERR: SRT 空/损坏"; exit 1; }
|
|
326
442
|
video-translate render-ass \
|
|
327
443
|
--srt "$WORK/caption.srt" --lang "$TAG" \
|
|
444
|
+
${STYLE:+--style "$STYLE"} \
|
|
328
445
|
--translations "$WORK/translations.json" \
|
|
329
446
|
--out "$WORK/subs.ass"
|
|
330
447
|
|
|
448
|
+
## A/V sync 预检(同单语 Step 2.5,挡后端偶发 audio/SRT 不同步)
|
|
449
|
+
AUDIO_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$WORK/translated_audio.wav")
|
|
450
|
+
SRT_END=$(awk '
|
|
451
|
+
/-->/ { t=$3; gsub(",", ".", t); split(t, p, ":"); end = p[1]*3600 + p[2]*60 + p[3] }
|
|
452
|
+
END { print end }
|
|
453
|
+
' "$WORK/caption.srt")
|
|
454
|
+
DELTA_AS=$(awk -v a="$AUDIO_DUR" -v s="$SRT_END" 'BEGIN { d=a-s; if (d<0) d=-d; print d }')
|
|
455
|
+
printf "[%s] AV-sync: audio=%.3fs srt_end=%.3fs delta=%.3fs\n" "$TAG" "$AUDIO_DUR" "$SRT_END" "$DELTA_AS"
|
|
456
|
+
if awk "BEGIN { exit !($DELTA_AS > 0.5) }"; then
|
|
457
|
+
echo "[$TAG] WARN: audio/SRT 时间差 >0.5s,跳过本语 mux。删 $WORK/gen.json 重跑 Step B1 该 lang。"
|
|
458
|
+
exit 1
|
|
459
|
+
fi
|
|
460
|
+
|
|
331
461
|
## mux 出片
|
|
332
462
|
video-translate mux \
|
|
333
463
|
--raw "$WORK/translated_audio.wav" \
|
|
@@ -356,17 +486,17 @@ echo "[$TAG] DONE -> $FINAL"
|
|
|
356
486
|
| | 单语循环(❌ 不要) | 渐进批量(✓) |
|
|
357
487
|
|---|---|---|
|
|
358
488
|
| 源视频下载 | N 次重下 | 1 次共用 |
|
|
359
|
-
|
|
|
489
|
+
| 翻译调用 | 串行 N × 5min | 并发(受 MiniMax RPM 限速影响) |
|
|
360
490
|
| chat 队列占 | N 条阻塞 bash | 1 条 submit + N 条快速 poll |
|
|
361
491
|
| 失败隔离 | 一个挂全停 | per-lang subshell + bash 独立 |
|
|
362
|
-
| 用户感知 | 黑盒
|
|
363
|
-
| **wall time(N=4)** | **~
|
|
492
|
+
| 用户感知 | 黑盒 ~20 min | 第 1 个 ~5-8 min 出,后续每 ~30 秒 1 个 |
|
|
493
|
+
| **wall time(N=4)** | **~20 min** | **~8-12 min**(实际看 MiniMax tier) |
|
|
364
494
|
|
|
365
495
|
### 失败处理
|
|
366
496
|
|
|
367
497
|
- 单 lang 失败:per-lang bash `exit 1`,agent 报告该语种失败但**继续跑下一个语种的 bash**
|
|
368
498
|
- 用户对失败的单 lang re-run → 删 `$WORK/gen.json` 重跑 Step B1 单语 + per-lang 模板即可
|
|
369
|
-
-
|
|
499
|
+
- MiniMax 余额不足 / RPM 限速持续失败 → 当 lang 个失败处理,不阻塞其他 lang
|
|
370
500
|
|
|
371
501
|
## 错误处理
|
|
372
502
|
|
|
@@ -374,20 +504,24 @@ echo "[$TAG] DONE -> $FINAL"
|
|
|
374
504
|
|---|---|
|
|
375
505
|
| URL 不通 | 重传或上传到 Optima 拿新 URL,不消耗翻译服务 credits |
|
|
376
506
|
| 源视频音量过低 | 让用户先用 ffmpeg `volume=20dB,acompressor` 放大后重传 |
|
|
377
|
-
|
|
|
378
|
-
|
|
|
379
|
-
|
|
|
507
|
+
| 后端 `status: failed` 包含 "no speaker" / "0 segments" | 源视频音量过低,同上处理 |
|
|
508
|
+
| MiniMax `1008 insufficient balance` | MiniMax 账户余额不足,运维充值后重跑 |
|
|
509
|
+
| MiniMax `1002 rate limit exceeded` 持续失败 | RPM tier 不够;后端有指数退避兜底,长视频可能超时 → 联系运维升级 tier |
|
|
510
|
+
| 后端其他失败 | 透出 task_id,提示用 `gen task get <id>` 查最新;干净退出 |
|
|
511
|
+
| 翻译 >30min 超时 | 同上,可能任务还在 running |
|
|
380
512
|
| `gen.json` 缺 `.audio_url` / `.caption_url` | gen 后端契约可能改字段名。打 `cat $WORK/gen.json` 看实际字段 |
|
|
381
|
-
| `curl <caption_url>` 失败 | URL
|
|
513
|
+
| `curl <caption_url>` 失败 | S3 presigned URL 24 小时 expire。retry 1 次后仍失败 → 重跑 step 1 |
|
|
382
514
|
| `video-translate render-ass` SRT 解析失败 | 显示 SRT 头 20 行,不重试 |
|
|
383
515
|
| `video-translate mux` 字体 ☐ | 检查 `fc-match Bangers / Sarabun / "Noto Sans"` 是否精确返回 |
|
|
516
|
+
| Step 2.5 报 "audio 与 SRT 末时间差 > 0.5s" | MiniMax adaptive-speed 本次大幅偏离,**字幕调样式没用**。删 `$WORK/gen.json $AUDIO $SRT`,重跑 Step 1 |
|
|
384
517
|
|
|
385
518
|
## 不做
|
|
386
519
|
|
|
387
|
-
- ❌ 性别自动检测(
|
|
520
|
+
- ❌ 性别自动检测(默认 `Portuguese_FriendlyNeighbor` 女声,用户想换主动说)
|
|
388
521
|
- ❌ 硬字幕(burnt-in)抹除 — 源视频有的话出片会双语
|
|
389
522
|
- ❌ 自动加粗关键词 — SRT 直入无粉色,用户手编 translations.json
|
|
390
|
-
- ❌ 双说话人差异化音色 —
|
|
523
|
+
- ❌ 双说话人差异化音色 — MiniMax v1 单音色 default,手动传 speakers JSON 才能分轨(SKILL v1 不暴露)
|
|
524
|
+
- ❌ 克隆原说话人音色 — MiniMax voice clone API 是独立流程,v1 不上
|
|
391
525
|
- ❌ 一次多语言 — 一次一种语言
|
|
392
526
|
|
|
393
527
|
## 参考
|
|
@@ -399,13 +533,15 @@ echo "[$TAG] DONE -> $FINAL"
|
|
|
399
533
|
|
|
400
534
|
## Voice Catalog
|
|
401
535
|
|
|
402
|
-
下面
|
|
536
|
+
下面 6 个 voice 是 MiniMax 预置音色,**任选一个,所有支持语言(en/th/ms/vi)都能说**(底层 `speech-02-turbo` + `language_boost` 跨语自适应)。POC 验证(2026-05)在卖货场景下跨 4 语均自然,Whisper 反向验证语种识别 > 90%。
|
|
403
537
|
|
|
404
|
-
| # | voice_id |
|
|
405
|
-
|
|
406
|
-
| 1 | `
|
|
407
|
-
| 2 | `
|
|
408
|
-
| 3 | `
|
|
409
|
-
| 4 | `
|
|
538
|
+
| # | voice_id | 风格定位 | 适用场景 |
|
|
539
|
+
|---|---|---|---|
|
|
540
|
+
| 1 | `Portuguese_FriendlyNeighbor` | 充满活力的友好邻居(F) | **默认** — 销售 / 教程 / demo,广谱适用 |
|
|
541
|
+
| 2 | `Russian_CrazyQueen` | 充满活力 + 狂野不可预测(F) | 反应方 / 惊呼 / 高能开场 |
|
|
542
|
+
| 3 | `Sweet_Girl` | 甜美年轻(F) | 美妆 / 母婴 / 温和卖货 |
|
|
543
|
+
| 4 | `lovely_girl` | 可爱俏皮(F) | Z 世代 / 活泼带货 |
|
|
544
|
+
| 5 | `English_Trustworthy_Man` | 美式磁性沉稳(M,带通用美式口音) | 科技 / 汽车 / 严肃产品 demo |
|
|
545
|
+
| 6 | `English_Aussie_Bloke` | 阳光开朗(M,澳式口音) | 短视频 / 运动 / 快消 |
|
|
410
546
|
|
|
411
|
-
>
|
|
547
|
+
> 维护说明:从 MiniMax `POST /v1/get_voice` 接口可拉全量 303 个预置音色。挑跨语 voice 优先 `English_` / `Russian_` / `Portuguese_` / `Sweet_` / `lovely_` / `Indonesian_` 前缀(描述含 "活力 / 甜美 / 俏皮 / Trustworthy / Bloke" 关键词的);其他 `Chinese_` / `Korean_` / `Japanese_` 前缀的强单语音色硬说外语会有明显口音。试新 voice 必须先用 `text="测试一句"` × 4 语单独调一次听感再批量上(参考 [[feedback_api_accept_neq_use]]:API 接受 ≠ 输出可用)。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# BGM 情绪库 — 来源与授权
|
|
2
|
+
|
|
3
|
+
所有曲目来自 **FreePD.com**,授权 **CC0 1.0(公共领域,可商用、零署名)**。
|
|
4
|
+
原始仓库镜像:`SoundSafari/CC0-1.0-Music`(`freepd.com/` 目录,CC0-1.0)。
|
|
5
|
+
|
|
6
|
+
本库文件已转码瘦身(30s、80kbps、mono、首尾淡入淡出)用于成片 BGM。
|
|
7
|
+
|
|
8
|
+
| 目录(情绪) | 文件 | FreePD 原曲 |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| warm | warm-01.mp3 | Aquarium |
|
|
11
|
+
| warm | warm-02.mp3 | Adding the Sun |
|
|
12
|
+
| calm | calm-01.mp3 | Amazing Grace |
|
|
13
|
+
| calm | calm-02.mp3 | Baltic Levity |
|
|
14
|
+
| upbeat | upbeat-01.mp3 | And Here We Go |
|
|
15
|
+
| upbeat | upbeat-02.mp3 | Backbeat |
|
|
16
|
+
| sad | sad-01.mp3 | After the End |
|
|
17
|
+
| sad | sad-02.mp3 | A Waltz For Naseem |
|
|
18
|
+
| energetic | energetic-01.mp3 | Action Strike |
|
|
19
|
+
| energetic | energetic-02.mp3 | Battle Ready |
|
|
20
|
+
| dramatic | dramatic-01.mp3 | Ancient Rite |
|
|
21
|
+
| dramatic | dramatic-02.mp3 | Alien Invasion |
|
|
22
|
+
|
|
23
|
+
注:情绪分类按曲名启发式归类,未经逐曲试听校准,可按实际听感调整目录归属。
|
|
24
|
+
扩库:往对应情绪目录丢入**可商用授权**的音频即可(脚本自动纳入随机池)。
|
|
25
|
+
CC0 全文:https://creativecommons.org/publicdomain/zero/1.0/
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/assets/video-compose/voice-samples/01-/346/270/251/346/232/226/345/260/221/345/245/263.mp3
ADDED
|
Binary file
|
package/assets/video-compose/voice-samples/02-/347/224/234/347/276/216/345/245/263/345/243/260.mp3
ADDED
|
Binary file
|
package/assets/video-compose/voice-samples/03-/347/224/234/347/276/216/345/205/203/346/260/224.mp3
ADDED
|
Binary file
|
package/assets/video-compose/voice-samples/04-/346/270/205/347/224/234/345/260/221/345/245/263.mp3
ADDED
|
Binary file
|
package/assets/video-compose/voice-samples/06-/346/210/220/347/206/237/347/237/245/346/200/247.mp3
ADDED
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# 音色样音目录(label = voice_id)
|
|
2
|
+
# Claude:把这些 mp3 给用户试听,用户选定后把对应 voice_id 写进 proposal.voice
|
|
3
|
+
01-温暖少女 = Chinese (Mandarin)_Warm_Girl
|
|
4
|
+
02-甜美女声 = Chinese (Mandarin)_Sweet_Lady
|
|
5
|
+
03-甜美元气 = female-tianmei
|
|
6
|
+
04-清甜少女 = female-shaonv
|
|
7
|
+
05-御姐 = female-yujie
|
|
8
|
+
06-成熟知性 = female-chengshu
|
|
9
|
+
07-女主播 = presenter_female
|