You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure文本转语音应用接入SSML后无输出问题求助

问题诊断与修复方案

核心问题:SSML字符串的转义错误

你当前构造SSML时使用了&lt;和&gt;这类HTML转义字符,但Azure Speech Service要求传入原生XML标签(即<和>),转义后的字符会被当成普通文本处理,导致SSML结构完全无效,合成服务无法解析,最终没有音频输出。

其他潜在问题与修复

  1. 输入文本的特殊字符处理
    如果用户输入的文本包含<、>、&等XML特殊字符,会直接破坏SSML的XML结构,必须先对这些字符进行转义。

  2. 完善错误诊断
    当前错误提示过于笼统,应该获取并显示Azure返回的具体错误信息,方便快速定位问题。

修改后的代码片段

重点修改speak_text方法里的SSML构造和错误处理部分:

def speak_text(self):
    text = self.input_text.get("1.0", "end").strip()  # 去除首尾空白,避免多余换行
    output_dir = self.output_dir_path.get()
    output_filename = self.output_filename_text.get()
    if output_filename == "":
        output_filename = "tcnoutput"
    output_file = os.path.join(output_dir, output_filename + ".wav")

    if os.path.exists(output_file):
        response = messagebox.askyesnocancel("File Exists", "A file with the same name already exists. Do you want to overwrite it?",
                                        icon='warning')
        if response == True:
            os.remove(output_file)
        elif response == False:
            i = 1
            while os.path.exists(os.path.join(output_dir, output_filename + f"({i})" + ".wav")):
                i += 1
            output_filename = output_filename + f"({i})"
            output_file = os.path.join(output_dir, output_filename + ".wav")
        else:
            raise KeyboardInterrupt
        
    # 转义文本中的XML特殊字符,避免破坏SSML结构
    def escape_xml(text):
        return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;").replace("'", "&apos;")
    
    pitch = "+50.0%"
    # 使用原生XML标签构造SSML,不要用HTML转义字符
    ssml_string = f'<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="ro-RO">' \
                  f'<prosody pitch="{pitch}">{escape_xml(text)}</prosody></speak>'
    
    try:
        speech_synthesis_result = self.speech_synthesizer.speak_ssml_async(ssml_string).get()
        if speech_synthesis_result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
            with open(output_file, "wb") as f:
                f.write(speech_synthesis_result.audio_data)
            # 用os.path.join统一路径格式,避免跨平台问题
            output_final = os.path.join(output_dir if output_dir else os.getcwd(), f"{output_filename}.wav")
            messagebox.showinfo("Success", f"Audio file successfully saved at: {output_final}")
        else:
            # 显示Azure返回的具体错误详情
            error_details = speech_synthesis_result.error_details
            messagebox.showerror("Error", f"Speech synthesis failed:\n{error_details}")
    except Exception as e:
        messagebox.showerror("Exception", f"An error occurred:\n{str(e)}")

关键修改说明

  • 将SSML中的&lt;/&gt;替换为原生</>,确保Azure能正确识别SSML结构。
  • 添加escape_xml函数,处理输入文本中的XML特殊字符,防止SSML格式被破坏。
  • 完善错误处理逻辑:捕获异常并显示具体错误信息,同时用os.path.join统一路径拼接,避免Windows/Linux路径格式冲突。
  • 去除输入文本的首尾空白,避免合成音频出现多余停顿。

内容的提问来源于stack exchange,提问作者Mario Anghel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:57:01