UNPKG

web-speech-profanity

Version:

Web Speech API adapter to use Cognitive Services Speech Services for both speech-to-text and text-to-speech service.

99 lines (79 loc) 2.71 kB
import memoize from 'memoize-one'; import AudioContextQueue from './AudioContextQueue'; import DOMEventEmitter from '../Util/DOMEventEmitter'; import fetchAuthorizationToken from '../fetchAuthorizationToken'; import fetchVoices from './fetchVoices'; import SpeechSynthesisUtterance from './SpeechSynthesisUtterance'; // Supported output format can be found at https://docs.microsoft.com/en-us/azure/cognitive-services/Speech/API-Reference-REST/BingVoiceOutput#Subscription const DEFAULT_OUTPUT_FORMAT = 'audio-16khz-128kbitrate-mono-mp3'; const TOKEN_EXPIRATION = 600000; const TOKEN_EARLY_RENEWAL = 60000; export default ({ authorizationToken, ponyfill = { AudioContext: window.AudioContext || window.webkitAudioContext }, subscriptionKey }) => { if (!authorizationToken && !subscriptionKey) { console.warn('Either authorizationToken or subscriptionKey must be specified'); return {}; } else if (!ponyfill.AudioContext) { console.warn('This browser does not support Web Audio and it will not work with Cognitive Services Speech Services.'); return {}; } const fetchMemoizedAuthorizationToken = memoize( ({ subscriptionKey }) => fetchAuthorizationToken(subscriptionKey), (arg, prevArg) => ( arg.subscriptionKey === prevArg.subscriptionKey && arg.now - prevArg.now < TOKEN_EXPIRATION - TOKEN_EARLY_RENEWAL ) ); class SpeechSynthesis extends DOMEventEmitter { constructor() { super(['voiceschanged']); this.outputFormat = DEFAULT_OUTPUT_FORMAT; this.queue = new AudioContextQueue(ponyfill); } cancel() { this.queue.stop(); } getVoices() { return fetchVoices(); } pause() { this.queue.pause(); } resume() { this.queue.resume(); } async speak(utterance) { if (!(utterance instanceof SpeechSynthesisUtterance)) { throw new Error('invalid utterance'); } return new Promise(async (resolve, reject) => { utterance.addEventListener('end', resolve); utterance.addEventListener('error', reject); utterance.authorizationToken = typeof authorizationToken === 'function' ? await authorizationToken() : authorizationToken ? await authorizationToken : await fetchMemoizedAuthorizationToken({ now: Date.now, subscriptionKey }); utterance.outputFormat = this.outputFormat; utterance.preload(); this.queue.push(utterance); }); } get speaking() { return this.queue.speaking; } } return { speechSynthesis: new SpeechSynthesis(), SpeechSynthesisUtterance }; }