【azure openai】用tts实现语音对话【demo】

打印 上一主题 下一主题

主题 911|帖子 911|积分 2733

能实现:

只要替换内里的key,就能跑通。
key的查找方法:
【保姆级教程】如何在azure里快速找到openai的key和demo-CSDN博客
代码结构:
azure_openai_client.py
main.py
prompts_config.py
speech_utils.py
stt01.py
tts01.py

azure_openai_client.py
  1. import os
  2. import base64
  3. from openai import AzureOpenAI
  4. from typing import List, Dict, Optional, Union
  5. class AzureOpenAIClient:
  6.     def __init__(
  7.         self,
  8.         endpoint: str = "替换成你的终结点",
  9.         deployment: str = "模型名称",
  10.         api_key: Optional[str] = None,
  11.         system_prompt: str = None
  12.     ):
  13.         """
  14.         初始化 Azure OpenAI 客户端
  15.         
  16.         Args:
  17.             endpoint: Azure OpenAI 服务端点
  18.             deployment: 部署名称
  19.             api_key: API 密钥,如果为 None 则从环境变量获取
  20.             system_prompt: 系统提示词,如果为 None 则使用默认提示
  21.         """
  22.         self.endpoint = endpoint
  23.         self.deployment = deployment
  24.         self.api_key = api_key or os.getenv(
  25.             "AZURE_OPENAI_API_KEY",
  26.             "替换为你的key"
  27.         )
  28.         
  29.         self.client = AzureOpenAI(
  30.             azure_endpoint=self.endpoint,
  31.             api_key=self.api_key,
  32.             api_version="2024-05-01-preview"
  33.         )
  34.         
  35.         # 使用传入的系统提示词或默认提示词
  36.         default_prompt_text = "你是一个帮助用户查找信息的 AI 助手。"
  37.         if system_prompt:
  38.             default_prompt_text = system_prompt
  39.         
  40.         self.default_chat_prompt = [
  41.             {
  42.                 "role": "system",
  43.                 "content": [
  44.                     {
  45.                         "type": "text",
  46.                         "text": default_prompt_text
  47.                     }
  48.                 ]
  49.             }
  50.         ]
  51.     def encode_image(self, image_path: str) -> str:
  52.         """
  53.         将图片编码为 base64 字符串
  54.         
  55.         Args:
  56.             image_path: 图片路径
  57.             
  58.         Returns:
  59.             base64 编码的图片字符串
  60.         """
  61.         with open(image_path, 'rb') as image_file:
  62.             return base64.b64encode(image_file.read()).decode('ascii')
  63.     def chat_completion(
  64.         self,
  65.         messages: Optional[List[Dict]] = None,
  66.         max_tokens: int = 200,
  67.         temperature: float = 0.7,
  68.         top_p: float = 0.95,
  69.         frequency_penalty: float = 0,
  70.         presence_penalty: float = 0,
  71.         stop: Optional[Union[str, List[str]]] = None,
  72.         stream: bool = False
  73.     ):
  74.         """
  75.         生成聊天完成
  76.         
  77.         Args:
  78.             messages: 聊天消息列表,如果为 None 则使用默认提示
  79.             max_tokens: 生成的最大标记数
  80.             temperature: 采样温度
  81.             top_p: 核采样概率
  82.             frequency_penalty: 频率惩罚
  83.             presence_penalty: 存在惩罚
  84.             stop: 停止序列
  85.             stream: 是否使用流式响应
  86.             
  87.         Returns:
  88.             聊天完成响应
  89.         """
  90.         if messages is None:
  91.             messages = self.default_chat_prompt
  92.         completion = self.client.chat.completions.create(
  93.             model=self.deployment,
  94.             messages=messages,
  95.             max_tokens=max_tokens,
  96.             temperature=temperature,
  97.             top_p=top_p,
  98.             frequency_penalty=frequency_penalty,
  99.             presence_penalty=presence_penalty,
  100.             stop=stop,
  101.             stream=stream
  102.         )
  103.         
  104.         return completion
