如何在Azure Speech Service文本转语音时实现音频播放控制及按钮启停?
实现同一按钮控制播放/停止Azure Speech Service语音合成
核心思路
Azure Speech SDK的SpeechSynthesizer提供了stopSpeakingAsync方法来终止正在进行的语音合成与播放,我们只需要添加状态标记区分按钮的两种操作模式(播放/停止),并在合适时机更新状态即可。无需保存为WAV文件就能实现控制,如果有离线播放需求,也可以结合Audio元素控制已保存的音频文件。
修改后的完整代码
const speechConfig = SpeechSDK.SpeechConfig.fromSubscription("key", "region"); let synthesizer = null; let isPlaying = false; // 标记当前是否正在播放 function initializeSynthesizer() { const audioConfig = SpeechSDK.AudioConfig.fromDefaultSpeakerOutput(); synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig, audioConfig); synthesizer.synthesizing = (s, e) => { console.log(`Synthesizing: ${e.result.audioData.byteLength} bytes`); }; // 合成完成或取消时重置播放状态 synthesizer.synthesisCompleted = () => { isPlaying = false; updateButtonText(); }; synthesizer.synthesisCanceled = () => { isPlaying = false; updateButtonText(); }; } function convertTextToSpeech(text) { if (!synthesizer) { initializeSynthesizer(); } isPlaying = true; updateButtonText(); let selectedLanguage = TranslationModule.getSelectedLanguage(); TranslationModule.translateText(text, selectedLanguage).then(translatedText => { synthesizer.speakTextAsync( translatedText, result => { if (result.reason === SpeechSDK.ResultReason.SynthesizingAudioCompleted) { console.log("Speech synthesis completed."); } else { console.error("Speech synthesis canceled, " + result.errorDetails); } }, error => { console.error("Error during speech synthesis:", error); isPlaying = false; updateButtonText(); } ); console.log("Speech synthesis started:", text); }).catch(error => { console.error('Error translating text for speech:', error); isPlaying = false; updateButtonText(); }); } function stopSpeech() { if (synthesizer && isPlaying) { synthesizer.stopSpeakingAsync( () => { console.log("Speech stopped successfully."); isPlaying = false; updateButtonText(); }, error => { console.error("Error stopping speech:", error); isPlaying = false; updateButtonText(); } ); } } // 更新按钮显示文本,提升用户体验 function updateButtonText() { const btn = document.getElementById('btnread'); btn.textContent = isPlaying ? '停止播放' : '朗读文本'; } $(document).off('click').on('click', '#btnread', function () { let textToRead = this.getAttribute('data-text'); if (isPlaying) { stopSpeech(); } else { convertTextToSpeech(textToRead); } });
关键修改点说明
- 添加
isPlaying状态变量:跟踪当前播放状态,决定按钮的点击行为。 - 新增
stopSpeech函数:封装SDK的stopSpeakingAsync方法,终止语音合成与播放并更新状态。 - 状态重置逻辑:在合成完成、取消、出错时自动重置
isPlaying,避免状态不一致。 - 按钮文本更新:通过
updateButtonText切换按钮显示文本,让用户清晰知晓当前操作。 - 按钮点击事件逻辑:根据
isPlaying状态判断执行播放还是停止操作。
关于保存WAV文件的控制方式
如果需要先保存合成音频为WAV文件再播放,可通过HTML5的Audio元素实现控制:
- 合成时将
audioConfig改为AudioConfig.fromAudioOutputBytesStream()获取音频数据,转为Blob后创建Audio对象。 - 调用Audio对象的
play()和pause()方法实现播放/停止,同时跟踪Audio的播放状态。
但这种方式需要额外处理音频数据转换,原生SDK的stopSpeakingAsync方法更直接高效,无需保存文件。
内容的提问来源于stack exchange,提问作者Shivani Valaboju
相关产品推荐
相关产品推荐

