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

谷歌TTS调用synthesizeSpeech无响应及gRPC超时问题求助

Google TextToSpeechClient 调用停滞及gRPC超时问题解决方案

问题描述

使用Google TextToSpeechClient进行文本转语音合成时,程序执行到SynthesizeSpeechResponse response = textToSpeechClient.synthesizeSpeech(input, voice, audioConfig);行时无响应停滞,此前还出现过gRPC deadline异常,现有解决方案多与当前版本不兼容。相关代码如下:

try (TextToSpeechClient textToSpeechClient = TextToSpeechClient.create(settings))
{
    System.out.println("In Try - Create TTS client");
    logger.info("In Try - Create TTS client");
    // Set the text input to be synthesized
    SynthesisInput input = SynthesisInput.newBuilder().setText(receivedtext).build();

    // Build the voice request, select the language code ("en-US") and the ssml
    VoiceSelectionParams voice = VoiceSelectionParams.newBuilder().setLanguageCode("en-US")
            .setSsmlGender(SsmlVoiceGender.FEMALE).build();
    logger.info("Set Voice Params");

    // Select the type of audio file you want returned
    AudioConfig audioConfig = AudioConfig.newBuilder().setAudioEncoding(AudioEncoding.MP3).build();
    logger.info("Audio Configured");
    
    // Perform the text-to-speech request
    SynthesizeSpeechResponse response = textToSpeechClient.synthesizeSpeech(input, voice, audioConfig);
    logger.info("Audio Synthesised");
    
    // Get the audio contents from the response
    ByteString audioContents = response.getAudioContent();

    // Write the response to the output file
    try (OutputStream out = new FileOutputStream(audioFileDirectory + audioFileName + audioFileFormat))
    {
        out.write(audioContents.toByteArray());
        logger.info("File Opened and Written");
    }
}

适配当前版本的解决方案

  • 显式配置gRPC超时与重试策略
    当前Google Cloud客户端支持通过TextToSpeechSettings自定义超时和重试规则,避免无限等待或超时异常。示例代码:
// 构建包含超时与重试的Settings
TextToSpeechSettings settings = TextToSpeechSettings.newBuilder()
    .synthesizeSpeechSettings()
    .setRetrySettings(RetrySettings.newBuilder()
        .setTotalTimeout(Duration.ofMinutes(2)) // 总请求超时时间
        .setInitialRetryDelay(Duration.ofSeconds(1))
        .setMaxRetryDelay(Duration.ofSeconds(5))
        .setRetryDelayMultiplier(1.5)
        .setMaxAttempts(3)
        .build())
    .build();

// 使用配置后的Settings创建客户端
try (TextToSpeechClient textToSpeechClient = TextToSpeechClient.create(settings)) {
    // 原有业务逻辑代码...
}
  • 检查并配置网络代理
    若运行环境存在代理,需为gRPC显式配置代理参数,避免请求被阻塞:
// 系统级代理配置
System.setProperty("http.proxyHost", "your-proxy-host");
System.setProperty("http.proxyPort", "your-proxy-port");
System.setProperty("https.proxyHost", "your-proxy-host");
System.setProperty("https.proxyPort", "your-proxy-port");

// 或通过Channel自定义代理
ManagedChannel channel = ManagedChannelBuilder.forTarget(TextToSpeechSettings.getDefaultEndpoint())
    .setProxyDetector(() -> Proxy.newProxyInstance(
        ClassLoader.getSystemClassLoader(),
        new Class[]{HttpURLConnection.class},
        new ProxySelector(null)
    ))
    .build();

TextToSpeechSettings settings = TextToSpeechSettings.newBuilder()
    .setTransportChannelProvider(TextToSpeechSettings.defaultHttpJsonTransportProviderBuilder()
        .setChannel(channel)
        .build())
    .build();
  • 验证认证凭据有效性
    请求停滞可能源于凭据加载失败导致的静默等待,确保GOOGLE_APPLICATION_CREDENTIALS环境变量配置正确,或在代码中显式加载凭据:
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("path/to/your/service-account-key.json"));
TextToSpeechSettings settings = TextToSpeechSettings.newBuilder()
    .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
    .build();
  • 切换为异步调用避免主线程阻塞
    若同步调用持续停滞,可尝试异步调用方式,通过回调处理结果,避免主线程阻塞:
textToSpeechClient.synthesizeSpeechCallable().futureCall(input, voice, audioConfig)
    .addListener(() -> {
        try {
            SynthesizeSpeechResponse response = textToSpeechClient.synthesizeSpeechCallable().futureCall(input, voice, audioConfig).get();
            // 处理音频响应逻辑,如写入文件等...
            ByteString audioContents = response.getAudioContent();
            try (OutputStream out = new FileOutputStream(audioFileDirectory + audioFileName + audioFileFormat)) {
                out.write(audioContents.toByteArray());
                logger.info("音频文件写入完成");
            }
        } catch (Exception e) {
            logger.error("语音合成失败", e);
        }
    }, MoreExecutors.directExecutor());

内容的提问来源于stack exchange,提问作者Thomas A Mathew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 12:53:22