augnitorecorder
Advanced tools
Comparing version 1.0.14 to 1.0.15
@@ -386,6 +386,2 @@ function _regeneratorRuntime() { | ||
function createWorkerScript(DONE_MSG, eosMessage, CONNECT_RETRY_TIMEOUT, CONSUME_INTERVAL, HEALTHCHECK_INTERVAL, socketTimeoutInterval, wsUrl, heavyOp, enableLogs) { | ||
return "\n const DONE_MSG = \"".concat(DONE_MSG, "\";\n const EOS_MSG = \"").concat(eosMessage, "\";\n const CONNECT_RETRY_TIMEOUT = ").concat(CONNECT_RETRY_TIMEOUT, ";\n const CONSUME_INTERVAL = ").concat(CONSUME_INTERVAL, ";\n const HEALTHCHECK_INTERVAL = ").concat(HEALTHCHECK_INTERVAL, ";\n const SOCKET_TIMEOUT = ").concat(socketTimeoutInterval, ";\n const wsUrl = \"").concat(wsUrl, "\";\n const heavyOp = ").concat(heavyOp === null || heavyOp === void 0 ? void 0 : heavyOp.toString(), ";\n const enableLogs = ").concat(enableLogs, ";\n\n let lastConnect;\n let lastDataSent;\n let lastDataReceived;\n const queue = [];\n let ws;\n let isDone = false;\n let JobID = \"\";\n\n initConnect();\n\n self.onmessage = handleMessage;\n\n function handleMessage(event) {\n if (event.data === DONE_MSG) {\n console.log(\"called EOS\",EOS_MSG)\n add(EOS_MSG);\n JobID = \"\";\n if (enableLogs) {\n console.log(\"Worker received DONE, time to terminate...\");\n }\n isDone = true;\n } else {\n add(event.data);\n }\n }\n\n function initConnect() {\n lastConnect = +new Date();\n ws = JobID ? new WebSocket(wsUrl + \"&jobid=\" + JobID) : new WebSocket(wsUrl);\n\n ws.onopen = handleOpen;\n ws.onmessage = handleMessageFromServer;\n ws.onerror = handleError;\n ws.onclose = handleClose;\n\n lastDataSent = +new Date();\n lastDataReceived = lastDataSent;\n }\n\n function handleOpen(event) {\n if (enableLogs) {\n console.log(\"WebSocket connection established: \" + JSON.stringify(event));\n }\n }\n\n function handleMessageFromServer(message) {\n if (enableLogs) {\n console.log(\"Message from server: \" + JSON.stringify(message.data));\n }\n lastDataReceived = +new Date();\n operate(message);\n }\n\n function handleError(error) {\n self.postMessage({ type: \"error\", data: error.toString() });\n }\n\n function handleClose(event) {\n if (enableLogs) {\n console.log(\"WebSocket connection closed: \" + JSON.stringify(event));\n }\n cleanup();\n }\n\n const consumer = setInterval(() => {\n while (queue.length > 0) {\n const data = queue.shift();\n const isSent = send(data);\n if (!isSent) {\n queue.unshift(data);\n break;\n }\n }\n }, CONSUME_INTERVAL);\n\n function send(data) {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.send(data);\n const currentTime = +new Date();\n if (lastDataSent <= lastDataReceived) {\n lastDataReceived = currentTime - 1;\n }\n lastDataSent = currentTime;\n return true;\n } else {\n if (data === EOS_MSG) {\n if (enableLogs) {\n console.warn(`Gulping ${EOS_MSG} as socket seems already closed...`);\n }\n cleanup();\n return true;\n }\n if (+new Date() - lastConnect > CONNECT_RETRY_TIMEOUT) {\n initConnect();\n }\n return false;\n }\n }\n\n function add(data) {\n queue.push(data);\n }\n\n function operate(message) {\n try {\n const data = JSON.parse(message.data);\n if (enableLogs) {\n console.log(\"[WORKER]: \" + JSON.stringify(data));\n }\n if (data.Type == \"meta\") {\n if (data.JobID) {\n JobID = data.JobID;\n console.log(\"JobID:\", JobID);\n }\n self.postMessage({ type: \"meta\", data: message.data });\n } else if (data.Result && data.Result.Final) {\n var outputText = JSON.stringify(data.Result);\n if (heavyOp) {\n outputText = heavyOp(JSON.stringify(data.Result));\n console.log(outputText);\n }\n self.postMessage({ type: \"final\", data: outputText });\n } else if (data.Result && !data.Result.Final) {\n self.postMessage({ type: \"partial\", data: data.Result.Transcript });\n } else if (data.Type == \"ACK\") {\n self.postMessage({ type: \"other\", data: message.data });\n }\n } catch (e) {\n self.postMessage({ type: \"error\", data: \"invalid response\" });\n }\n }\n\n const healthCheck = setInterval(() => {\n if (ws && ws.readyState === WebSocket.OPEN) {\n const currentTime = +new Date();\n if (lastDataSent > lastDataReceived && currentTime - lastDataReceived > SOCKET_TIMEOUT) {\n if (enableLogs) {\n console.error(`No data received since more than ${SOCKET_TIMEOUT / 1000} secs, closing time...`);\n }\n ws.close();\n }\n }\n }, HEALTHCHECK_INTERVAL);\n\n function cleanup() {\n if (isDone) {\n clearInterval(consumer);\n clearInterval(healthCheck);\n self.close();\n }\n }\n "); | ||
} | ||
var Executor = /*#__PURE__*/function () { | ||
@@ -414,7 +410,15 @@ function Executor(wsUrl, enableLogs, eosMessage, socketTimeoutInterval, onFinalResult, onPartialResult, onError, onSessionEvent, onOtherResults) { | ||
var _this = this; | ||
var workerScript = createWorkerScript(DONE_MSG, this.eosMessage, CONNECT_RETRY_TIMEOUT, CONSUME_INTERVAL, HEALTHCHECK_INTERVAL, this.socketTimeoutInterval, this.wsUrl, this.heavyOp, this.enableLogs); | ||
var blob = new Blob([workerScript], { | ||
type: "text/javascript" | ||
}); | ||
this.worker = new Worker(URL.createObjectURL(blob)); | ||
var arg1 = DONE_MSG; | ||
var arg2 = this.eosMessage; | ||
var arg3 = CONNECT_RETRY_TIMEOUT; | ||
var arg4 = this.socketTimeoutInterval; | ||
var arg5 = HEALTHCHECK_INTERVAL; | ||
var arg6 = CONSUME_INTERVAL; | ||
var arg7 = this.wsUrl; | ||
var arg8 = this.enableLogs; | ||
var arg9 = this.heavyOp; | ||
var workerScript = "\n (() => {\n (".concat(WorkerBlob.toString(), ")(").concat(JSON.stringify(arg1), ", ").concat(JSON.stringify(arg2), ", ").concat(JSON.stringify(arg3), ", ").concat(JSON.stringify(arg4), ", ").concat(JSON.stringify(arg5), ", ").concat(JSON.stringify(arg6), ", ").concat(JSON.stringify(arg7), ", ").concat(JSON.stringify(arg8), ", ").concat(JSON.stringify(arg9), ");\n })();\n"); | ||
this.worker = new Worker(URL.createObjectURL(new Blob([workerScript], { | ||
type: "application/javascript" | ||
}))); | ||
// message received from web-worker | ||
@@ -448,21 +452,14 @@ this.worker.onmessage = function (event) { | ||
if (data === DONE_MSG) { | ||
var _this$worker; | ||
// message sent to web-worker | ||
this.worker.postMessage(DONE_MSG); | ||
(_this$worker = this.worker) === null || _this$worker === void 0 || _this$worker.postMessage(DONE_MSG); | ||
clearInterval(this.idleLoop); | ||
} else { | ||
var _this$worker2; | ||
// message sent to web-worker - transferrable | ||
this.worker.postMessage(data, [data]); | ||
console.log("message sent to worker"); | ||
(_this$worker2 = this.worker) === null || _this$worker2 === void 0 || _this$worker2.postMessage(data, [data]); | ||
} | ||
} | ||
// worker-thread | ||
}, { | ||
key: "process", | ||
value: function process() {} | ||
// log(event) { | ||
// const data = `${new Date().toLocaleTimeString()}: ${event}`; | ||
// console.log(data + "\n"); | ||
// } | ||
}, { | ||
key: "HeavyOp", | ||
@@ -474,3 +471,159 @@ set: function set(heavyOp) { | ||
}(); | ||
function WorkerBlob(doneMessage, eosMessage, connectionRetryTimeout, socketTimeoutInterval, healthcheckInterval, consumeInterval, wsUrl, enableLogs, heavyOp) { | ||
var lastConnect; | ||
var lastDataSent; | ||
var lastDataReceived; | ||
var queue = []; | ||
var ws; | ||
var isDone = false; | ||
var consumer; | ||
var healthCheck; | ||
function initConnect() { | ||
lastConnect = +new Date(); | ||
ws = new WebSocket(wsUrl); | ||
ws.onopen = function (event) { | ||
if (enableLogs) { | ||
console.log("WebSocket connection established: " + JSON.stringify(event)); | ||
} | ||
}; | ||
ws.onmessage = function (message) { | ||
if (enableLogs) { | ||
console.log("Message from server: " + JSON.stringify(message.data)); | ||
} | ||
lastDataReceived = +new Date(); | ||
operate(message); | ||
}; | ||
ws.onerror = function (error) { | ||
console.error("WebSocket error: ", error); | ||
self.postMessage({ | ||
type: "error", | ||
data: JSON.stringify(error) | ||
}); | ||
// TODO may want to reinitialise | ||
}; | ||
ws.onclose = function (event) { | ||
if (enableLogs) { | ||
console.log("WebSocket connection closed: " + JSON.stringify(event)); | ||
} | ||
cleanup(); | ||
}; | ||
lastDataSent = +new Date(); | ||
lastDataReceived = lastDataSent; | ||
} | ||
// TODO lose the interval and try reading from queue on-add and on-open. | ||
function send(data) { | ||
if (ws && ws.readyState === WebSocket.OPEN) { | ||
ws.send(data); | ||
// This needs to be done to keep the "lastDataReceived" value closer to the | ||
// first "lastDataSent" value after ASR is received from the server, so as to | ||
// not invoke the healthcheck loop and force close the connection. | ||
var currentTime = +new Date(); | ||
if (lastDataSent <= lastDataReceived) { | ||
lastDataReceived = currentTime - 1; | ||
} | ||
lastDataSent = currentTime; | ||
return true; | ||
} else { | ||
if (data === eosMessage) { | ||
if (enableLogs) { | ||
console.warn("Gulping ".concat(eosMessage, " as socket seems already closed...")); | ||
} | ||
cleanup(); | ||
return true; | ||
} | ||
// console.error("WebSocket connection is not open..."); | ||
if (+new Date() - lastConnect > connectionRetryTimeout) { | ||
// log("...time to reconnect."); | ||
initConnect(); | ||
} | ||
return false; | ||
} | ||
} | ||
function add(data) { | ||
queue.push(data); | ||
} | ||
function operate(message) { | ||
try { | ||
var data = JSON.parse(message.data); | ||
if (enableLogs) { | ||
console.log("[WORKER]: " + JSON.stringify(data)); | ||
} | ||
if (data.Type == "meta") { | ||
self.postMessage({ | ||
type: "meta", | ||
data: message.data | ||
}); | ||
} else if (data.Result && data.Result.Final) { | ||
// should not be called with "this", check worker construction for more info. | ||
var outputText = JSON.stringify(data.Result); | ||
if (heavyOp) { | ||
outputText = heavyOp(JSON.stringify(data.Result)); | ||
console.log(outputText); | ||
} | ||
self.postMessage({ | ||
type: "final", | ||
data: outputText | ||
}); | ||
// message sent to main-thread | ||
} else if (data.Result && !data.Result.Final) { | ||
self.postMessage({ | ||
type: "partial", | ||
data: data.Result.Transcript | ||
}); | ||
} else if (data.Type == "ACK") { | ||
self.postMessage({ | ||
type: "other", | ||
data: message.data | ||
}); | ||
} | ||
} catch (e) { | ||
self.postMessage({ | ||
type: "error", | ||
data: "invalid response" | ||
}); | ||
} | ||
} | ||
function cleanup() { | ||
if (isDone) { | ||
clearInterval(consumer); | ||
clearInterval(healthCheck); | ||
self.close(); | ||
} | ||
} | ||
initConnect(); | ||
consumer = setInterval(function () { | ||
while (queue.length > 0) { | ||
var data = queue.shift(); | ||
var isSent = send(data); | ||
if (!isSent) { | ||
queue.unshift(data); | ||
break; | ||
} | ||
} | ||
}, consumeInterval); | ||
healthCheck = setInterval(function () { | ||
if (ws && ws.readyState === WebSocket.OPEN) { | ||
var currentTime = +new Date(); | ||
if (lastDataSent > lastDataReceived && currentTime - lastDataReceived > socketTimeoutInterval) { | ||
if (enableLogs) { | ||
console.error("No data received since more than ".concat(socketTimeoutInterval / 1000, " secs, closing time...")); | ||
} | ||
ws.close(); | ||
} | ||
} | ||
}, healthcheckInterval); | ||
self.onmessage = function (event) { | ||
if (event.data === doneMessage) { | ||
add(eosMessage); | ||
if (enableLogs) { | ||
console.log("Worker received DONE, time to terminate..."); | ||
} | ||
isDone = true; | ||
} else add(event.data); | ||
}; | ||
} | ||
// worklet-thread | ||
@@ -477,0 +630,0 @@ var worklet = "class MyAudioWorkletProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.accumulator = [];\n this.reset();\n this.isProcessing = true;\n // message received from main-thread\n this.port.onmessage = (e) => {\n console.log(\"Worklet received event: \", e.data);\n if (this.sampleSize > 0) {\n this.accumulator.push(this.sampleVal / this.sampleSize);\n }\n if (e.data == \"PAUSE\") {\n // append silence to get last word ASR.\n const silenceSize = 16000 * 2;\n for (let i = 0; i < silenceSize; i++) {\n this.accumulator.push(0);\n }\n }\n this.send();\n if (e.data == \"STOP\") {\n // message sent to main-thread\n this.port.postMessage(\"DONE\");\n this.isProcessing = false;\n }\n };\n }\n\n static get parameterDescriptors() {\n return [\n {\n name: \"scale\",\n defaultValue: 1,\n minValue: 1,\n maxValue: 6,\n },\n {\n name: \"bufferSizeInterval\",\n defaultValue: 1,\n minValue: 1,\n maxValue: 100,\n },\n ];\n }\n\n // 128 frames\n process(inputList, outputList, params) {\n const input = inputList[0];\n if (input && input.length && input[0].length) {\n const output = outputList[0];\n const scale = params.scale[0];\n const bufferSizeInterval = params[\"bufferSizeInterval\"][0];\n console.log(\"BufferSizeInterval\", bufferSizeInterval);\n // Jackpot\n input[0].forEach((float32Element) => {\n const int16Element = Math.min(1, Math.max(-1, float32Element)) * 0x7fff;\n this.sampleVal += int16Element;\n this.sampleSize++;\n if (this.sampleSize == scale) {\n this.accumulator.push(this.sampleVal / this.sampleSize);\n this.reset();\n }\n\n // Comment this when streaming microphone audio\n // output[0][index] = float32Element;\n });\n if (this.accumulator.length >= 125 * 128 * bufferSizeInterval) {\n this.send();\n }\n }\n return this.isProcessing;\n }\n\n send() {\n if (this.accumulator.length == 0) return;\n const audioData = new Int16Array(this.accumulator);\n // message sent to main-thread - transferrable\n this.port.postMessage(audioData.buffer, [audioData.buffer]);\n this.accumulator = [];\n this.reset();\n }\n\n reset() {\n this.sampleVal = 0;\n this.sampleSize = 0;\n }\n}\n\nregisterProcessor(\"worklet-processor\", MyAudioWorkletProcessor);"; |
{ | ||
"name": "augnitorecorder", | ||
"version": "1.0.14", | ||
"version": "1.0.15", | ||
"description": "Audio recorder and streamer compatible with any browser", | ||
@@ -5,0 +5,0 @@ "main": "dist/augnitoRecorder.js", |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112144
6
1289