Creating a Speech to Text ‘Server’ on MacOS 10.12
All credit goes to @daveyjones for his code and help. I just made the tutorial. I use the Focusrite Scarlett 2i2 USB Audio Interface for the connection from the Aux line out of the chapel to the MacBook Pro.
SERVER-
Get an IBM Dev Account - Standard –
https://console.bluemix.net/catalog/ser ... ch-to-text
In Terminal install Homebrew -
Code: Select all
usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Install node and npm2 via homebrew -
Install the ‘mic module’ on MacOS using
or Linux
Using the following directory scheme, create the following:
/usr/local/bin/
|----public
|----|+-- index.html
|----|+-- server.js
|----|+-- package.json
|----|---- scripts
|----|----+-- main.js
|----|---- styles
|----|----+-- main.css
Create the text file named ‘Server.js’
[Note: you will need to use YOUR username and password from IBM’s dev center below]
Code: Select all
var app = require("express")();
var events = require("events");
var server = require("http").Server(app);
var mic = require("mic");
var os = require("os");
var io = require("socket.io")(server);
var watson = require("watson-developer-cloud/speech-to-text/v1");
var wav = require("wav");
events.EventEmitter.prototype._maxListeners = 100;
//====================================================================================================
// Watson
//====================================================================================================
var speechToText = new watson({
url: "https://stream.watsonplatform.net/speech-to-text/api",
username: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
password: "xxxxxxxx"
});
var micInstance = mic({rate: "44100", channels: "1", debug: false});
var micInputStream = micInstance.getAudioStream();
var wavStream = new wav.Writer({sampleRate: 44100, channels: 1});
var recognizeStream = speechToText.recognizeUsingWebSocket({
content_type: "audio/wav",
//customization_id: "##########",
interim_results: true,
objectMode: true,
inactivity_timeout: 3600
});
var cleanTranscript = (data) => {
transcript = data.results[0].alternatives[0].transcript;
// Remove hesitation indicators
transcript = transcript.replace(/\s*\%HESITATION\s*/g, " ");
// Remove supposed profanity
transcript = transcript.replace(/\*/g, "");
// Remove extra spaces
transcript = transcript.replace(/ +/g, " ").trim();
// Return the cleaned transcript
return transcript;
}
micInputStream.pipe(wavStream);
wavStream.pipe(recognizeStream);
micInstance.start();
//====================================================================================================
// Server
//====================================================================================================
app.get("/", function (req, res) {
res.sendFile(__dirname + "/public/index.html");
});
app.get("/scripts/main.js", function (req, res) {
res.sendFile(__dirname + "/public/scripts/main.js");
});
app.get("/styles/main.css", function (req, res) {
res.sendFile(__dirname + "/public/styles/main.css");
});
io.on("connection", function (socket) {
recognizeStream.on("data", function(data) {
var transcript = cleanTranscript(data);
if (transcript.length > 0) {
socket.emit("data", {
final: data.results[0].final,
transcript: cleanTranscript(data)
});
}
});
});
server.listen(8000);
Create the text file called package.json
Code: Select all
{ "name": "local-server",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.16.3",
"mic": "^2.1.2",
"socket.io": "^2.1.1",
"watson-developer-cloud": "^3.5.0",
"wav": "^1.0.2"
}
}
Create file called index.html
Code: Select all
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>LDS Captions</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Libre+Baskerville">
<link rel="stylesheet" href="/styles/main.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/scripts/main.js?v=2"></script>
</head>
<body>
<div id="content">
<span id="t0"></span>
</div>
</body>
</html>
Create a folder ‘scripts’ and text file called main.js
[Note: change ‘localhost’ with the IP of the server]
Code: Select all
var socket = io("http://localhost:8000");
var i = 0;
socket.on("data", function (data) {
$("#t" + i).text(data.transcript);
if (data.final) {
var words = $("#t" + i).text().split(" ");
if (words.length < 2) {
$("#t" + i).prev(".dot").remove();
$("#t" + i).remove();
}
i++;
$("#content").append(` <span class="dot">•</span> <span id="t${i}"></span>`);
}
});
setInterval(function() {
$("#content").scrollTop($("#content").scrollTop() + 1);
}, 10);
Create a folder 'styles’ and text file called main.css
Code: Select all
body {
background: black;
}
#content {
position: fixed;
top: 48px;
right: 48px;
bottom: 48px;
left: 48px;
line-height: 1.75em;
font-family: "Libre Baskerville";
font-size: 48px;
color: white;
overflow: hidden;
}
.dot {
font-size: 48px;
opacity: 0.4;
}
.dot:first-child {
display: none;
}
Now to change the default location of apache’s Document Root Directory location from /Library/WebServer/Documents to our new location of /usr/local/bin/public
Open Terminal and type
and press enter.
Press Ctrl+W which will bring up a search.
Search for /Library/WebServer/Documents and press enter.
Change the two (2) instances of /Library/WebServer/Documents to /usr/local/bin/public
Press Ctrl+O followed by Enter to save the change you just made.
Press Ctrl+X to exit nano.
Type
and press enter.
Type
and press enter.
Type
and press enter. [This installs all dependencies for the server.js]
Let’s test by running node server.js
Type
and press enter.
On the server go to
http://localhost (Note: you may need to enter the full IP of the machine.)
You should see a black screen and if you talk, you should get speech to text!
If all works out, lets run the server.js in pm2 so if it crashes the pm2 app will restart it automatically and keep it up and running.
Type
and press enter.
CLIENT-
Open a web browser and go to the
http://IPofServer:8000