0

テキスト読み上げサービス (TTS) を使用して、Yelp API から結果を読み取ります。タイミングの問題が発生しています:

  1. TTS 関数の呼び出しが速すぎると、音声が中断されます。

私のアイデアは、オーディオが再生されているかどうかを確認し、完了したら次のコマンドのみを赤くするセマフォを作成することでした。不運にも:

  1. オーディオが再生されなくなるまで待つと (audio.paused == true)、プログラムがハングアップし、while ループから抜け出せなくなります。

2番目の問題に遭遇せずに最初の問題を解決する方法について、誰かアイデアはありますか?

//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)
            }
    })
    }
4

1 に答える 1

3

セマフォは、マルチスレッド/IPC 環境で使用されます。JavaScriptエンジンでは、これはありません。setTimeout または setIntegal を使用しない限り、Javascript でポーリングしようとしていますが、これはシングル スレッド環境では機能しません。

あなたのセットアップでは、3 種類のイベントがあるように見えます。新しい音声タスクが表示され (キューに入れられる必要があります)、Yelp AJAX 呼び出しが返され、オーディオ再生が終了します。最初の 2 つのイベントを処理したようで、音声終了イベントを処理する方法を見つけようとしています。

すべてのキューサービスコードを独自の関数に移動し、興味深いイベントが発生するたびにそれを呼び出します。何をすべきかは、キュー サービス コードに任せてください。コードの残りの部分は、イベントを処理し、状態を追跡するだけです。このようなものがうまくいくかもしれません:

    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());

そしてより明確です。

于 2013-02-08T21:14:11.173 に答える