main.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. from flask import Flask, request, send_file, jsonify
  2. from flask_cors import CORS
  3. import dashscope
  4. from dashscope.audio.tts_v2 import SpeechSynthesizer
  5. import hashlib
  6. import os
  7. app = Flask(__name__)
  8. CORS(app) # 允许所有域名跨域访问
  9. # 配置
  10. CACHE_FOLDER = 'audio_cache'
  11. MODEL = "cosyvoice-v1"
  12. VOICE = "longxiaochun"
  13. # 确保缓存文件夹存在
  14. os.makedirs(CACHE_FOLDER, exist_ok=True)
  15. def get_md5(text):
  16. """生成文本的MD5哈希值"""
  17. return hashlib.md5(text.encode('utf-8')).hexdigest()
  18. def generate_audio(text, output_path):
  19. """使用DashScope生成语音文件"""
  20. synthesizer = SpeechSynthesizer(model=MODEL, voice=VOICE)
  21. audio = synthesizer.call(text)
  22. with open(output_path, 'wb') as f:
  23. f.write(audio)
  24. return synthesizer.get_last_request_id()
  25. @app.route('/tts', methods=['POST', 'OPTIONS'])
  26. def text_to_speech():
  27. if request.method == 'OPTIONS':
  28. return jsonify({}), 200
  29. # 获取请求数据
  30. data = request.get_json()
  31. if not data or 'text' not in data:
  32. return jsonify({'error': 'Missing text parameter'}), 400
  33. text = data['text']
  34. # 生成文件名
  35. filename = get_md5(text) + '.mp3'
  36. filepath = os.path.join(CACHE_FOLDER, filename)
  37. # 检查缓存
  38. if not os.path.exists(filepath):
  39. try:
  40. request_id = generate_audio(text, filepath)
  41. print(f'Generated new audio file with requestId: {request_id}')
  42. except Exception as e:
  43. return jsonify({'error': f'Failed to generate audio: {str(e)}'}), 500
  44. # 返回音频文件
  45. try:
  46. return send_file(
  47. filepath,
  48. mimetype='audio/mpeg',
  49. as_attachment=True,
  50. download_name=f'tts_{filename}'
  51. )
  52. except Exception as e:
  53. return jsonify({'error': f'Failed to send audio file: {str(e)}'}), 500
  54. if __name__ == '__main__':
  55. app.run(host='0.0.0.0', port=15001, debug=True)