-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
193 lines (177 loc) · 5.52 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
"use strict";
const credentials = require("./credentials");
const fs = require("fs");
const express = require("express");
const OpenTok = require("opentok");
const sdk = require("microsoft-cognitiveservices-speech-sdk");
const app = express();
app.use(express.json());
const port = 8080;
const path = require("path");
const expressWs = require("express-ws")(app);
app.use(express.static("static"));
const apiKey = credentials.VONAGE_API_KEY;
const apiSecret = credentials.VONAGE_API_SECRET;
const subscriptionKey = credentials.AZURE_SUBSCRIPTION_KEY;
const serviceRegion = credentials.AZURE_SERVICE_REGION;
const websocketURI = `wss://${credentials.APP_DOMAIN}`;
const defaultTargetLanguage = credentials.DEFAULT_TARGET_LANGUAGE;
const targetLanguagesToAdd = new Set();
targetLanguagesToAdd.add(defaultTargetLanguage);
// Verify that the credentials are defined
if (
!apiKey ||
!apiSecret ||
!subscriptionKey ||
!serviceRegion ||
!websocketURI ||
!defaultTargetLanguage
) {
console.log("You must specify all values in credentials.js");
process.exit(1);
}
const opentok = new OpenTok(apiKey, apiSecret);
// Create a session and store session ID in the express app
const sessionOptions = {
mediaMode: "routed",
};
opentok.createSession(sessionOptions, (err, session) => {
if (err) throw err;
app.set("sessionId", session.sessionId);
// We will wait on starting the app until this is done
init();
});
app.get("/", (req, res) => {
res.sendFile(path.resolve("pages/index.html"));
});
app.get("/session", async (req, res) => {
console.log("/session");
const sessionId = app.get("sessionId");
const token = opentok.generateToken(sessionId);
res.setHeader("Content-Type", "application/json");
res.send({
apiKey,
sessionId,
token,
});
});
app.post("/connect", async (req, res) => {
console.log("/connect");
const sessionId = app.get("sessionId");
const token = opentok.generateToken(sessionId);
const { streamId, connectionId, speaker, spoken } = req.body;
console.log({ streamId, connectionId, speaker, spoken });
opentok.websocketConnect(
sessionId,
token,
`${websocketURI}/socket/${connectionId}/${speaker.replaceAll(
" ",
"_"
)}/${spoken}`,
{ streams: [streamId] },
function (error, socket) {
if (error) {
console.log("Error:", error.message);
res.setHeader("Content-Type", "application/json");
res.send({ error: error.message });
} else {
console.log("Audio Connector WebSocket connected: ", socket);
res.setHeader("Content-Type", "application/json");
res.send({
socket,
});
}
}
);
});
app.get("/disconnect/:connectionId", (req, res) => {
console.log("/disconnect: ", req.params.connectionId);
const sessionId = app.get("sessionId");
opentok.forceDisconnect(sessionId, req.params.connectionId, (error) => {
if (error) {
console.log("Error:", error.message);
res.setHeader("Content-Type", "application/json");
res.send({ error: error.message });
} else {
res.setHeader("Content-Type", "application/json");
res.send({
status: `connection ${req.params.connectionId} disconnected`,
});
}
});
});
app.post("/translate", (req, res) => {
console.log("/translate");
targetLanguagesToAdd.add(req.body.target);
res.setHeader("Content-Type", "application/json");
res.send({
status: "started",
});
});
app.ws("/socket/:connectionId/:speaker/:spoken", (ws, req) => {
const sessionId = app.get("sessionId");
const speechTranslationConfig = sdk.SpeechTranslationConfig.fromSubscription(
subscriptionKey,
serviceRegion
);
speechTranslationConfig.speechRecognitionLanguage = req.params.spoken;
speechTranslationConfig.addTargetLanguage(defaultTargetLanguage);
const pushStream = sdk.AudioInputStream.createPushStream();
const audioConfig = sdk.AudioConfig.fromStreamInput(pushStream);
const recognizer = new sdk.TranslationRecognizer(
speechTranslationConfig,
audioConfig
);
recognizer.recognized = function (s, e) {
console.log("recognized connectionId: ", req.params.connectionId);
// Note: Can not get all translations at once: https://learn.microsoft.com/en-us/azure/ai-services/speech-service/how-to-translate-speech?tabs=terminal&pivots=programming-language-javascript#choose-one-or-more-target-languages
targetLanguagesToAdd.forEach((lang) => {
recognizer.addTargetLanguage(lang);
});
let translations = {};
recognizer.targetLanguages.forEach((lang) => {
translations[lang] = e.result.translations.get(lang);
});
console.log("translations: ", translations);
opentok.signal(
sessionId,
null,
{
type: "translation",
data: JSON.stringify({
speaker: req.params.speaker,
translations,
}),
},
function (error) {
if (error) return console.log("error:", error);
}
);
};
recognizer.startContinuousRecognitionAsync(
function (result) {
console.log("result: ", result);
},
function (err) {
console.log("err: ", err);
recognizer.close();
recognizer = undefined;
}
);
ws.on("message", (msg) => {
try {
const msgJSON = JSON.parse(msg);
console.log(
`/socket/${req.params.connectionId}/${req.params.speaker}/${req.params.spoken}: `,
msgJSON
);
} catch (err) {
pushStream.write(msg);
}
});
});
function init() {
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
}