Last active
May 27, 2020 08:03
-
-
Save aylarov/9f7bee706bad5eb83e11e2f7ecbe9370 to your computer and use it in GitHub Desktop.
Voximplant Speech Recognition demo. VoxEngine scenario and web client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Voximplant Speech Recognition Demo</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script> | |
<script type="text/javascript" src="//cdn.voximplant.com/voximplant.min.js"></script> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
<script type="text/javascript"> | |
var sdk = VoxImplant.getInstance(), call, rec_result = " "; | |
sdk.addEventListener(VoxImplant.Events.SDKReady, onSDKReady); | |
sdk.addEventListener(VoxImplant.Events.ConnectionEstablished, onConnectionEstablished); | |
sdk.addEventListener(VoxImplant.Events.ConnectionClosed, onConnectionClosed); | |
sdk.addEventListener(VoxImplant.Events.ConnectionFailed, onConnectionFailed); | |
sdk.addEventListener(VoxImplant.Events.MicAccessResult, onMicAccessResult); | |
sdk.addEventListener(VoxImplant.Events.AuthResult, onAuthResult); | |
sdk.init({ | |
micRequired: true | |
}); | |
function onSDKReady(e) { | |
console.log("Voximplant SDK ver. "+e.version+" initialized"); | |
$('div.label').html("Please allow access to your microphone"); | |
sdk.connect(); | |
} | |
function onMicAccessResult(e) { | |
if (e.result) { | |
$('div.label').html("Establishing connection..."); | |
} else { | |
$('div.label').html("You need to allow access to use this application"); | |
} | |
} | |
function onConnectionEstablished() { | |
$('div.label').html("Authorizing..."); | |
sdk.login(USERNAME, PASSWORD); | |
} | |
function onConnectionClosed() { | |
$('div.label').html("Network connection has been closed"); | |
} | |
function onConnectionFailed() { | |
$('div.label').html("Couldn't connect to Voximplant: check if UDP is allowed"); | |
} | |
function onAuthResult(e) { | |
if (e.result) { | |
$('div.label').html("Idle"); | |
$('div.preloader-wrapper').remove(); | |
$('#container').append("<a onclick='javascript:makeCall()' class='waves-effect green btn-large'><i class='material-icons left'>mic</i>Start</a>"); | |
} else { | |
$('div.label').html("Authorization error"); | |
} | |
} | |
function makeCall() { | |
$('a.btn-large').remove(); | |
$('div.label').html("Calling..."); | |
call = sdk.call("recognizer"); | |
call.addEventListener(VoxImplant.CallEvents.Connected, onCallConnected); | |
call.addEventListener(VoxImplant.CallEvents.Failed, onCallFailed); | |
call.addEventListener(VoxImplant.CallEvents.Disconnected, onCallDisconnected); | |
call.addEventListener(VoxImplant.CallEvents.MessageReceived, onMessageReceived); | |
} | |
function hangupCall() { | |
call.hangup(); | |
} | |
function onCallConnected(e) { | |
$('div.label').html("Call connected"); | |
$('#container').append("<a onclick='javascript:hangupCall()' class='waves-effect red btn-large'><i class='material-icons left'>mic_none</i>Stop</a>"); | |
} | |
function onCallFailed(e) { | |
$('div.label').html("Call error: "+e.code+" ("+e.reason+") "); | |
$('a.btn-large').remove(); | |
$('#container').append("<a onclick='javascript:makeCall()' class='waves-effect green btn-large'><i class='material-icons left'>mic</i>Start</a>"); | |
} | |
function onCallDisconnected(e) { | |
rec_result = " " | |
$('div.label').html("Idle"); | |
$('a.btn-large').remove(); | |
$('#container').append("<a onclick='javascript:makeCall()' class='waves-effect green btn-large'><i class='material-icons left'>mic</i>Start</a>"); | |
removeResultContainer(); | |
} | |
function onMessageReceived(e) { | |
try { | |
var result = JSON.parse(e.text); | |
if (result.type == "RESULT") { | |
rec_result = rec_result + " " + result.text; | |
$('div.card-panel span').html( rec_result ); | |
} | |
if (result.type == "CAPTURE_STARTED") { | |
if ( !$('div.row').length ) { | |
createResultContainer(); | |
} | |
$('div.card-panel span').html( rec_result + "<div class='loader'></div>"); | |
} | |
} catch (e) { | |
console.log(e); | |
} | |
} | |
function createResultContainer() { | |
$('#container').append("<div class='row'></div>"); | |
$('div.row').append("<div class='col'></div>"); | |
$('div.col').append("<div class='card-panel'></div>"); | |
$('div.card-panel').append("<span class='blue-text text-darken-2'></span>"); | |
} | |
function removeResultContainer() { | |
$('div.row').remove(); | |
} | |
</script> | |
<style> | |
body, html { | |
width: 100%; | |
height: 100%; | |
display: flex; | |
align-content: center; | |
} | |
#container { | |
display: flex; | |
width: 100%; | |
height: 100%; | |
align-self: center; | |
align-content: center; | |
justify-content: center; | |
flex-direction: column; | |
} | |
div.preloader-wrapper { | |
align-self: center; | |
margin: 10px; | |
} | |
div.label { | |
margin-top: 20px; | |
align-self: center; | |
} | |
a.btn-large { | |
align-self: center; | |
} | |
div.row { | |
align-self: center; | |
} | |
.loader, | |
.loader:after { | |
border-radius: 50%; | |
width: 16px; | |
height: 16px; | |
margin-left: 5px; | |
} | |
.loader { | |
display: inline-block; | |
font-size: 16px; | |
position: relative; | |
text-indent: -9999em; | |
border-top: 3px solid rgba(0, 0, 0, 0.2); | |
border-right: 3px solid rgba(0, 0, 0, 0.2); | |
border-bottom: 3px solid rgba(0, 0, 0, 0.2); | |
border-left: 3px solid #333333; | |
-webkit-transform: translateZ(0); | |
-ms-transform: translateZ(0); | |
transform: translateZ(0); | |
-webkit-animation: load8 1.1s infinite linear; | |
animation: load8 1.1s infinite linear; | |
} | |
@-webkit-keyframes load8 { | |
0% { | |
-webkit-transform: rotate(0deg); | |
transform: rotate(0deg); | |
} | |
100% { | |
-webkit-transform: rotate(360deg); | |
transform: rotate(360deg); | |
} | |
} | |
@keyframes load8 { | |
0% { | |
-webkit-transform: rotate(0deg); | |
transform: rotate(0deg); | |
} | |
100% { | |
-webkit-transform: rotate(360deg); | |
transform: rotate(360deg); | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div id="container"> | |
<div class="preloader-wrapper big active"> | |
<div class="spinner-layer spinner-blue"> | |
<div class="circle-clipper left"> | |
<div class="circle"></div> | |
</div><div class="gap-patch"> | |
<div class="circle"></div> | |
</div><div class="circle-clipper right"> | |
<div class="circle"></div> | |
</div> | |
</div> | |
<div class="spinner-layer spinner-red"> | |
<div class="circle-clipper left"> | |
<div class="circle"></div> | |
</div><div class="gap-patch"> | |
<div class="circle"></div> | |
</div><div class="circle-clipper right"> | |
<div class="circle"></div> | |
</div> | |
</div> | |
<div class="spinner-layer spinner-yellow"> | |
<div class="circle-clipper left"> | |
<div class="circle"></div> | |
</div><div class="gap-patch"> | |
<div class="circle"></div> | |
</div><div class="circle-clipper right"> | |
<div class="circle"></div> | |
</div> | |
</div> | |
<div class="spinner-layer spinner-green"> | |
<div class="circle-clipper left"> | |
<div class="circle"></div> | |
</div><div class="gap-patch"> | |
<div class="circle"></div> | |
</div><div class="circle-clipper right"> | |
<div class="circle"></div> | |
</div> | |
</div> | |
</div> | |
<div class="label">Initializing...</div> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require(Modules.ASR); | |
require(Modules.Player); | |
var mycall, | |
myasr, | |
player, | |
ts, | |
ts2, | |
vad = false; | |
VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) { | |
mycall = e.call; | |
e.call.addEventListener(CallEvents.Connected, handleCallConnected); | |
e.call.answer(); | |
}); | |
function handleCallConnected(e) { | |
mycall.handleMicStatus(true); | |
mycall.addEventListener(CallEvents.MicStatusChange, handleMicStatus); | |
mycall.addEventListener(CallEvents.Disconnected, VoxEngine.terminate); | |
myasr = VoxEngine.createASR({ | |
lang: ASRLanguage.RUSSIAN_RU | |
}); | |
myasr.addEventListener(ASREvents.CaptureStarted, function (e) { | |
clearTimeout(ts); | |
mycall.sendMessage(JSON.stringify({ | |
type: "CAPTURE_STARTED" | |
})); | |
}); | |
myasr.addEventListener(ASREvents.Result, function (e) { | |
ts = setTimeout(recognitionEnded, 5000); | |
mycall.sendMessage(JSON.stringify({ | |
type: "RESULT", | |
text: e.text, | |
confidence: e.confidence | |
})); | |
}); | |
myasr.addEventListener(ASREvents.SpeechCaptured, function (e) { | |
mycall.sendMessage(JSON.stringify({ | |
type: "SPEECH_CAPTURED" | |
})); | |
}); | |
setTimeout(function () { | |
player = VoxEngine.createTTSPlayer("Слушаю вас", Language.RU_RUSSIAN_FEMALE); | |
player.addMarker(-1000); | |
player.addEventListener(PlayerEvents.PlaybackMarkerReached, function (e) { | |
mycall.sendMediaTo(myasr); | |
}); | |
player.sendMediaTo(mycall); | |
}, 200); | |
} | |
function recognitionEnded() { | |
myasr.stop(); | |
VoxEngine.terminate(); | |
} | |
function handleMicStatus(e) { | |
if (e.active) { | |
vad = true; | |
clearTimeout(ts2); | |
mycall.sendMessage(JSON.stringify({ | |
type: "VAD", | |
status: true | |
})); | |
} else { | |
ts2 = setTimeout(function () { | |
if (!vad) { | |
myasr.stop(); | |
VoxEngine.terminate(); | |
} | |
}, 6000); | |
vad = false; | |
mycall.sendMessage(JSON.stringify({ | |
type: "VAD", | |
status: false | |
})); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment