@itslanguage/api
Version:
The JavaScript API SDK for ITSLanguage.
277 lines (230 loc) • 23.4 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>challenges/choice/recognition.js - ITSLanguage JavaScript SDK</title>
<meta name="description" content="Speech technology for language education. JSDoc 3 website for the JavaScript SDK." />
<meta name="keywords" content="itslangauge, jsdoc, documentation, speech, speech technology" />
<meta name="keyword" content="itslangauge, jsdoc, documentation, speech, speech technology" />
<meta property="og:title" content="ITSLanguage JavaScript SDK"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="https://avatars0.githubusercontent.com/u/20972344?s=400&u=73936e7fa2d2a1e5c180a11675bf9166d3717a6d&v=4"/>
<meta property="og:site_name" content="ITSLanguage JavaScript SDK"/>
<meta property="og:url" content="http://itslanguage.github.io/itslanguage-js/"/>
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
<script src="scripts/nav.js" defer></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
<div class="navicon"></div>
</label>
<label for="nav-trigger" class="overlay"></label>
<nav >
<input type="text" id="nav-search" placeholder="Search" />
<h2><a href="index.html">Home</a></h2><h2><a href="https://github.com/itslanguage/itslanguage-js" target="_blank" class="menu-item" id="repository" >Github repo</a></h2><h3>Modules</h3><ul><li><a href="module-api.html">api</a><ul class='members'><li data-type='member'><a href="module-api.html#.version">version</a></li></ul><ul class='methods'><li data-type='method'><a href="module-api.html#.createItslApi">createItslApi</a></li></ul></li><li><a href="module-api_authentication.html">api/authentication</a><ul class='methods'><li data-type='method'><a href="module-api_authentication.html#.assembleScope">assembleScope</a></li><li data-type='method'><a href="module-api_authentication.html#.authenticate">authenticate</a></li><li data-type='method'><a href="module-api_authentication.html#.impersonate">impersonate</a></li></ul></li><li><a href="module-api_basicauth.html">api/basicauth</a><ul class='methods'><li data-type='method'><a href="module-api_basicauth.html#.create">create</a></li></ul></li><li><a href="module-api_broadcaster.html">api/broadcaster</a></li><li><a href="module-api_categories.html">api/categories</a><ul class='methods'><li data-type='method'><a href="module-api_categories.html#.create">create</a></li><li data-type='method'><a href="module-api_categories.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_categories.html#.getAllWithParentId">getAllWithParentId</a></li><li data-type='method'><a href="module-api_categories.html#.getById">getById</a></li><li data-type='method'><a href="module-api_categories.html#.update">update</a></li></ul></li><li><a href="module-api_challenges.html">api/challenges</a><ul class='members'><li data-type='member'><a href="module-api_challenges.html#.choice">choice</a></li><li data-type='member'><a href="module-api_challenges.html#.choiceRecognition">choiceRecognition</a></li><li data-type='member'><a href="module-api_challenges.html#.feedback">feedback</a></li><li data-type='member'><a href="module-api_challenges.html#.feedbackSpeech">feedbackSpeech</a></li><li data-type='member'><a href="module-api_challenges.html#.pronunciation">pronunciation</a></li><li data-type='member'><a href="module-api_challenges.html#.pronunciationAnalysis">pronunciationAnalysis</a></li><li data-type='member'><a href="module-api_challenges.html#.speech">speech</a></li><li data-type='member'><a href="module-api_challenges.html#.speechRecording">speechRecording</a></li></ul></li><li><a href="module-api_challenges_choice.html">api/challenges/choice</a><ul class='methods'><li data-type='method'><a href="module-api_challenges_choice.html#.create">create</a></li><li data-type='method'><a href="module-api_challenges_choice.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_challenges_choice.html#.getById">getById</a></li></ul></li><li><a href="module-api_challenges_choice_recognition.html">api/challenges/choice/recognition</a><ul class='methods'><li data-type='method'><a href="module-api_challenges_choice_recognition.html#.create">create</a></li><li data-type='method'><a href="module-api_challenges_choice_recognition.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_challenges_choice_recognition.html#.getById">getById</a></li><li data-type='method'><a href="module-api_challenges_choice_recognition.html#.prepare">prepare</a></li><li data-type='method'><a href="module-api_challenges_choice_recognition.html#.prepareChallenge">prepareChallenge</a></li><li data-type='method'><a href="module-api_challenges_choice_recognition.html#.recognise">recognise</a></li><li data-type='method'><a href="module-api_challenges_choice_recognition.html#.recogniseAudioStream">recogniseAudioStream</a></li><li data-type='method'><a href="module-api_challenges_choice_recognition.html#.recogniseNonStreaming">recogniseNonStreaming</a></li><li data-type='method'><a href="module-api_challenges_choice_recognition.html#~url">url</a></li></ul></li><li><a href="module-api_challenges_feedback.html">api/challenges/feedback</a><ul class='methods'><li data-type='method'><a href="module-api_challenges_feedback.html#.create">create</a></li><li data-type='method'><a href="module-api_challenges_feedback.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_challenges_feedback.html#.getById">getById</a></li></ul></li><li><a href="module-api_challenges_feedback_speech.html">api/challenges/feedback/speech</a><ul class='methods'><li data-type='method'><a href="module-api_challenges_feedback_speech.html#.feedback">feedback</a></li><li data-type='method'><a href="module-api_challenges_feedback_speech.html#.listenAndReply">listenAndReply</a></li><li data-type='method'><a href="module-api_challenges_feedback_speech.html#.pause">pause</a></li><li data-type='method'><a href="module-api_challenges_feedback_speech.html#.prepare">prepare</a></li><li data-type='method'><a href="module-api_challenges_feedback_speech.html#.resume">resume</a></li></ul></li><li><a href="module-api_challenges_pronunciation.html">api/challenges/pronunciation</a><ul class='methods'><li data-type='method'><a href="module-api_challenges_pronunciation.html#.create">create</a></li><li data-type='method'><a href="module-api_challenges_pronunciation.html#.deleteChallenge">deleteChallenge</a></li><li data-type='method'><a href="module-api_challenges_pronunciation.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_challenges_pronunciation.html#.getById">getById</a></li></ul></li><li><a href="module-api_challenges_pronunciation_analysis.html">api/challenges/pronunciation/analysis</a><ul class='methods'><li data-type='method'><a href="module-api_challenges_pronunciation_analysis.html#.alignChallenge">alignChallenge</a></li><li data-type='method'><a href="module-api_challenges_pronunciation_analysis.html#.endStreamAudio">endStreamAudio</a></li><li data-type='method'><a href="module-api_challenges_pronunciation_analysis.html#.getById">getById</a></li><li data-type='method'><a href="module-api_challenges_pronunciation_analysis.html#.prepare">prepare</a></li><li data-type='method'><a href="module-api_challenges_pronunciation_analysis.html#.prepareAudio">prepareAudio</a></li><li data-type='method'><a href="module-api_challenges_pronunciation_analysis.html#.prepareChallenge">prepareChallenge</a></li><li data-type='method'><a href="module-api_challenges_pronunciation_analysis.html#.streamAudio">streamAudio</a></li><li data-type='method'><a href="module-api_challenges_pronunciation_analysis.html#~url">url</a></li></ul></li><li><a href="module-api_challenges_speech.html">api/challenges/speech</a><ul class='methods'><li data-type='method'><a href="module-api_challenges_speech.html#.create">create</a></li><li data-type='method'><a href="module-api_challenges_speech.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_challenges_speech.html#.getById">getById</a></li></ul></li><li><a href="module-api_challenges_speech_recordings.html">api/challenges/speech/recordings</a><ul class='methods'><li data-type='method'><a href="module-api_challenges_speech_recordings.html#.create">create</a></li><li data-type='method'><a href="module-api_challenges_speech_recordings.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_challenges_speech_recordings.html#.getById">getById</a></li><li data-type='method'><a href="module-api_challenges_speech_recordings.html#.record">record</a></li><li data-type='method'><a href="module-api_challenges_speech_recordings.html#~url">url</a></li></ul></li><li><a href="module-api_communication.html">api/communication</a><ul class='members'><li data-type='member'><a href="module-api_communication.html#.settings">settings</a></li><li data-type='member'><a href="module-api_communication.html#~APPLICATION_JSON">APPLICATION_JSON</a></li><li data-type='member'><a href="module-api_communication.html#~AUTHORIZATION">AUTHORIZATION</a></li><li data-type='member'><a href="module-api_communication.html#~CONTENT_TYPE">CONTENT_TYPE</a></li><li data-type='member'><a href="module-api_communication.html#~LINK">LINK</a></li></ul><ul class='methods'><li data-type='method'><a href="module-api_communication.html#.addAccessToken">addAccessToken</a></li><li data-type='method'><a href="module-api_communication.html#.authorisedRequest">authorisedRequest</a></li><li data-type='method'><a href="module-api_communication.html#.request">request</a></li><li data-type='method'><a href="module-api_communication.html#.updateSettings">updateSettings</a></li><li data-type='method'><a href="module-api_communication.html#~getBearerToken">getBearerToken</a></li><li data-type='method'><a href="module-api_communication.html#~handleResponse">handleResponse</a></li></ul></li><li><a href="module-api_communication_websocket.html">api/communication/websocket</a><ul class='methods'><li data-type='method'><a href="module-api_communication_websocket.html#.closeWebsocketConnection">closeWebsocketConnection</a></li><li data-type='method'><a href="module-api_communication_websocket.html#.getWebsocketConnection">getWebsocketConnection</a></li><li data-type='method'><a href="module-api_communication_websocket.html#.makeWebsocketCall">makeWebsocketCall</a></li><li data-type='method'><a href="module-api_communication_websocket.html#.openWebsocketConnection">openWebsocketConnection</a></li><li data-type='method'><a href="module-api_communication_websocket.html#~establishNewBundesbahn">establishNewBundesbahn</a></li><li data-type='method'><a href="module-api_communication_websocket.html#~handleWebsocketAuthorisationChallenge">handleWebsocketAuthorisationChallenge</a></li></ul></li><li><a href="module-api_emailauth.html">api/emailauth</a><ul class='methods'><li data-type='method'><a href="module-api_emailauth.html#.create">create</a></li><li data-type='method'><a href="module-api_emailauth.html#~url">url</a></li></ul></li><li><a href="module-api_groups.html">api/groups</a><ul class='methods'><li data-type='method'><a href="module-api_groups.html#.create">create</a></li><li data-type='method'><a href="module-api_groups.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_groups.html#.getById">getById</a></li></ul></li><li><a href="module-api_organisations.html">api/organisations</a><ul class='methods'><li data-type='method'><a href="module-api_organisations.html#.create">create</a></li><li data-type='method'><a href="module-api_organisations.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_organisations.html#.getById">getById</a></li></ul></li><li><a href="module-api_profile.html">api/profile</a><ul class='methods'><li data-type='method'><a href="module-api_profile.html#.create">create</a></li><li data-type='method'><a href="module-api_profile.html#.getById">getById</a></li><li data-type='method'><a href="module-api_profile.html#.getCurrent">getCurrent</a></li><li data-type='method'><a href="module-api_profile.html#~url">url</a></li></ul></li><li><a href="module-api_progress.html">api/progress</a><ul class='methods'><li data-type='method'><a href="module-api_progress.html#.getById">getById</a></li></ul></li><li><a href="module-api_roles.html">api/roles</a><ul class='methods'><li data-type='method'><a href="module-api_roles.html#.create">create</a></li><li data-type='method'><a href="module-api_roles.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_roles.html#.getById">getById</a></li></ul></li><li><a href="module-api_tenants.html">api/tenants</a><ul class='methods'><li data-type='method'><a href="module-api_tenants.html#.create">create</a></li><li data-type='method'><a href="module-api_tenants.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_tenants.html#.getById">getById</a></li></ul></li><li><a href="module-api_users.html">api/users</a><ul class='methods'><li data-type='method'><a href="module-api_users.html#.create">create</a></li><li data-type='method'><a href="module-api_users.html#.getAll">getAll</a></li><li data-type='method'><a href="module-api_users.html#.getById">getById</a></li><li data-type='method'><a href="module-api_users.html#.getCurrent">getCurrent</a></li></ul></li><li><a href="module-api_utils.html">api/utils</a><ul class='methods'><li data-type='method'><a href="module-api_utils.html#.asyncBlobToArrayBuffer">asyncBlobToArrayBuffer</a></li><li data-type='method'><a href="module-api_utils.html#.checkAudioIsNotEmpty">checkAudioIsNotEmpty</a></li><li data-type='method'><a href="module-api_utils.html#.dataToBase64">dataToBase64</a></li></ul></li><li><a href="module-api_utils_audio-over-socket.html">api/utils/audio-over-socket</a><ul class='methods'><li data-type='method'><a href="module-api_utils_audio-over-socket.html#.encodeAndSendAudioOnDataAvailable">encodeAndSendAudioOnDataAvailable</a></li><li data-type='method'><a href="module-api_utils_audio-over-socket.html#.prepareServerForAudio">prepareServerForAudio</a></li><li data-type='method'><a href="module-api_utils_audio-over-socket.html#.registerStreamForRecorder">registerStreamForRecorder</a></li></ul></li></ul><h3>Classes</h3><ul><li><a href="module-api.Itslanguage.html">Itslanguage</a></li></ul><h3>Events</h3><ul><li><a href="broadcaster.html#event:websocketserverreadyforaudio">websocketserverreadyforaudio</a></li></ul>
</nav>
<div id="main">
<h1 class="page-title">challenges/choice/recognition.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* This file contains the readily available functions which interact with the
* ITSLanguage choice recognition API.
*
* Speech recognitions can be stored and retrieved for user submitted audio using the ITSLanguage
* Speech API. The actual recognitions are performed by the ITSLanguage websocket server.
*
* For streaming, note that this is one of the "nested" or "composite" APIs; You can only obtain the
* data if you provide a reference to the challenge for which you want a recording.
*
* @module api/challenges/choice/recognition
*/
import {
registerStreamForRecorder,
encodeAndSendAudioOnDataAvailable,
prepareServerForAudio,
} from '../../utils/audio-over-socket';
import { authorisedRequest } from '../../communication';
import { makeWebsocketCall } from '../../communication/websocket';
/**
* The URL for the choice recognition challenge handler(s).
*
* @param challengeId
* @returns {string}
*/
const url = challengeId => `/challenges/choice/${challengeId}/recognitions`;
/**
* Submit an audio fragment for recognition. The recognition is created for the current
* authenticated user.
*
* @see https://itslanguage.github.io/itslanguage-docs/api/recognitions/index.html#create-a-choice-recognition
* @param {string} challengeId - The ID of the challenge to relate the recognition to.
* @param {Blob} audio - The actual audio.
* @param {string} recognised - The recognised string.
* @param {string} [recognitionId=null] - Unique identifier for the recognition. If none is given,
* one is generated.
* @returns {Promise} - The created recognition with an url to download the audio if needed.
*/
export function create(challengeId, audio, recognised, recognitionId = null) {
const recognition = {
audio,
recognised,
};
if (recognitionId) {
recognition.id = recognitionId;
}
return authorisedRequest('POST', `${url(challengeId)}`, recognition);
}
/**
* Get a single ChoiceRecognition by its ID.
*
* @see https://itslanguage.github.io/itslanguage-docs/api/recognitions/index.html#get-a-single-choice-recognition
* @param {string} challengeId - ID of the Choice Challenge to get all the recognitions for.
* @param {string} id - ID of the choice recognition to get.
* @returns {Promise} - Promise with the Choice Recognition as result if successful.
*/
export function getById(challengeId, id) {
return authorisedRequest('GET', `${url(challengeId)}/${id}`);
}
/**
* Get all Choice Recognitions for a specific Choice Challenge.
*
* @see https://itslanguage.github.io/itslanguage-docs/api/recognitions/index.html#list-choice-recognitions
* @param {string} challengeId - ID of the Choice Challenge to get all the recognitions for.
* @returns {Promise} - Promise with the Choice Recognitions as result if successful.
*/
export function getAll(challengeId) {
return authorisedRequest('GET', `${url(challengeId)}`);
}
/**
* This is the starting point for a choice recognition. A unique recognition id is generated,
* which serves a leading role in the recognition. Each other call requires the recognition id
* as a parameter.
*
* If other RPCs are called without this RPC being called first, the error
* `nl.itslanguage.session_not_initialised` will be returned.
*
* @see https://itslanguage.github.io/itslanguage-docs/websocket/choice_recognitions/index.html#initialising-a-choice-recognition
* @returns {Promise} - Returns a promise. When successfully the ID of the recognition is returned.
*/
export function prepare() {
return makeWebsocketCall('choice.init_recognition');
}
/**
* Before performing the recognition, a WFST needs to be prepared for the challenge. When the RPC is
* called, the challenge is initialised asynchronously. When the challenge is to be used, the server
* automatically waits for the challenge initialisation to finish. If the initialisation results in
* an error, the error is relayed to the client.
*
* @see https://itslanguage.github.io/itslanguage-docs/websocket/choice_recognitions/index.html#initialise-choice-challenge
* @param {string} recognitionId - The ID of the recognition to prepare the challenge for.
* @param {string} challengeId - The ID of the challenge to prepare.
* @returns {Promise} - If succesful the promise returns nothing. On error, there will be an error.
*/
export function prepareChallenge(recognitionId, challengeId) {
return makeWebsocketCall('choice.init_challenge', {
args: [recognitionId, challengeId],
});
}
/**
* Based on a recognitionId and a recorder register a RPC call that will be used to send the audio
* across the line. The actual registration will not be done here, but we send the RPC that the
* backend needs to call to the 'nl.itslanguage.choice.recognise' function.
*
* @param {string} recognitionId - The ID of the recognition to send audio for.
* @param {MediaRecorder} recorder - Audio recorder instance.
* @returns {Promise} - When all good, the result will have the actual recognition.
*/
export function recogniseAudioStream(recognitionId, recorder) {
// Generate a somewhat unique RPC name
const rpcNameToRegister = `choice.stream.${Math.floor(Date.now() / 1000)}`;
return (
registerStreamForRecorder(recorder, rpcNameToRegister)
// We don't use rpcNameToRegister here because it lacks some namespacing info. The
// registration.procedure does have the needed information.
.then(registration =>
makeWebsocketCall('choice.recognise', {
args: [recognitionId, registration.procedure],
}),
)
);
}
/**
* Easy function to do a recognition in one go. This is the "dance of the RPC's" that needs to be
* done in order to get correct feedback from the backend.
*
* @param {string} challengeId - The ID of the challenge to take the recognition for.
* @param {MediaRecorder} recorder - Audio recorder instance.
* @returns {Promise<*>} - If all good it returns the actual recognition. If not, any error can be
* expected to be returned.
*/
export function recognise(challengeId, recorder) {
let recognitionId;
return prepare()
.then(rId => {
recognitionId = rId;
return rId;
})
.then(() => prepareChallenge(recognitionId, challengeId))
.then(() =>
recogniseAudioStream(recognitionId, recorder).then(result => result),
);
}
/**
* Easy function to do a recognition in one go. This is the "dance of the RPC's" that needs to be
* done in order to get correct feedback from the backend.
*
* This function is here to support possible old backend servers where we did not use the streaming
* for choice challenges yet. It is deprecated and will be removed in the first minor update of the
* api sdk.
*
* @deprecated
* @param {string} challengeId - The ID of the challenge to take the recognition for.
* @param {MediaRecorder} recorder - Audio recorder instance.
* @returns {Promise<*>} - If all good it returns the actual recognition. If not, any error can be
* expected to be returned.
*/
export function recogniseNonStreaming(challengeId, recorder) {
let recognitionId;
return prepare()
.then(rId => {
recognitionId = rId;
return rId;
})
.then(() => prepareChallenge(recognitionId, challengeId))
.then(() =>
prepareServerForAudio(recognitionId, recorder, 'choice.init_audio'),
)
.then(() =>
encodeAndSendAudioOnDataAvailable(
recognitionId,
recorder,
'choice.write',
),
)
.then(() =>
makeWebsocketCall('choice.recognise', { args: [recognitionId] }),
);
}
</code></pre>
</article>
</section>
</div>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Mon Oct 12 2020 12:26:34 GMT+0000 (Coordinated Universal Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>
<script>prettyPrint();</script>
<script src="scripts/polyfill.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/search.js" defer></script>
</body>
</html>