我正在使用文本转语音服务 (TTS) 来读取 Yelp API 的结果。我遇到了时间问题:
- 如果我太快调用 TTS 功能,语音会自行中断。
我的想法是编写一个信号量来检查音频是否正在播放,并且只有在完成后才将下一个命令显示为红色。不幸的是:
- 如果我等到音频不播放(audio.paused == true),程序就会挂起/不会跳出 while 循环。
有人知道如何解决第一个问题而不遇到第二个问题吗?
//check if command isn't already queued, and then add command to the queue
function voiceSynth (string, name) {
if(voiceQueue.indexOf(string)== -1){
voiceQueue.push(string)
voiceQueue.push(name) //used to keep track of the current item being read
}
//Iterate over items in the queue
while (voiceQueue.length > 1){
if (voiceBusy == false && audio.paused == true) {
voiceCall.call(undefined, voiceQueue.shift(),voiceQueue.shift())
}
}
}
//ajax call to the TTS service
function voiceCall (string, name) {
voiceBusy = true
console.log('synth called on ' + string)
$.ajax('read/?string=' + string + '&speed=' + speed, {
type: 'GET',
success: function(src) {
audio.setAttribute('src', src)
audio.play()
voiceBusy = false
voiceCursor = name
},
error: function(xhr, ajaxOptions, thrownError) {
console.log(xhr)
console.log(ajaxOptions)
console.log(thrownError)
}
})
}
最佳答案
信号量用于多线程/IPC 环境。使用 javascript 引擎,你就没有这个。您尝试在 Javascript 中轮询,这在单线程环境中不起作用,除非您使用 setTimeout 或 setInteval。
在您的设置中,您似乎有三种类型的事件:新的语音任务出现(并且应该排队)、Yelp AJAX 调用返回以及音频播放结束。您似乎已经处理了前两个事件,并且正在尝试找出如何处理音频结束事件。
我会将所有队列服务代码移至其自己的函数中,然后在发生有趣的事件时调用它。让队列服务代码弄清楚要做什么。其余代码只需处理事件并跟踪状态。像这样的东西可能会起作用:
var ajaxOutstanding = false;
var audioOutstanding = false;
function voiceSynth(string, name) {
if(voiceQueue.indexOf(string)== -1){
voiceQueue.push(string)
voiceQueue.push(name) //used to keep track of the current item being read
}
serviceQueue();
}
//ajax call to the TTS service
function voiceCall (string, name) {
console.log('synth called on ' + string)
$.ajax('read/?string=' + string + '&speed=' + speed, {
type: 'GET',
success: function(src) {
ajaxOutstanding = false;
audio.setAttribute('src', src);
audioOutstanding = true;
audio.play();
voiceCursor = name;
serviceQueue();
},
error: function(xhr, ajaxOptions, thrownError) {
ajaxOutstanding = false;
console.log(xhr);
console.log(ajaxOptions);
console.log(thrownError);
serviceQueue();
}
});
}
function handleAudioEnded() {
audioOutstanding = false;
serviceQueue();
}
audio.addEventListener('ended', handleAudioEnded);
function serviceQueue() {
if (voiceQueue.length > 1 && !ajaxOustanding && !audioOutstanding) {
voiceCall.call(undefined, voiceQueue.shift(),voiceQueue.shift());
}
}
顺便说一下,
voiceCall.call(undefined, voiceQueue.shift(),voiceQueue.shift());
与
相同 voiceCall(voiceQueue.shift(), voiceQueue.shift());
而且更清晰。
关于javascript - 如何编写信号量检查两种不同的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14780290/