3

Je travaille sur le tutorial pour IBM Watson Speech-to-Text, en utilisant WebSocket pour la transcription en temps réel. J'utilise Angular.Les données du microphone d'envoi de texte de synthèse d'IBM Watson se terminent

Les 25 premières lignes de code sont copiées à partir du API reference. Ce code se connecte avec succès et lance une demande de reconnaissance. Watson m'envoie un message { "state": "listening" }. J'ai écrit function onClose() qui se connecte lorsque la connexion se ferme.

J'ai fait un bouton qui exécute le gestionnaire $scope.startSpeechRecognition. Cela utilise getUserMedia() pour diffuser l'audio à partir du microphone et websocket.send() pour diffuser les données à Watson. Cela ne fonctionne pas. Cliquer sur ce bouton ferme la connexion. Je suppose que j'envoie le mauvais type de données et Watson ferme la connexion? J'ai déplacé websocket.send(blob); de onOpen à mon gestionnaire $scope.startSpeechRecognition. J'ai changé websocket.send(blob); en websocket.send(mediaStream);. Je peux avoir tort: ​​'content-type': 'audio/l16;rate=22050'. Comment savoir quel débit provient du microphone?

Existe-t-il un tutoriel pour JavaScript? Lorsque je google "didacticiel JavaScript IBM Watson discours-texte" en haut est un 8000-line SDK. Le SDK est-il nécessaire ou puis-je écrire un programme simple pour apprendre comment fonctionne le service?

Voici mon contrôleur:

'use strict'; 
app.controller('WatsonController', ['$scope', 'watsonToken', function($scope, watsonToken) { 
    console.log("Watson controller."); 

    var token = watsonToken; 
    var wsURI = "wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize" 
    + "?watson-token=" + token + '&model=en-US_BroadbandModel'; 

    var websocket = new WebSocket(wsURI); // opens connection to Watson 
    websocket.onopen = function(evt) { onOpen(evt) }; // executes when a connection opens 
    websocket.onclose = function(evt) { onClose(evt) }; // executes when a connection closes 
    websocket.onmessage = function(evt) { onMessage(evt) }; // logs messages from Watson to the console 
    websocket.onerror = function(evt) { onError(evt) }; // logs errors to the console 

    function onOpen(evt) { 
    var message = { 
     action: 'start', 
     'content-type': 'audio/flac', 
     'interim_results': true, 
     'max-alternatives': 3, 
     keywords: ['colorado', 'tornado', 'tornadoes'], 
     'keywords_threshold': 0.5 
    }; 
    websocket.send(JSON.stringify(message)); 

    // Prepare and send the audio file. 
    // websocket.send(blob); 

    // websocket.send(JSON.stringify({action: 'stop'})); 
    } 

    function onClose() { 
    console.log("Connection closed."); 
    }; 

    function onMessage(evt) { 
    console.log(evt.data); // log the message to the console 
    } 

    $scope.startSpeechRecognition =() => { 
    console.log("Starting speech recognition."); 
    var constraints = { audio: true, video: false }; 
    navigator.mediaDevices.getUserMedia(constraints) 
    .then(function(mediaStream) { 
     console.log("Streaming audio."); 
     websocket.send(mediaStream); 
    }) 
    .catch(function(err) { console.log(err.name + ": " + err.message); }); // log errors 
    }; 

    $scope.stopSpeechRecognition =() => { // handler for button 
    console.log("Stopping speech recognition."); 
    websocket.send(JSON.stringify({action: 'stop'})); 
    }; 

    $scope.closeWatsonSpeechToText =() => { // handler for button 
    console.log("Closing connection to Watson."); 
    websocket.close(); // closes connection to Watson? 
    }; 

}]); 

Et voici mon modèle:

<div class="row"> 
    <div class="col-sm-2 col-md-2 col-lg-2"> 
    <p>Watson test.</p> 
    </div> 
</div> 

<div class="row"> 
    <div class="col-sm-2 col-md-2 col-lg-2"> 
    <button type="button" class="btn btn-primary" ng-click="startSpeechRecognition()">Start</button> 
    </div> 

    <div class="col-sm-2 col-md-2 col-lg-2"> 
    <button type="button" class="btn btn-warning" ng-click="stopSpeechRecognition()">Stop</button> 
    </div> 

    <div class="col-sm-2 col-md-2 col-lg-2"> 
    <button type="button" class="btn btn-danger" ng-click="closeWatsonSpeechToText()">Close</button> 
    </div> 
</div> 
+0

Thomas, il y a un javascript sdk qui va vous faciliter la vie: https://github.com/watson-developer-cloud/speech-javascript-sdk Regardez les exemples ici. –

Répondre

3

The SDK n'est pas nécessaire, mais comme l'a dit Geman Attanasio, il ne vous rendre la vie beaucoup plus facile.

sur votre code, cependant, cette ligne certainement ne fonctionnera pas:

websocket.send(mediaStream);

L'objet mediaStream de getUserMedia() ne peut pas être directement envoyé sur le WebsSocket - WebSockets acceptent que du texte et binaire données (blob dans l'exemple original). Vous devez extraire l'audio et l'envoyer seulement.

Mais même cela n'est pas suffisant dans ce cas, car l'API WebAudio fournit l'audio dans les flottants 32 bits, ce qui n'est pas un format que l'API Watson comprend nativement. Le SDK l'extrait automatiquement et le convertit en audio/l16;rate=16000 (16 bits).

Comment connaître le débit binaire du microphone?

Il est disponible sur le AudioContext et, si vous ajoutez un scriptProcessorNode, il peut être transmis AudioBuffers qui incluent des données audio et la fréquence d'échantillonnage. Multipliez la fréquence d'échantillonnage par la taille de chaque échantillon (32 bits avant la conversion en l16, 16 bits après) par le nombre de canaux (généralement 1) pour obtenir le débit binaire.Mais notez que le nombre que vous mettez dans le type de contenu sous rate= est la fréquence d'échantillonnage, pas le débit binaire. Vous pouvez donc simplement le copier depuis AudioContext ou AudioBuffer sans multiplication. (À moins que vous n'échantilliez l'audio, comme le fait le SDK, il doit être réglé sur le taux d'échantillonnage cible, pas sur le taux d'entrée.)

Si vous voulez voir comment tout cela fonctionne, SDK est open source:

Familiarité avec le Node.js Streams standard est utile lors de la lecture de ces fichiers. FWIW, si vous utilisez un système de regroupement tel que Browserify ou Webpack, vous pouvez choisir uniquement les parties du SDK dont vous avez besoin et obtenir une taille de fichier beaucoup plus petite. Vous pouvez également le configurer pour le téléchargement après le chargement et le rendu de la page puisque le SDK ne fera pas partie de votre rendu initial.

+1

Merci, j'ai téléchargé le SDK et je viens de recevoir l'exemple "Transcribe from Microphone" exécuté localement dans mon navigateur. Demain, je vais essayer de le faire à partir de mon projet Angular. –

+1

J'ai un travail de synthèse vocale en Angular. Merci encore! –

+0

Content de l'entendre! –