| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """analyze-model-lang-matrix.py — 解析 sysvoices-dom,生成 model × lang × voice 矩阵"""
- import re, json, sys
- from collections import defaultdict
- PATH = r"C:/Users/caoyg/AppData/Local/Temp/sysvoices-dom.txt"
- text = open(PATH, encoding='utf-8').read()
- # 阿里云页面有 4 个章节(每个章节都重复了"本页导读"导航,所以取第一个匹配即可)
- SECTIONS = [
- ('cosyvoice-v3-flash', r'cosyvoice-v3-flash\s*音色列表'),
- ('cosyvoice-v3-plus', r'cosyvoice-v3-plus\s*音色列表'),
- ('cosyvoice-v2', r'cosyvoice-v2\s*音色列表'),
- ('cosyvoice-v1', r'cosyvoice-v1\s*音色列表'),
- ]
- # 取每个模型标题第一个出现的位置(跳过右侧栏的目录)
- positions = []
- for model, pat in SECTIONS:
- matches = list(re.finditer(pat, text))
- # 选最小位置的(主体内容不是侧栏目录)
- if matches:
- m = min(matches, key=lambda x: x.start())
- positions.append((m.start(), model))
- positions.sort()
- all_voices = defaultdict(list)
- all_voices_per_model = {}
- for i, (start, model) in enumerate(positions):
- end = positions[i + 1][0] if i + 1 < len(positions) else len(text)
- section = text[start:end]
- voices = []
- pos = [mm.start() for mm in re.finditer(r'名称[::]\s*.+?\n', section)]
- pos.append(len(section))
- for j in range(len(pos) - 1):
- chunk = section[pos[j]:pos[j + 1]]
- v = {}
- n = re.search(r'^名称[::]\s*(.+?)\s*$', chunk, re.MULTILINE)
- if n: v['name'] = n.group(1).strip()
- vp = re.search(r'voice参数[::]\s*(\w+)', chunk)
- if vp: v['voice_id'] = vp.group(1)
- t = re.search(r'特质[::]\s*(.+?)\n', chunk)
- if t: v['desc'] = t.group(1).strip()[:80]
- a = re.search(r'年龄[::]\s*(.+?)\n', chunk)
- if a: v['age'] = a.group(1).strip()
- l = re.search(r'语言[::]\s*(.+?)\n', chunk)
- if l: v['lang'] = l.group(1).strip()[:60]
- v['instruct'] = '支持' if 'Instruct:支持' in chunk else '不支持' if 'Instruct:不支持' in chunk else '?'
- if v.get('name'):
- voices.append(v)
- all_voices_per_model[model] = voices
- # 输出汇总
- sys.stdout.reconfigure(encoding='utf-8')
- total_voices = 0
- all_langs = set()
- for model, voices in all_voices_per_model.items():
- print(f'\n=== {model}: {len(voices)} 个音色 ===')
- lang_count = defaultdict(int)
- for v in voices:
- lang = v.get('lang', '?')
- for l in re.split('[、,]', lang):
- l = l.strip()
- if not l: continue
- all_langs.add(l)
- lang_count[l] += 1
- for l, c in sorted(lang_count.items(), key=lambda x: (-x[1], x[0])):
- print(f' {l}: {c}')
- total_voices += len(voices)
- print(f'\n========== 总览 ==========')
- print(f'总音色数: {total_voices}')
- print(f'涉及语种 ({len(all_langs)} 种):')
- for l in sorted(all_langs): print(f' - {l}')
- # 写 JSON 给前端用
- with open(r"C:/Users/caoyg/AppData/Local/Temp/alicloud-voices-matrix.json", 'w', encoding='utf-8') as f:
- json.dump(all_voices_per_model, f, ensure_ascii=False, indent=2)
- print(f'\nJSON: {len(all_voices_per_model)} 个模型 → C:/Users/caoyg/AppData/Local/Temp/alicloud-voices-matrix.json')
|