复制代码
main.py
  1. from speech_utils import SpeechService, text_to_speech, speech_to_text
  2. import time
  3. import os
  4. from azure_openai_client import AzureOpenAIClient
  5. from prompts_config import get_system_prompt
  6. def main():
  7.     # 创建 SpeechService 实例
  8.     speech_service = SpeechService(
  9.         speech_key="替换为你的key",
  10.         service_region="资源部署地"
  11.     )
  12.    
  13.     while True:
  14.         print("\n=== 功能菜单 ===")
  15.         print("1. 语音转文字")
  16.         print("2. 文字转语音")
  17.         print("3. AI 语音对话")
  18.         print("0. 退出")
  19.         
  20.         choice = input("请选择功能 (0-3): ")
  21.         
  22.         if choice == "0":
  23.             print("感谢使用,再见!")
  24.             break
  25.         elif choice == "1":
  26.             print("\n=== 语音转文字 ===")
  27.             print("支持的语言:中文、英语、日语")
  28.             print("请说话...")
  29.             
  30.             # 记录开始时间
  31.             start_time = time.time()
  32.             
  33.             success, result = speech_service.speech_to_text(
  34.                 languages=["zh-CN", "en-US", "ja-JP"]
  35.             )
  36.             
  37.             # 计算并显示耗时
  38.             elapsed_time = time.time() - start_time
  39.             print(f"\n语音识别耗时: {elapsed_time:.2f}秒")
  40.             
  41.             if success:
  42.                 print(f"识别结果: {result['text']}")
  43.                 if result['detected_language']:
  44.                     print(f"检测到的语言: {result['detected_language']}")
  45.                
  46.                 if input("\n是否要将识别的文字转换为语音?(y/n): ").lower() == 'y':
  47.                     # 记录文字转语音开始时间
  48.                     tts_start_time = time.time()
  49.                     
  50.                     success, message = speech_service.text_to_speech(result['text'])
  51.                     
  52.                     # 计算并显示文字转语音耗时
  53.                     tts_elapsed_time = time.time() - tts_start_time
  54.                     print(f"文字转语音耗时: {tts_elapsed_time:.2f}秒")
  55.                     print(message)
  56.             else:
  57.                 print(f"错误: {result}")
  58.                
  59.         elif choice == "2":
  60.             print("\n=== 文字转语音 ===")
  61.             print("可选择的语音:")
  62.             print("1. 中文女声 (zh-CN-XiaoxiaoNeural)")
  63.             print("2. 中文男声 (zh-CN-YunxiNeural)")
  64.             print("3. 英文女声 (en-US-AriaNeural)")
  65.             
  66.             voice_choice = input("请选择语音 (1-3,默认1): ").strip()
  67.             voice_map = {
  68.                 "1": "zh-CN-XiaoxiaoNeural",
  69.                 "2": "zh-CN-YunxiNeural",
  70.                 "3": "en-US-AriaNeural"
  71.             }
  72.             voice_name = voice_map.get(voice_choice, "zh-CN-XiaoxiaoNeural")
  73.             
  74.             text = input("\n请输入要转换为语音的文字: ")
  75.             
  76.             # 记录开始时间
  77.             start_time = time.time()
  78.             
  79.             success, message = speech_service.text_to_speech(text, voice_name=voice_name)
  80.             
  81.             # 计算并显示耗时
  82.             elapsed_time = time.time() - start_time
  83.             print(f"文字转语音耗时: {elapsed_time:.2f}秒")
  84.             print(message)
  85.             
  86.         elif choice == "3":
  87.             voice_chat()
  88.         else:
  89.             print("\n无效的选择,请重试。")
  90.         
  91.         time.sleep(1)
  92. def voice_chat():
  93.     # 初始化服务
  94.     ai_client = AzureOpenAIClient()
  95.     speech_service = SpeechService(
  96.         speech_key=".....",
  97.         service_region="资源位置。例:eastus"
  98.     )
  99.    
  100.     # 选择语言
  101.     print("\n请选择对话语言:")
  102.     print("1. 中文")
  103.     print("2. English")
  104.     lang_choice = input("请选择 (1/2): ")
  105.    
  106.     language = "zh-CN" if lang_choice == "1" else "en-US"
  107.    
  108.     # 获取为该语言配置的系统提示词
  109.     system_prompt = get_system_prompt(language)
  110.    
  111.     # 创建AI客户端并设置系统提示
  112.     ai_client = AzureOpenAIClient(system_prompt=system_prompt)
  113.    
  114.     # 更新系统提示
  115.     messages = [
  116.         {
  117.             "role": "system",
  118.             "content": [{"type": "text", "text": system_prompt}]
  119.         }
  120.     ]
  121.    
  122.     print("\n=== AI 语音对话开始 ===")
  123.     print("输入 's' 开始对话,输入 'q' 结束对话")
  124.    
  125.     while True:
  126.         command = input("\n请输入命令 (s: 开始对话, q: 退出): ")
  127.         if command.lower() == 'q':
  128.             break
  129.         elif command.lower() == 's':
  130.             print("\n开始对话模式...")
  131.             print("系统会在AI回复完成后才开始检测您的语音")
  132.             print("说 '再见' 或 'goodbye' 结束对话")
  133.             
  134.             continue_dialog = True
  135.             while continue_dialog:
  136.                 # 提示用户说话
  137.                 print("\n请开始说话...")
  138.                
  139.                 # 每次只进行一次语音识别
  140.                 success, result = speech_service.speech_to_text(languages=[language])
  141.                
  142.                 if success and result['text']:
  143.                     user_text = result['text']
  144.                     print(f"\n您说: {user_text}")
  145.                     
  146.                     # 检查是否要结束对话
  147.                     if (language == "zh-CN" and "再见" in user_text.lower()) or \
  148.                        (language == "en-US" and "goodbye" in user_text.lower()):
  149.                         print("对话结束")
  150.                         continue_dialog = False
  151.                         break
  152.                     
  153.                     # 添加用户消息
  154.                     messages.append({
  155.                         "role": "user",
  156.                         "content": [{"type": "text", "text": user_text}]
  157.                     })
  158.                     
  159.                     # 获取 AI 响应
  160.                     print("AI思考中...")
  161.                     response = ai_client.chat_completion(messages=messages)
  162.                     ai_text = response.choices[0].message.content
  163.                     print(f"AI 响应: {ai_text}")
  164.                     
  165.                     # 添加 AI 响应到消息历史
  166.                     messages.append({
  167.                         "role": "assistant",
  168.                         "content": [{"type": "text", "text": ai_text}]
  169.                     })
  170.                     
  171.                     # 文字转语音 - 等待语音合成完成
  172.                     print("正在生成语音...")
  173.                     voice_name = "zh-CN-XiaoxiaoNeural" if language == "zh-CN" else "en-US-AriaNeural"
  174.                     success, message = speech_service.text_to_speech(ai_text, voice_name=voice_name)
  175.                     if not success:
  176.                         print(f"语音合成失败: {message}")
  177.                     
  178.                     print("AI语音播放完成,准备下一轮对话")
  179.                 else:
  180.                     print("未能识别您的语音,请重试")
  181.         else:
  182.             print("无效的命令,请重试")
  183. if __name__ == "__main__":
  184.     main()
复制代码
prompts_config.py
  1. # 系统提示词配置
  2. # 主要系统提示词 - 使用一种语言编写(中文)
  3. MAIN_SYSTEM_PROMPT = """
  4. 你是一个智能AI助手,专注于提供有用、准确的信息。请遵循以下准则:
  5. 1. 保持回答简洁明了,避免冗长解释
  6. 2. 使用礼貌友好的语气
  7. 3. 如果不确定答案,坦诚表示不知道
  8. 4. 避免有害或不适当的内容
  9. 5. 提供准确、最新的信息
  10. 6. 尊重用户隐私,不要要求个人信息
  11. 7. 只能输出自然语言,禁止输出md格式的内容。
  12. """
  13. # 语言特定的补充提示
  14. LANGUAGE_PROMPTS = {
  15.     "zh-CN": "请用中文简短回答。",
  16.     "en-US": "Please respond in English concisely.",
  17.     "ja-JP": "簡潔に日本語で回答してください。",
  18.     # 可以添加更多语言
  19. }
  20. def get_system_prompt(language_code="zh-CN"):
  21.     """获取指定语言的完整系统提示词"""
  22.     language_prompt = LANGUAGE_PROMPTS.get(language_code, LANGUAGE_PROMPTS["zh-CN"])
  23.     return f"{MAIN_SYSTEM_PROMPT}\n{language_prompt}"
复制代码
speech_utils.py
  1. import azure.cognitiveservices.speech as speechsdk
  2. import time
  3. class SpeechService:
  4.     def __init__(self, speech_key, service_region):
  5.         self.speech_key = speech_key
  6.         self.service_region = service_region
  7.         self.speech_config = speechsdk.SpeechConfig(
  8.             subscription=speech_key,
  9.             region=service_region
  10.         )
  11.     def text_to_speech(self, text, voice_name="zh-CN-XiaoxiaoNeural"):
  12.         """
  13.         将文字转换为语音
  14.         :param text: 要转换的文字
  15.         :param voice_name: 语音名称,默认使用中文女声
  16.         :return: 转换结果和错误信息(如果有)
  17.         """
  18.         try:
  19.             self.speech_config.speech_synthesis_voice_name = voice_name
  20.             speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=self.speech_config)
  21.             
  22.             # 创建事件来跟踪语音合成完成
  23.             synthesis_completed = False
  24.             
  25.             def synthesis_completed_cb(evt):
  26.                 nonlocal synthesis_completed
  27.                 synthesis_completed = True
  28.             
  29.             # 注册事件
  30.             speech_synthesizer.synthesis_completed.connect(synthesis_completed_cb)
  31.             
  32.             result = speech_synthesizer.speak_text_async(text).get()
  33.             if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
  34.                 # 等待合成完成事件
  35.                 while not synthesis_completed:
  36.                     time.sleep(0.1)
  37.                 return True, "语音合成成功"
  38.             elif result.reason == speechsdk.ResultReason.Canceled:
  39.                 cancellation_details = result.cancellation_details
  40.                 return False, f"语音合成取消: {cancellation_details.reason}"
  41.         except Exception as e:
  42.             return False, f"发生错误: {str(e)}"
  43.     def speech_to_text(self, languages=None, continuous=False):
  44.         """
  45.         语音转文字
  46.         :param languages: 支持的语言列表,例如 ["zh-CN", "en-US", "ja-JP"]
  47.         :param continuous: 是否使用连续识别模式
  48.         :return: 识别结果和错误信息(如果有)
  49.         """
  50.         try:
  51.             if languages:
  52.                 # 多语言支持
  53.                 auto_detect_source_language_config = speechsdk.languageconfig.AutoDetectSourceLanguageConfig(
  54.                     languages=languages
  55.                 )
  56.                 speech_recognizer = speechsdk.SpeechRecognizer(
  57.                     speech_config=self.speech_config,
  58.                     auto_detect_source_language_config=auto_detect_source_language_config
  59.                 )
  60.             else:
  61.                 # 默认使用中文
  62.                 self.speech_config.speech_recognition_language = "zh-CN"
  63.                 speech_recognizer = speechsdk.SpeechRecognizer(speech_config=self.speech_config)
  64.             if continuous:
  65.                 # 使用连续识别模式
  66.                 done = False
  67.                 def handle_result(evt):
  68.                     if evt.result.reason == speechsdk.ResultReason.RecognizedSpeech:
  69.                         return True, {
  70.                             "text": evt.result.text,
  71.                             "detected_language": evt.result.properties.get(
  72.                                 speechsdk.PropertyId.SpeechServiceConnection_AutoDetectSourceLanguageResult
  73.                             )
  74.                         }
  75.                     return False, "无识别结果"
  76.                 def stop_cb(evt):
  77.                     nonlocal done
  78.                     done = True
  79.                 # 绑定事件
  80.                 speech_recognizer.recognized.connect(handle_result)
  81.                 speech_recognizer.session_stopped.connect(stop_cb)
  82.                 speech_recognizer.canceled.connect(stop_cb)
  83.                 # 开始连续识别
  84.                 speech_recognizer.start_continuous_recognition()
  85.                 while not done:
  86.                     time.sleep(0.5)
  87.                 speech_recognizer.stop_continuous_recognition()
  88.                
  89.                 return True, {"text": "", "detected_language": None}
  90.             else:
  91.                 # 单次识别模式
  92.                 result = speech_recognizer.recognize_once()
  93.                 if result.reason == speechsdk.ResultReason.RecognizedSpeech:
  94.                     detected_language = None
  95.                     if hasattr(result, 'properties') and result.properties.get(
  96.                         speechsdk.PropertyId.SpeechServiceConnection_AutoDetectSourceLanguageResult
  97.                     ):
  98.                         detected_language = result.properties[
  99.                             speechsdk.PropertyId.SpeechServiceConnection_AutoDetectSourceLanguageResult
  100.                         ]
  101.                     return True, {
  102.                         "text": result.text,
  103.                         "detected_language": detected_language
  104.                     }
  105.                 elif result.reason == speechsdk.ResultReason.NoMatch:
  106.                     return False, f"无法识别语音: {result.no_match_details}"
  107.                 elif result.reason == speechsdk.ResultReason.Canceled:
  108.                     return False, f"语音识别取消: {result.cancellation_details.reason}"
  109.         except Exception as e:
  110.             return False, f"发生错误: {str(e)}"
  111.     def start_continuous_recognition(self, languages=None, callback=None):
  112.         """
  113.         启动连续语音识别
  114.         :param languages: 支持的语言列表,例如 ["zh-CN", "en-US", "ja-JP"]
  115.         :param callback: 回调函数,用于处理识别结果
  116.         :return: speech_recognizer 对象,用于后续控制
  117.         """
  118.         try:
  119.             if languages:
  120.                 # 多语言支持
  121.                 auto_detect_source_language_config = speechsdk.languageconfig.AutoDetectSourceLanguageConfig(
  122.                     languages=languages
  123.                 )
  124.                 speech_recognizer = speechsdk.SpeechRecognizer(
  125.                     speech_config=self.speech_config,
  126.                     auto_detect_source_language_config=auto_detect_source_language_config
  127.                 )
  128.             else:
  129.                 # 默认使用中文
  130.                 self.speech_config.speech_recognition_language = "zh-CN"
  131.                 speech_recognizer = speechsdk.SpeechRecognizer(speech_config=self.speech_config)
  132.             # 处理识别结果的事件
  133.             def handle_result(evt):
  134.                 if evt.result.reason == speechsdk.ResultReason.RecognizedSpeech:
  135.                     text = evt.result.text
  136.                     detected_language = evt.result.properties.get(
  137.                         speechsdk.PropertyId.SpeechServiceConnection_AutoDetectSourceLanguageResult
  138.                     )
  139.                     
  140.                     if callback:
  141.                         should_continue = callback(text, detected_language)
  142.                         if should_continue is False:
  143.                             # 如果回调返回 False,停止识别
  144.                             speech_recognizer.stop_continuous_recognition_async()
  145.             # 处理错误的事件
  146.             def handle_canceled(evt):
  147.                 if evt.reason == speechsdk.CancellationReason.Error:
  148.                     print(f"语音识别错误: {evt.error_details}")
  149.             # 绑定事件处理器
  150.             speech_recognizer.recognized.connect(handle_result)
  151.             speech_recognizer.canceled.connect(handle_canceled)
  152.             # 开始连续识别
  153.             speech_recognizer.start_continuous_recognition_async()
  154.             
  155.             return speech_recognizer
  156.             
  157.         except Exception as e:
  158.             print(f"启动连续识别时发生错误: {str(e)}")
  159.             raise
  160. def text_to_speech(text: str, language: str = "zh-CN") -> None:
  161.     """
  162.     将文本转换为语音
  163.    
  164.     Args:
  165.         text: 要转换的文本
  166.         language: 语言代码,默认为中文
  167.     """
  168.     # 使用类中已定义的密钥
  169.     speech_key = "语音识别的key"
  170.     service_region = "资源位置,例:eastus"
  171.    
  172.     # 创建语音配置
  173.     speech_config = speechsdk.SpeechConfig(
  174.         subscription=speech_key,
  175.         region=service_region
  176.     )
  177.    
  178.     # 根据语言选择合适的语音
  179.     if language == "zh-CN":
  180.         speech_config.speech_synthesis_voice_name = "zh-CN-XiaoxiaoNeural"
  181.     else:
  182.         speech_config.speech_synthesis_voice_name = "en-US-AriaNeural"
  183.    
  184.     # 创建语音合成器
  185.     speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config)
  186.    
  187.     # 执行语音合成
  188.     result = speech_synthesizer.speak_text_async(text).get()
  189.    
  190.     if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
  191.         print("语音合成完成")
  192.     elif result.reason == speechsdk.ResultReason.Canceled:
  193.         cancellation_details = result.cancellation_details
  194.         print(f"语音合成取消: {cancellation_details.reason}")
  195.         if cancellation_details.reason == speechsdk.CancellationReason.Error:
  196.             print(f"错误详情: {cancellation_details.error_details}")
  197. def speech_to_text(language: str = "zh-CN") -> str:
  198.     """
  199.     将语音转换为文本
  200.    
  201.     Args:
  202.         language: 语言代码,默认为中文
  203.    
  204.     Returns:
  205.         识别出的文本,如果失败则返回空字符串
  206.     """
  207.     speech_key = "语音识别的key"
  208.     service_region = "资源位置"
  209.    
  210.     # 创建语音配置
  211.     speech_config = speechsdk.SpeechConfig(
  212.         subscription=speech_key,
  213.         region=service_region
  214.     )
  215.    
  216.     # 设置语音识别语言
  217.     speech_config.speech_recognition_language = language
  218.    
  219.     # 创建音频配置
  220.     audio_config = speechsdk.audio.AudioConfig(use_default_microphone=True)
  221.    
  222.     # 创建语音识别器
  223.     speech_recognizer = speechsdk.SpeechRecognizer(
  224.         speech_config=speech_config,
  225.         audio_config=audio_config
  226.     )
  227.    
  228.     print("开始说话...")
  229.    
  230.     # 执行语音识别
  231.     result = speech_recognizer.recognize_once_async().get()
  232.    
  233.     if result.reason == speechsdk.ResultReason.RecognizedSpeech:
  234.         return result.text
  235.     elif result.reason == speechsdk.ResultReason.NoMatch:
  236.         print(f"无法识别语音: {result.no_match_details}")
  237.     elif result.reason == speechsdk.ResultReason.Canceled:
  238.         cancellation_details = result.cancellation_details
  239.         print(f"语音识别取消: {cancellation_details.reason}")
  240.         if cancellation_details.reason == speechsdk.CancellationReason.Error:
  241.             print(f"错误详情: {cancellation_details.error_details}")
  242.    
  243.     return ""
复制代码
stt01.py
  1. # Copyright (c) Microsoft. All rights reserved.
  2. # Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
  3. from speech_utils import SpeechService
  4. def main():
  5.     # 创建 SpeechService 实例
  6.     speech_service = SpeechService(
  7.         speech_key="语音识别的key",
  8.         service_region="eastus"
  9.     )
  10.    
  11.     print("请说话...")
  12.     success, result = speech_service.speech_to_text(languages=["zh-CN", "en-US", "ja-JP"])
  13.    
  14.     if success:
  15.         print(f"识别结果: {result['text']}")
  16.         if result['detected_language']:
  17.             print(f"检测到的语言: {result['detected_language']}")
  18.     else:
  19.         print(f"错误: {result}")
  20. if __name__ == "__main__":
  21.     main()
复制代码
tts01.py
  1. # Copyright (c) Microsoft. All rights reserved.
  2. # Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
  3. from speech_utils import SpeechService
  4. def main():
  5.     # 创建 SpeechService 实例
  6.     speech_service = SpeechService(
  7.         speech_key="语音识别的key",
  8.         service_region="eastus"
  9.     )
  10.    
  11.     print("请输入要转换为语音的文字...")
  12.     text = input()
  13.    
  14.     success, message = speech_service.text_to_speech(text)
  15.     print(message)
  16. if __name__ == "__main__":
  17.     main()
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表