knowledge-vault/discussions/technology/Claude-Code/Voice管理/1.mmx讨论与测试.md

15 KiB
Raw Permalink Blame History

我这样每次都确认太麻烦,能不能写个交接文档,如果需要的话。 我准备重启Cluade下次启动会加上参数--permission-mode auto,这样就不用每次都确认了。

但是我还想续着本次的工作。你看我怎么样处理合适,你做哪些?

1

# 在本地路径下,建一个工作目录,比如`D:\AI\ClaudeCode\voice-ge`运行powershell

# cli进入工作目录
cd D:\AI\ClaudeCode\voice-ge

# 启动Claude 自动审批模式
claude --permission-mode auto

# 以下是对话内容:

我有一个Mmx CLI的Skill你看看能不能用

2

你也用的是minimax账户是一套。它的这些能力准确说应该你也有你能做这些么

3

那么我准备基于mmx cli开发一个语音生成的系统或者叫Agent系统。

分为环境准备和工作两部分:

环境准备:

  1. 我指定一个我的语音文件确定生成的voice id你调用Mmx 生成这个voice id记录下来。
  2. 我可能有多个语音账户下生成多个voice id

工作:

  1. 有voice id 清单我选择具体的voice id
  2. 指定一个口播稿路径,基于路径下的文稿,在指定的目标目录下生成语音文件
    1. 可能是一个口播稿,也可能是多个;
    2. 口播稿文件名,需要与口播稿同名,只是后缀不同:口播稿是.md格式生成的语音文件看能生成什么格式的。

使用方式:

  1. 是命令行的方式我可以包装成一个技能直接在Cluade CodeCodex或者OpenClaw中进行调用。

基于以上,你能帮我做一个规划么? 你的工作目录是D:\AI\ClaudeCode\voice-ge,你可以认为这个就是开发用的路径。你的规划,将来的脚本或者过程产物都放在这里。

4

plan我看了我同意。 只是一个小小的修正我本地是有Conda环境的不要直接用python在Conda中建一个与本次配套的新环境及环境清单如果我想移植到别的机器的话将来测试跑脚本都在Conda的环境里。

接下来你就要进入开发阶段了么?

5

远程仓库:https://git.wantsong.life/wantsong/voice-generation.git 我们把这个项目push 到远程仓库里。

6

我输入 voice-gen init报错了,下面是执行信息:

(base) PS C:\Users\wangq> conda activate voice-gen
(voice-gen) PS C:\Users\wangq> cd D:/AI/ClaudeCode/voice-ge
(voice-gen) PS D:\AI\ClaudeCode\voice-ge> voice-gen init
voice-gen : 无法将“voice-gen”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写如果包括路径请确
保路径正确,然后再试一次。
所在位置 行:1 字符: 1
+ voice-gen init
+ ~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (voice-gen:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

7

我确认一下,我刚执行了:

(base) PS C:\Users\wangq> conda activate voice-gen
(voice-gen) PS C:\Users\wangq> cd D:/AI/ClaudeCode/voice-ge
(voice-gen) PS D:\AI\ClaudeCode\voice-ge> cd D:\Mine\口(voice-gen) PS D:\Mine\口播> voice-gen init
initialized in D:\Mine\口(voice-gen) PS D:\Mine\口播> voice-gen voices list
(no voices registered; run `voice-gen voices add <name> <mp3>`)
(voice-gen) PS D:\Mine\口播>

现在通知我没有no voices registered,服务器上的已经删过了是么?

因为voice id是和minimax cli的账号绑定的如果我在本机这个路径下做了voice id那么我在别的机器也用这个账号的话init时应该能拿下来。 除了init外是否应该有一个pull voice id的指令把voice id在本地与服务器同步一下。

8

现在服务器上的文件都是旧的,需要清掉。 先清服务器上的旧文件。

我在D:\Mine\口播环境下,上传新的音频,在新环境里测试。完了再说看需要补充哪些功能。

9

voice-gen voices add wantsong ./your-sample.mp3 --notes "anchor"

示例命令中的--notes "anchor" 是什么意思是voice-id么 我看你刚给的,又变成了"anchor voice",这个给谁用的,我能填中文么?

voiceid默认就是音频文件名对吧

10

voice-gen voices add这个命令需要更新,增加friendly name或者将notes直接改成friendly name。

notes对我没用将来显示friendly name,我直接用这个:

voice-gen voices add wantsong C:\Users\wangq\Documents\录\BroTsong-Saying.m4a --name "BroTsong-2026-06-10"

你看下这个命令格式是否正确。

json形如


"voices": {
   "wantsong": {
   "file_id":396061597295017,
   "filename": "your-sample.mp3",
   "created_at": "2026-06-10T...",
   "friendly_name": "BroTsong-2026-06-10" }
   }

你看下我的这个诉求,是否合理,合理的话。

  1. 改程序
  2. 我的这个D:\Mine\口播环境需要重新初始化么,还是直接可以继续。

C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a

11

Dict key干啥用的? 你的意思比如wantsong类似于张三可以作为分组他名下有好多voice还可以有个李四名下也好多voice。这个我这里不需要。

直接拿 BroTsong-2026-06-10 当 dict key 和 --voice 的入参,不要 wantsong。我开始没明白json里的wantong是啥。这样的话json里也不用出现friendly_name了。 那么调整完,形如:

voice-gen voices add wantsong C:\Users\wangq\Documents\录\BroTsong-Saying.m4a --name "BroTsong-2026-06-10"

"voices": {
   "BroTsong-2026-06-10": {
      "file_id":396061597295017,
      "filename": "your-sample.mp3",
      "created_at": "2026-06-10T..." }
   }

这样就ok了。

若对齐思路,你可以做调整了。

12

我执行:

voice-gen voices add BroTsong-2026-06-10 "C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a"

报错了:

(voice-gen) PS D:\Mine\口播> voice-gen voices add BroTsong-2026-06-10 "C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a"
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\wangq\miniconda3\envs\voice-gen\Scripts\voice-gen.exe\__main__.py", line 5, in <module>
  File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 226, in main
    return cmd_voices_add(args)
           ^^^^^^^^^^^^^^^^^^^^
  File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 121, in cmd_voices_add
    info = _upload_voice_file(audio)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 61, in _upload_voice_file
    raise MmxError(exit_code=result.returncode, stderr=result.stderr, command=" ".join(cmd))
voice_gen.errors.MmxError: mmx command failed (exit=1): {
  "error": {
    "code": 1,
    "message": "API error: HTTP 404 (HTTP 404)"
  }
} [cmd: mmx file upload --non-interactive --quiet --output json --file C:\Users\wangq\Documents\录\BroTsong-Saying.m4a --purpose voice_clone]

13

应该是生成了'BroTsong-2026-06-10' voice按照你的测试生成了hello.md

然后生成语音报错了

(voice-gen) PS D:\Mine\口播> voice-gen voices add BroTsong-2026-06-10 "C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a"
registered 'BroTsong-2026-06-10'file_id=407449867293232
(voice-gen) PS D:\Mine\口播> echo "Hello, this is a test." > scripts/hello.md
(voice-gen) PS D:\Mine\口播> voice-gen gen --voice BroTsong-2026-06-10 scripts
✗ hello.md: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
done: 0 ok, 1 failed

14

执行后,报错:

(voice-gen) PS D:\Mine\口播> voice-gen gen --voice BroTsong-2026-06-10 scripts
✗ hello.md: mmx command failed (exit=1): {
  "error": {
    "code": 1,
    "message": "API error: voice id not exist (HTTP 200)"
  }
} [cmd: mmx speech synthesize --non-interactive --quiet --text Hello, this is a test. --voice 407449867293232 --format mp3 --out output\hello.mp3]
done: 0 ok, 1 failed
(voice-gen) PS D:\Mine\口播>

15

报错:


(voice-gen) PS D:\Mine\口播> voice-gen voices list
(no voices registered; run `voice-gen voices add <name> <mp3>`)
(voice-gen) PS D:\Mine\口播> voice-gen voices add BroTsong-2026-06-10 "C:\Users\wangq\Documents\录音\BroTsong-Saying.m4a"
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\wangq\miniconda3\envs\voice-gen\Scripts\voice-gen.exe\__main__.py", line 5, in <module>
  File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 357, in main
    return cmd_voices_add(args)
           ^^^^^^^^^^^^^^^^^^^^
  File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 248, in cmd_voices_add
    _clone_voice_file(info["file_id"], args.name)
  File "D:\AI\ClaudeCode\voice-ge\src\voice_gen\cli.py", line 197, in _clone_voice_file
    raise MmxError(
voice_gen.errors.MmxError: mmx command failed (exit=1): voice_clone failed: status_code=2039 msg=voice clone voice id duplicate raw={'input_sensitive': False, 'input_sensitive_type': 0, 'demo_audio': '', 'base_resp': {'status_code': 2039, 'status_msg': 'voice clone voice id duplicate'}} [cmd: curl ... https://api.minimaxi.com/v1/voice_clone]

16

好的测试成功了,拿到了音频。 提交并push到远程标记一下这个是可以跑通的版本。

现在应该有一套完整的Voice id的管理及与服务器同步的命令。我考虑的有以下不一定准确你自己判断。 制订个管理和同步的规划:

  1. 项目init时应该去pull一下
  2. 应该在create mp3 前去pull 一下。若服务器没有MP3也做不成功。
  3. 功能上应该有pull命令
  4. 可以由用户指定删除某个voice id同步服务器删除。
  5. 与服务器操作前应该都需要pull包括add

17

基于服务器不能删的话,那么我们做个简化

  • 加 pull 命令
  • 在 add 前做pull判断是否能加

工作范围,我调整如下:

##范围| 命令 |状态 | |---|---| | voices add |改:加服务端去重预检 | | voices list | 不变 | | voices cleanup | 不变 | | voices pull | 新增| | voices status | 新增 | | gen | 不变 | | init | 不变(保持离线)| | README + SKILL.md |同步 |

voices status是做什么的查服务器端的Voices list 如果是的话,可否考虑:

  • voices list local
  • voices list server

为了避免类似的情况我前面的voiceid其实已经打了时间戳。那么pull下来就好了。不做voices remove

你觉得呢?

18

我们现在的remove是假的由于server 不支持,我建议删掉这个命令:voice-gen voices remove <name>,不然会造成混淆。 即,服务器上不支持删,客户端上也不支持。

pull 从 filename派生所以我后续会保持文件名与voice id一致。那么我们需要改add

  1. 形如voice-gen voices add "C:\Users\wangq\Documents\录音\BroTsong-Saying-2026-06-10.m4a"这样没有命名的问题就用文件名也不需要重新命名。你add的时候friendly name就从文件名取。
  2. 增加pull

前面上传的文件没有日期,后面的文件都会有日期,所以也没问题。

你觉得呢?

后续我的测试: 这个改完后,

  1. 我重新找个文件夹,初始化init然后pull下来会有一个从服务器上拉下来的voice我尝试生成
  2. 我上传一个新的语音文件,尝试生成

19

你后续测试的预期行为测试1新目录 + pull

powershellmkdir D:\Mine\pull-test; 
cd D:\Mine\pull-test
voice-gen init # voices.json 是空的local 也空)
voice-gen pull # 自动从服务器拉下所有 voice_clone 文件,按 filename派生 voice_id

#当前服务端有BroTsong-Saying.m4afile_id407449867293232
# → 本地会有一个 entry{"BroTsong-Saying": {file_id:..., filename:"BroTsong-Saying.m4a", ...}}
voice-gen listvoice-gen gen --voice BroTsong-Saying scripts

测试2新文件 add + 生成)

powershell#准备一个带日期的文件,比如 BroTsong-Saying-2026-06-10.m4avoice-gen 

voices add "C:\path\to\BroTsong-Saying-2026-06-10.m4a"

#内部filename → "BroTsong-Saying-2026-06-10" voice_id# 上传 + voice_clone +存 registryvoice-gen
list#应该有BroTsong-Saying-2026-06-10 file_id=... filename=...
voice-gen gen --voice BroTsong-Saying-2026-06-10 scripts

20

之前,我们传的BroTsong-Saying.m4avoice-id为BroTsong-2026-06-10现在pull下来后默认按文件名走的话这个名字对应不上了。

(voice-gen) PS D:\Mine\口播2> voice-gen pull
usage: voice-gen [-h] {init,voices,gen} ...
voice-gen: error: argument command: invalid choice: 'pull' (choose from 'init', 'voices', 'gen')
(voice-gen) PS D:\Mine\口播2> voice-gen voices pull
  file_id=407449867293232  filename=BroTsong-Saying.m4a
  friendly name [BroTsong-Saying]:
  + 'BroTsong-Saying'  file_id=407449867293232  filename=BroTsong-Saying.m4a
pulled: 1 added
(voice-gen) PS D:\Mine\口播2> voice-gen gen --voice BroTsong-Saying scripts
✗ hello.md: mmx command failed (exit=1): {
  "error": {
    "code": 1,
    "message": "API error: voice id not exist (HTTP 200)"
  }
} [cmd: mmx speech synthesize --non-interactive --quiet --text Hello, this is a test. --voice BroTsong-Saying --format mp3 --out output\hello.mp3]
done: 0 ok, 1 failed
(voice-gen) PS D:\Mine\口播2> voice-gen list server
usage: voice-gen [-h] {init,voices,gen} ...
voice-gen: error: argument command: invalid choice: 'list' (choose from 'init', 'voices', 'gen')
(voice-gen) PS D:\Mine\口播2> voice-gen voices list server
BroTsong-Saying.m4a  file_id=407449867293232
(voice-gen) PS D:\Mine\口播2>

上面是我的测试我觉得服务器上应该有记录friendLy name。 你检查下api是否可以查到friendly name。 完了我们再判断,这里怎么优化。

21

行了不用改了。先提交并push到远程标记为完善了voice id命名从文件名取增加了pull。

我在PowerShell里做了测试。那么Cluade code/这里可以按技能调用么?

22

我看到这个目录,放在这里的话,是不是本机都能看见? C:\Users\wangq\.agents\skills

C:\Users\wangq\.claude\skillscluade的技能其实都引用的是C:\Users\wangq\.agents\skills这里的。

另外文件夹有点问题skill的默认文件夹叫voice-gen更合理些,包括技能名字也叫voice-gen 我在新机器上是否能够利用npx 这样的命令给一个我的git服务器链接就能安装技能

所以,如果我说的没问题的话,先回答问题,再处理:

  1. 更新相应的说明文件,配置文件
  2. 删掉 claude skills将skill放到.agents/skills/.claude/skills/里应该只是个引用