You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Unity调用Bing语音API时UnityWebRequest返回HTTP 408状态码问题

解决Unity调用Bing文本转语音API出现408超时的问题

我之前也碰到过类似的Unity调用Azure Bing TTS API超时的状况,结合你描述的「Postman正常但Unity用UnityWebRequest连发起两个POST请求就报408」的情况,大概率是请求流程或配置的细节没处理到位,下面给你梳理几个排查方向和解决办法:

1. 调整UnityWebRequest的超时时间

UnityWebRequest默认的超时阈值比较短,而调用TTS API需要服务器生成并返回音频数据,耗时可能比普通请求长。你可以手动给请求设置更长的超时时间:

// 给TTS请求设置15秒超时,可根据实际情况调整
UnityWebRequest ttsRequest = UnityWebRequest.Post(ttsApiUrl, postData);
ttsRequest.timeout = 15;

2. 严格保证请求的顺序与完整性

很多时候408是因为第二个TTS请求发起过早——比如第一个获取Token的请求还没完全拿到响应,就急着用空的/无效的Token发起请求,导致服务器无法识别请求,最终超时。

用协程处理的话,一定要确保第一个请求完成后再执行第二步,示例代码如下:

IEnumerator CallBingTTS(string ssmlContent)
{
    // 第一步:获取Access Token
    UnityWebRequest tokenReq = UnityWebRequest.Post(tokenApiUrl, tokenFormData);
    // 配置Token请求的必要头信息(比如Content-Type等)
    tokenReq.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    
    yield return tokenReq.SendWebRequest();

    if (tokenReq.result != UnityWebRequest.Result.Success)
    {
        Debug.LogError("Token获取失败:" + tokenReq.error);
        yield break;
    }

    // 解析返回的Token(根据API返回的JSON格式处理)
    string accessToken = ParseAccessToken(tokenReq.downloadHandler.text);
    if (string.IsNullOrEmpty(accessToken))
    {
        Debug.LogError("解析Token失败");
        yield break;
    }

    // 第二步:调用TTS API
    UnityWebRequest ttsReq = UnityWebRequest.Post(ttsApiUrl, ssmlContent);
    // 配置TTS请求的所有必要头信息
    ttsReq.SetRequestHeader("Authorization", "Bearer " + accessToken);
    ttsReq.SetRequestHeader("Content-Type", "application/ssml+xml");
    ttsReq.SetRequestHeader("X-Microsoft-OutputFormat", "riff-24khz-16bit-mono-pcm");
    ttsReq.timeout = 15;

    yield return ttsReq.SendWebRequest();

    if (ttsReq.result != UnityWebRequest.Result.Success)
    {
        Debug.LogError("TTS请求失败:" + ttsReq.error + ",状态码:" + ttsReq.responseCode);
    }
    else
    {
        // 处理返回的Wav音频字节数据
        byte[] audioBytes = ttsReq.downloadHandler.data;
        // 可将字节数组转为AudioClip播放,或保存为文件
    }
}

// 辅助方法:解析Token响应
private string ParseAccessToken(string responseText)
{
    // 示例:假设返回的是{"access_token":"xxx","expires_in":xxx}
    var json = JsonUtility.FromJson<TokenResponse>(responseText);
    return json.access_token;
}

// 对应Token返回的JSON结构的类
[System.Serializable]
private class TokenResponse
{
    public string access_token;
    public int expires_in;
}

3. 核对请求头的准确性

Postman能正常运行,说明请求头是正确的,但Unity里很容易出现漏加头或格式错误的情况:

  • 确认Authorization头的格式是Bearer {accessToken},注意Bearer后面有一个空格
  • 检查Content-Type是否和Postman一致(比如用SSML的话是application/ssml+xml
  • 确认X-Microsoft-OutputFormat的取值完全匹配(比如riff-24khz-16bit-mono-pcm

4. 检查Unity的网络配置

有时候Unity的PlayerSettings会影响网络请求的正常发送:

  • 进入「PlayerSettings -> Other Settings -> Configuration」,把Internet Access设置为Require
  • 如果API用的是HTTP协议(不推荐,但如果是测试环境),需要开启「Allow Downloads over HTTP」

5. 抓包对比请求差异

如果上面的方法都没用,建议用Fiddler之类的工具抓包,对比Postman和Unity发送的请求:

  • 检查请求头是否完全一致
  • 核对请求体的内容(比如SSML是否有转义错误、格式是否正确)
  • 查看服务器返回的响应细节,能快速定位是请求哪里出了问题

内容的提问来源于stack exchange,提问作者Montacer Dkhilali

火山引擎 最新活动