@jambonz/speech-utils 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +5 -0
- package/lib/config.js +2 -0
- package/lib/synth-audio.js +26 -3
- package/lib/utils.js +9 -7
- package/package.json +1 -1
package/.github/workflows/ci.yml
CHANGED
|
@@ -13,6 +13,11 @@ jobs:
|
|
|
13
13
|
with:
|
|
14
14
|
node-version: lts/*
|
|
15
15
|
- run: npm install
|
|
16
|
+
- name: Install Docker Compose
|
|
17
|
+
run: |
|
|
18
|
+
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
|
19
|
+
sudo chmod +x /usr/local/bin/docker-compose
|
|
20
|
+
docker-compose --version
|
|
16
21
|
- run: npm run jslint
|
|
17
22
|
- run: sudo apt update && sudo apt install -y squid
|
|
18
23
|
- run: sudo cp test/squid.conf /etc/squid/squid.conf
|
package/lib/config.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const JAMBONES_TTS_TRIM_SILENCE = process.env.JAMBONES_TTS_TRIM_SILENCE;
|
|
2
2
|
const JAMBONES_DISABLE_TTS_STREAMING = process.env.JAMBONES_DISABLE_TTS_STREAMING;
|
|
3
3
|
const JAMBONES_DISABLE_AZURE_TTS_STREAMING = process.env.JAMBONES_DISABLE_AZURE_TTS_STREAMING;
|
|
4
|
+
const JAMBONES_EAGERLY_PRE_CACHE_AUDIO = process.env.JAMBONES_EAGERLY_PRE_CACHE_AUDIO;
|
|
4
5
|
|
|
5
6
|
const JAMBONES_HTTP_PROXY_IP = process.env.JAMBONES_HTTP_PROXY_IP;
|
|
6
7
|
const JAMBONES_HTTP_PROXY_PORT = process.env.JAMBONES_HTTP_PROXY_PORT;
|
|
@@ -18,6 +19,7 @@ module.exports = {
|
|
|
18
19
|
JAMBONES_HTTP_PROXY_IP,
|
|
19
20
|
JAMBONES_HTTP_PROXY_PORT,
|
|
20
21
|
JAMBONES_TTS_CACHE_DURATION_MINS,
|
|
22
|
+
JAMBONES_EAGERLY_PRE_CACHE_AUDIO,
|
|
21
23
|
TMP_FOLDER,
|
|
22
24
|
HTTP_TIMEOUT
|
|
23
25
|
};
|
package/lib/synth-audio.js
CHANGED
|
@@ -44,6 +44,7 @@ const {
|
|
|
44
44
|
JAMBONES_HTTP_PROXY_IP,
|
|
45
45
|
JAMBONES_HTTP_PROXY_PORT,
|
|
46
46
|
JAMBONES_TTS_CACHE_DURATION_MINS,
|
|
47
|
+
JAMBONES_EAGERLY_PRE_CACHE_AUDIO,
|
|
47
48
|
} = require('./config');
|
|
48
49
|
const EXPIRES = JAMBONES_TTS_CACHE_DURATION_MINS;
|
|
49
50
|
const OpenAI = require('openai');
|
|
@@ -86,7 +87,7 @@ const trimTrailingSilence = (buffer) => {
|
|
|
86
87
|
*/
|
|
87
88
|
async function synthAudio(client, createHash, retrieveHash, logger, stats, { account_sid,
|
|
88
89
|
vendor, language, voice, gender, text, engine, salt, model, credentials, deploymentId,
|
|
89
|
-
disableTtsCache, renderForCaching, disableTtsStreaming, options
|
|
90
|
+
disableTtsCache, renderForCaching = false, disableTtsStreaming, options
|
|
90
91
|
}) {
|
|
91
92
|
let audioBuffer;
|
|
92
93
|
let servedFromCache = false;
|
|
@@ -157,20 +158,42 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
|
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
}
|
|
161
|
+
|
|
160
162
|
const key = makeSynthKey({
|
|
161
163
|
account_sid,
|
|
162
164
|
vendor,
|
|
163
165
|
language: language || '',
|
|
164
166
|
voice: voice || deploymentId,
|
|
165
167
|
engine,
|
|
166
|
-
text
|
|
168
|
+
text,
|
|
169
|
+
renderForCaching
|
|
167
170
|
});
|
|
168
171
|
let filePath;
|
|
169
|
-
filePath = makeFilePath(vendor, key, salt);
|
|
172
|
+
filePath = makeFilePath({vendor, key, salt, renderForCaching});
|
|
170
173
|
debug(`synth key is ${key}`);
|
|
171
174
|
let cached;
|
|
172
175
|
if (!disableTtsCache) {
|
|
173
176
|
cached = await client.get(key);
|
|
177
|
+
/**
|
|
178
|
+
* If we are using tts streaming and also precaching audio, audio could have been cached by streaming (r8)
|
|
179
|
+
* or here in speech-utils due to precaching (mp3), so we need to check for both keys.
|
|
180
|
+
*/
|
|
181
|
+
if (!cached && JAMBONES_EAGERLY_PRE_CACHE_AUDIO) {
|
|
182
|
+
const preCachekey = makeSynthKey({
|
|
183
|
+
account_sid,
|
|
184
|
+
vendor,
|
|
185
|
+
language: language || '',
|
|
186
|
+
voice: voice || deploymentId,
|
|
187
|
+
engine,
|
|
188
|
+
text,
|
|
189
|
+
renderForCaching: true
|
|
190
|
+
});
|
|
191
|
+
cached = await client.get(preCachekey);
|
|
192
|
+
if (cached) {
|
|
193
|
+
// Precache audio is available update filpath with precache file extension.
|
|
194
|
+
filePath = makeFilePath({vendor, key, salt, renderForCaching: true});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
174
197
|
}
|
|
175
198
|
if (cached) {
|
|
176
199
|
// found in cache - extend the expiry and use it
|
package/lib/utils.js
CHANGED
|
@@ -16,29 +16,31 @@ const debug = require('debug')('jambonz:realtimedb-helpers');
|
|
|
16
16
|
*/
|
|
17
17
|
//const nuanceClientMap = new Map();
|
|
18
18
|
|
|
19
|
-
function makeSynthKey({
|
|
19
|
+
function makeSynthKey({
|
|
20
|
+
account_sid = '', vendor, language, voice, engine = '', text,
|
|
21
|
+
renderForCaching = false}) {
|
|
20
22
|
const hash = crypto.createHash('sha1');
|
|
21
23
|
hash.update(`${language}:${vendor}:${voice}:${engine}:${text}`);
|
|
22
24
|
const hexHashKey = hash.digest('hex');
|
|
23
25
|
const accountKey = account_sid ? `:${account_sid}` : '';
|
|
24
|
-
const namespace = vendor.startsWith('custom') ? vendor : getFileExtension(vendor);
|
|
26
|
+
const namespace = vendor.startsWith('custom') ? vendor : getFileExtension({vendor, renderForCaching});
|
|
25
27
|
const key = `tts${accountKey}:${namespace}:${hexHashKey}`;
|
|
26
28
|
return key;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
function makeFilePath(vendor, key, salt = '') {
|
|
30
|
-
const extension = getFileExtension(vendor);
|
|
31
|
+
function makeFilePath({vendor, key, salt = '', renderForCaching = false}) {
|
|
32
|
+
const extension = getFileExtension({vendor, renderForCaching});
|
|
31
33
|
return `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt}`)}.${extension}`;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
function getFileExtension(vendor) {
|
|
36
|
+
function getFileExtension({vendor, renderForCaching = false}) {
|
|
35
37
|
const mp3Extension = 'mp3';
|
|
36
38
|
const r8Extension = 'r8';
|
|
37
39
|
|
|
38
40
|
switch (vendor) {
|
|
39
41
|
case 'azure':
|
|
40
42
|
case 'microsoft':
|
|
41
|
-
if (!JAMBONES_DISABLE_TTS_STREAMING || JAMBONES_TTS_TRIM_SILENCE) {
|
|
43
|
+
if (!renderForCaching && !JAMBONES_DISABLE_TTS_STREAMING || JAMBONES_TTS_TRIM_SILENCE) {
|
|
42
44
|
return r8Extension;
|
|
43
45
|
} else {
|
|
44
46
|
return mp3Extension;
|
|
@@ -46,7 +48,7 @@ function getFileExtension(vendor) {
|
|
|
46
48
|
case 'deepgram':
|
|
47
49
|
case 'elevenlabs':
|
|
48
50
|
case 'rimlabs':
|
|
49
|
-
if (!JAMBONES_DISABLE_TTS_STREAMING) {
|
|
51
|
+
if (!renderForCaching && !JAMBONES_DISABLE_TTS_STREAMING) {
|
|
50
52
|
return r8Extension;
|
|
51
53
|
} else {
|
|
52
54
|
return mp3Extension;
|