#!/usr/bin/env python3
"""下载所有阿里云音色样本到 project/voices/ 目录"""
import json, os, re, requests, time, sys

OUTPUT_DIR = "voices"
os.makedirs(OUTPUT_DIR, exist_ok=True)

# 先获取全部音色URL（不只是前80个）
print("正在通过浏览器提取全部音色...")
import subprocess
result = subprocess.run([
    "npx", "playwright-cli", "run-code",
    r"""async (page) => {
  const data = await page.evaluate(() => {
    const result = [];
    document.querySelectorAll('audio').forEach(audio => {
      const src = audio.querySelector('source')?.src || audio.src;
      if (src) {
        const tr = audio.closest('tr');
        const text = tr?.textContent || '';
        const vm = text.match(/voice\s*参数\s*[：:]\s*([a-z]\w*)/i);
        const nm = text.match(/名称\s*[：:]\s*(\S+)/);
        result.push({url: src, voice: vm?vm[1]:'', name: nm?nm[1]:''});
      }
    });
    return result;
  });
  return JSON.stringify(data);
}"""], capture_output=True, text=True, timeout=60,
    cwd=r"c:/Users/caoyg/ai/audio-tts/audio_codebuddy")

output = result.stdout
# 提取真正的 JSON
json_match = re.search(r'"(\[.*\])"', output, re.DOTALL)
if not json_match:
    print("无法解析输出，前500字符:", output[:500])
    sys.exit(1)

json_str = json_match.group(1)
# 反转义
json_str = json_str.replace('\\"', '"').replace('\\\\', '\\')
voices = json.loads(json_str)
print(f"找到 {len(voices)} 个音色样本\n")

# 按模型分类计数器
stats = {}
downloaded = 0
failed = 0
skipped = 0

for i, v in enumerate(voices):
    url = v['url']
    voice = v['voice']
    name = v.get('name', '')
    
    if not url:
        skipped += 1
        continue
    
    # 清理文件名
    safe_name = f"{name}_{voice}" if name else voice
    safe_name = re.sub(r'[\\/:*?"<>|]', '_', safe_name)
    safe_name = voice  # 简单用voice参数名
    fname = f"{voice}.mp3"
    fpath = os.path.join(OUTPUT_DIR, fname)
    
    if os.path.exists(fpath):
        stats[voice] = stats.get(voice, 0) + 1
        skipped += 1
        continue
    
    # 进度
    pct = (i+1) * 100 // len(voices)
    bar = "█" * (pct // 5) + "░" * (20 - pct // 5)
    print(f"\r[{bar}] {pct}%  {i+1}/{len(voices)}  {voice:25s}", end='', flush=True)
    
    try:
        resp = requests.get(url, timeout=60, headers={
            'Referer': 'https://help.aliyun.com/',
            'User-Agent': 'Mozilla/5.0'
        })
        if resp.status_code == 200 and len(resp.content) > 100:
            with open(fpath, 'wb') as f:
                f.write(resp.content)
            downloaded += 1
        else:
            failed += 1
    except Exception as e:
        failed += 1
        pass
    
    time.sleep(0.2)

print(f"\n\n完成！下载 {downloaded} 个, 跳过 {skipped} 个, 失败 {failed} 个")
print(f"文件保存在: {OUTPUT_DIR}/")

# 生成索引
with open(os.path.join(OUTPUT_DIR, "INDEX.md"), "w", encoding="utf-8") as f:
    f.write("# 阿里云百炼 官方音色样本\n\n")
    f.write(f"共 {len(voices)} 个音色，来源：help.aliyun.com 官方帮助中心\n\n")
    f.write("| # | 音色名 | voice参数 | 文件名 |\n")
    f.write("|---|--------|----------|--------|\n")
    for i, v in enumerate(voices):
        f.write(f"| {i+1} | {v['name']} | `{v['voice']}` | [{v['voice']}.mp3]({v['voice']}.mp3) |\n")
