cosyvoice_test.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. CosyVoice 非实时语音合成测试
  5. 使用阿里云百炼 API,测试长文本合成
  6. """
  7. import requests
  8. import json
  9. import time
  10. import os
  11. import sys
  12. API_KEY = "sk-c25679401ba24c749f53be86b0c9a7a6"
  13. API_URL = "https://dashscope.aliyuncs.com/api/v1/services/audio/tts/SpeechSynthesizer"
  14. OUTPUT_DIR = "test-results"
  15. os.makedirs(OUTPUT_DIR, exist_ok=True)
  16. # 《匆匆》朱自清,全文约 1700+ 字
  17. TEXT = """燕子去了,有再来的时候;杨柳枯了,有再青的时候;桃花谢了,有再开的时候。但是,聪明的,你告诉我,我们的日子为什么一去不复返呢?——是有人偷了他们罢:那是谁?又藏在何处呢?是他们自己逃走了罢:现在又到了哪里呢?
  18. 我不知道他们给了我多少日子;但我的手确乎是渐渐空虚了。在默默里算着,八千多日子已经从我手中溜去;像针尖上一滴水滴在大海里,我的日子滴在时间的流里,没有声音,也没有影子。我不禁头涔涔而泪潸潸了。
  19. 去的尽管去了,来的尽管来着;去来的中间,又怎样地匆匆呢?早上我起来的时候,小屋里射进两三方斜斜的太阳。太阳他有脚啊,轻轻悄悄地挪移了;我也茫茫然跟着旋转。于是——洗手的时候,日子从水盆里过去;吃饭的时候,日子从饭碗里过去;默默时,便从凝然的双眼前过去。我觉察他去的匆匆了,伸出手遮挽时,他又从遮挽着的手边过去,天黑时,我躺在床上,他便伶伶俐俐地从我身上跨过,从我脚边飞去了。等我睁开眼和太阳再见,这算又溜走了一日。我掩着面叹息。但是新来的日子的影儿又开始在叹息里闪过了。
  20. 在逃去如飞的日子里,在千门万户的世界里的我能做些什么呢?只有徘徊罢了,只有匆匆罢了;在八千多日的匆匆里,除徘徊外,又剩些什么呢?过去的日子如轻烟,被微风吹散了,如薄雾,被初阳蒸融了;我留着些什么痕迹呢?我何曾留着像游丝样的痕迹呢?我赤裸裸来到这世界,转眼间也将赤裸裸的回去罢?但不能平的,为什么偏要白白走这一遭啊?
  21. 你聪明的,告诉我,我们的日子为什么一去不复返呢?"""
  22. print("=" * 50)
  23. print(" CosyVoice 非实时语音合成测试")
  24. print("=" * 50)
  25. print(f"\n模型: cosyvoice-v3.5-flash")
  26. print(f"音色: longanyang")
  27. print(f"格式: mp3 / 采样率: 24000")
  28. print(f"文本长度: {len(TEXT)} 字符\n")
  29. payload = {
  30. "model": "cosyvoice-v3.5-flash",
  31. "input": {
  32. "text": TEXT,
  33. "voice": "longanyang",
  34. "format": "mp3",
  35. "sample_rate": 24000
  36. }
  37. }
  38. headers = {
  39. "Authorization": f"Bearer {API_KEY}",
  40. "Content-Type": "application/json"
  41. }
  42. print("正在调用 API ...")
  43. start_time = time.time()
  44. try:
  45. resp = requests.post(API_URL, headers=headers, json=payload, timeout=120)
  46. elapsed = time.time() - start_time
  47. print(f"HTTP 状态码: {resp.status_code}")
  48. print(f"耗时: {elapsed:.1f} 秒\n")
  49. if resp.status_code != 200:
  50. print("❌ 请求失败!响应内容:")
  51. print(json.dumps(resp.json(), ensure_ascii=False, indent=2))
  52. sys.exit(1)
  53. data = resp.json()
  54. request_id = data.get("request_id", "N/A")
  55. output = data.get("output", {})
  56. audio = output.get("audio", {})
  57. audio_url = audio.get("url", "")
  58. audio_id = audio.get("id", "N/A")
  59. finish_reason = output.get("finish_reason", "N/A")
  60. char_count = data.get("usage", {}).get("characters", 0)
  61. expires_at = audio.get("expires_at", 0)
  62. print("✅ 请求成功!")
  63. print(f"\n--- 响应摘要 ---")
  64. print(f"Request ID: {request_id}")
  65. print(f"Audio ID: {audio_id}")
  66. print(f"完成原因: {finish_reason}")
  67. print(f"计费字符数: {char_count}")
  68. if expires_at:
  69. exp_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(expires_at))
  70. print(f"链接过期: {exp_time}")
  71. print(f"Audio URL: {audio_url[:80]}...")
  72. # 下载音频
  73. ts = time.strftime("%Y%m%d_%H%M%S")
  74. audio_file = os.path.join(OUTPUT_DIR, f"cosyvoice-test-{ts}.mp3")
  75. print(f"\n正在下载音频到: {audio_file}")
  76. audio_resp = requests.get(audio_url, timeout=60)
  77. if audio_resp.status_code == 200:
  78. with open(audio_file, "wb") as f:
  79. f.write(audio_resp.content)
  80. file_size = os.path.getsize(audio_file)
  81. print(f"✅ 音频下载成功!")
  82. print(f" 文件: {audio_file}")
  83. print(f" 大小: {file_size:,} 字节 ({file_size/1024:.1f} KB)\n")
  84. print("完整 JSON 响应:")
  85. print(json.dumps(data, ensure_ascii=False, indent=2))
  86. else:
  87. print(f"❌ 音频下载失败,HTTP: {audio_resp.status_code}")
  88. sys.exit(1)
  89. except requests.exceptions.RequestException as e:
  90. print(f"❌ 网络请求异常: {e}")
  91. sys.exit(1)
  92. except Exception as e:
  93. print(f"❌ 未知错误: {e}")
  94. sys.exit(1)