Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const path = window.location.pathname;
- const page = path.split("/").pop();
- function playAudio(path, volume, callback) {
- return new Promise((resolve) => {
- _playSound.play(path, volume, callback).then(() => {
- audio = null;
- resolve({ success: true, resultText: `audio played: ${path}`, path: path });
- }).catch((error) => {
- audio = null;
- resolve({ success: false, resultText: error, path: path });
- });
- });
- }
- const _playSound = {
- clearSound: () => {
- Object.values(_playSound.activeAudio).map(function (a) {
- a.pause();
- a.currentTime = 0;
- })
- _playSound.activeAudio = {};
- },
- activeAudio: {},
- play: (path, volume, callback) => {
- let timeStamp = Date.now();
- _playSound.activeAudio[timeStamp] = new Audio(path);
- _playSound.activeAudio[timeStamp].volume = volume || 0.5;
- _playSound.activeAudio[timeStamp].addEventListener('error', function () {
- _playSound.activeAudio[timeStamp] = null;
- delete _playSound.activeAudio[timeStamp];
- }, false);
- _playSound.activeAudio[timeStamp].addEventListener("ended", function () {
- if (callback) {
- callback();
- }
- _playSound.activeAudio[timeStamp] = null;
- delete _playSound.activeAudio[timeStamp];
- }, false);
- return _playSound.activeAudio[timeStamp].play();
- },
- soundQue: {
- list: [],
- active: false,
- add: (path, volume) => {
- _playSound.soundQue.list.push([path, volume]);
- if (!_playSound.soundQue.active) {
- _playSound.soundQue.play();
- }
- },
- play: (data) => {
- if (_playSound.soundQue.list.length > 0) {
- let res = _playSound.soundQue.list.shift();
- _playSound.soundQue.active = true;
- _playSound.play(res[0], res[1], function () {
- if (_playSound.soundQue.list.length > 0) {
- setTimeout(() => _playSound.soundQue.play(), 1000);
- }
- else {
- _playSound.soundQue.active = false;
- }
- });
- }
- }
- }
- }
- const speech = {
- utterances: [],
- playing: false
- };
- function speechPlayer() {
- if (speech.playing === true) return;
- if (speech.utterances.length === 0) return;
- speech.playing = true;
- const msg = speech.utterances.shift();
- msg.onstart = (event) => {
- sentActionToServer(true, 'onstart', msg.text, event);
- }
- msg.onerror = (event) => {
- sentActionToServer(false, 'onerror', event.utterance.text, event);
- speech.playing = false;
- speechPlayer();
- }
- speechUtteranceChunker(msg, null, (result) => {
- console.log(result);
- if (result.success === true) {
- sentActionToServer(true, 'onend', msg.text, event);
- speech.playing = false;
- speechPlayer();
- } else {
- sentActionToServer(false, 'onend', msg.text, event);;
- speech.playing = false;
- speechPlayer();
- }
- });
- }
- function optionSpeech(index, volume, rate, pitch, text) {
- //speechSynthesis.cancel();
- const msg = new SpeechSynthesisUtterance();
- msg.voice = speechSynthesis.getVoices()[index];
- msg.voiceURI = 'native';
- msg.volume = volume;
- msg.rate = rate;
- msg.pitch = pitch;
- msg.lang = 'en-GB';
- msg.text = text;
- speech.utterances.push(msg);
- speechPlayer();
- }
- function sentActionToServer(success, name, msg, event) {
- if (socket) {
- if (socket.emit) {
- socket.emit('speech-synthesis', { success: success, action: name, text: msg, page: page, event: event });
- }
- }
- }
- function resetVoice() {
- speechSynthesis.cancel();
- }
- function stopTTS() {
- resetVoice();
- }
- /**
- * Chunkify
- * Google Chrome Speech Synthesis Chunking Pattern
- * Fixes inconsistencies with speaking long texts in speechUtterance objects
- * Licensed under the MIT License
- * https://gist.github.com/woollsta/2d146f13878a301b36d7#file-chunkify-js
- * Peter Woolley and Brett Zamir
- */
- const speechUtteranceChunker = (utt, settings, callback) => {
- settings = settings || {};
- let newUtt;
- const txt = (settings && settings.offset !== undefined ? utt.text.substring(settings.offset) : utt.text);
- if (utt.voice && utt.voice.voiceURI === 'native') { // Not part of the spec
- newUtt = utt;
- newUtt.text = txt;
- newUtt.addEventListener('end', (event) => {
- if (speechUtteranceChunker.cancel) {
- speechUtteranceChunker.cancel = false;
- }
- if (callback !== undefined) {
- callback({ success: false, event: event });
- }
- });
- }
- else {
- const chunkLength = (settings && settings.chunkLength) || 160;
- const pattRegex = new RegExp('^[\\s\\S]{' + Math.floor(chunkLength / 2) + ',' + chunkLength + '}[.!?,]{1}|^[\\s\\S]{1,' + chunkLength + '}$|^[\\s\\S]{1,' + chunkLength + '} ');
- const chunkArr = txt.match(pattRegex);
- if (chunkArr[0] === undefined || chunkArr[0].length <= 2) {
- //call once all text has been spoken...
- if (callback !== undefined) {
- callback({ success: true });
- }
- return;
- }
- const chunk = chunkArr[0];
- newUtt = new SpeechSynthesisUtterance(chunk);
- let x;
- for (x in utt) {
- if (utt[x] && x !== 'text') {
- newUtt[x] = utt[x];
- }
- }
- newUtt.addEventListener('end', () => {
- if (speechUtteranceChunker.cancel) {
- speechUtteranceChunker.cancel = false;
- return;
- }
- settings.offset = settings.offset || 0;
- settings.offset += chunk.length - 1;
- speechUtteranceChunker(utt, settings, callback);
- });
- }
- if (settings.modifier) {
- settings.modifier(newUtt);
- }
- console.log(newUtt); //IMPORTANT!! Do not remove: Logging the object out fixes some onend firing issues.
- //placing the speak invocation inside a callback fixes ordering and onend issues.
- setTimeout(() => {
- speechSynthesis.speak(newUtt);
- }, 0);
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement