谷歌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
相关产品推荐
相关产品推荐

