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

Azure App Service部署认知服务TTS API时SpeechSynthesizer初始化失败

解决Azure App Service上文本转语音API的SPXERR_AUDIO_SYS_LIBRARY_NOT_FOUND错误

问题场景

本地运行文本转语音API一切正常,但发布到Azure App Service后,调用端点时初始化SpeechSynthesizer出现错误代码0x38(SPXERR_AUDIO_SYS_LIBRARY_NOT_FOUND),触发点在调用GetVoice方法设置SpeechSynthesisVoiceName的过程中。

问题原因

Azure App Service的Windows宿主环境没有预装音频驱动及相关系统库,当创建SpeechSynthesizer时如果不指定空音频配置,SDK会尝试加载音频输出组件,导致找不到依赖库抛出错误。此外代码中还存在异步调用使用.Result可能引发死锁、存储路径权限不足的潜在问题。

解决方案

1. 修改GetVoice方法,使用空音频配置

获取语音列表不需要实际输出音频,因此创建SpeechSynthesizer时传入AudioConfig.FromNull(),跳过音频设备初始化:

public static async Task<VoiceInfo> GetVoice(this SpeechConfig config, string localeid)
{
    // 传入空音频配置,避免加载音频系统依赖
    using (var synthesizer = new SpeechSynthesizer(config, AudioConfig.FromNull()))
    {
        using (var voices = await synthesizer.GetVoicesAsync())
        {
            var voice = voices.Voices.FirstOrDefault(voice => voice.Locale == localeid) ??
                        voices.Voices.First(voice => voice.Locale == defaultLocale);

            return voice;
        }
    }
}

2. 替换.Result为await,避免死锁

异步方法中使用.Result会阻塞线程,在ASP.NET环境易引发死锁,修改调用逻辑为:

try
{
    // 改用await调用异步方法
    _config.SpeechSynthesisVoiceName = (await _config.GetVoice(localeid)).ShortName;
}
catch (Exception ex)
{
    _logger.LogError($"Error getting voice for {localeid}: {ex.Message}, Stack: {ex.StackTrace}");
    throw;
}

3. 更换音频文件存储路径到临时目录

CommonApplicationData目录在App Service中可能没有写入权限,改用系统临时目录存储生成的音频文件,同时使用后删除临时文件避免空间占用:

// 使用临时目录存储音频文件
string audioPath = Path.Combine(Path.GetTempPath(), $"{text.GetHashCode()}-{localeid}.wav");
_logger.LogInformation($"AudioPath: {audioPath}");

// ... 生成音频逻辑 ...

if (!response.HasError)
{
    response.Wave = System.IO.File.ReadAllBytes(audioPath);
    // 删除临时文件
    System.IO.File.Delete(audioPath);
}

内容的提问来源于stack exchange,提问作者Hans-Henrik Møller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:05:27