Compare commits

...
8 Commits
Author SHA1 Message Date
Dave Horton 8f216e64d8 0.1.15 2024-08-12 09:30:09 -04:00
Dave Horton e1f4486e01 bump version 2024-08-12 09:27:12 -04:00
Dave Horton b0d6272974 Merge pull request #84 from jambonz/feat/precache_audio_with_tts_stream
support precache audio with tts stream enabled
2024-08-12 09:26:00 -04:00
Quan HL ef23b0807a add comment 2024-08-12 20:16:24 +07:00
Quan HL ab7e25243d improve on check precache 2024-08-12 20:10:43 +07:00
Quan HL bf0ea14423 install docker 2024-08-12 18:40:47 +07:00
Quan HL 305dabd84b wip 2024-08-12 18:35:48 +07:00
Quan HL b6a3fa5081 support precache audio with tts stream enabled 2024-08-12 18:29:01 +07:00
6 changed files with 45 additions and 13 deletions
+5
View File
@@ -13,6 +13,11 @@ jobs:
with: with:
node-version: lts/* node-version: lts/*
- run: npm install - run: npm install
- name: Install Docker Compose
run: |
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
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
- run: npm run jslint - run: npm run jslint
- run: sudo apt update && sudo apt install -y squid - run: sudo apt update && sudo apt install -y squid
- run: sudo cp test/squid.conf /etc/squid/squid.conf - run: sudo cp test/squid.conf /etc/squid/squid.conf
+2
View File
@@ -1,6 +1,7 @@
const JAMBONES_TTS_TRIM_SILENCE = process.env.JAMBONES_TTS_TRIM_SILENCE; const JAMBONES_TTS_TRIM_SILENCE = process.env.JAMBONES_TTS_TRIM_SILENCE;
const JAMBONES_DISABLE_TTS_STREAMING = process.env.JAMBONES_DISABLE_TTS_STREAMING; const JAMBONES_DISABLE_TTS_STREAMING = process.env.JAMBONES_DISABLE_TTS_STREAMING;
const JAMBONES_DISABLE_AZURE_TTS_STREAMING = process.env.JAMBONES_DISABLE_AZURE_TTS_STREAMING; const JAMBONES_DISABLE_AZURE_TTS_STREAMING = process.env.JAMBONES_DISABLE_AZURE_TTS_STREAMING;
const JAMBONES_EAGERLY_PRE_CACHE_AUDIO = process.env.JAMBONES_EAGERLY_PRE_CACHE_AUDIO;
const JAMBONES_HTTP_PROXY_IP = process.env.JAMBONES_HTTP_PROXY_IP; const JAMBONES_HTTP_PROXY_IP = process.env.JAMBONES_HTTP_PROXY_IP;
const JAMBONES_HTTP_PROXY_PORT = process.env.JAMBONES_HTTP_PROXY_PORT; const JAMBONES_HTTP_PROXY_PORT = process.env.JAMBONES_HTTP_PROXY_PORT;
@@ -18,6 +19,7 @@ module.exports = {
JAMBONES_HTTP_PROXY_IP, JAMBONES_HTTP_PROXY_IP,
JAMBONES_HTTP_PROXY_PORT, JAMBONES_HTTP_PROXY_PORT,
JAMBONES_TTS_CACHE_DURATION_MINS, JAMBONES_TTS_CACHE_DURATION_MINS,
JAMBONES_EAGERLY_PRE_CACHE_AUDIO,
TMP_FOLDER, TMP_FOLDER,
HTTP_TIMEOUT HTTP_TIMEOUT
}; };
+26 -3
View File
@@ -44,6 +44,7 @@ const {
JAMBONES_HTTP_PROXY_IP, JAMBONES_HTTP_PROXY_IP,
JAMBONES_HTTP_PROXY_PORT, JAMBONES_HTTP_PROXY_PORT,
JAMBONES_TTS_CACHE_DURATION_MINS, JAMBONES_TTS_CACHE_DURATION_MINS,
JAMBONES_EAGERLY_PRE_CACHE_AUDIO,
} = require('./config'); } = require('./config');
const EXPIRES = JAMBONES_TTS_CACHE_DURATION_MINS; const EXPIRES = JAMBONES_TTS_CACHE_DURATION_MINS;
const OpenAI = require('openai'); const OpenAI = require('openai');
@@ -86,7 +87,7 @@ const trimTrailingSilence = (buffer) => {
*/ */
async function synthAudio(client, createHash, retrieveHash, logger, stats, { account_sid, async function synthAudio(client, createHash, retrieveHash, logger, stats, { account_sid,
vendor, language, voice, gender, text, engine, salt, model, credentials, deploymentId, vendor, language, voice, gender, text, engine, salt, model, credentials, deploymentId,
disableTtsCache, renderForCaching, disableTtsStreaming, options disableTtsCache, renderForCaching = false, disableTtsStreaming, options
}) { }) {
let audioBuffer; let audioBuffer;
let servedFromCache = false; let servedFromCache = false;
@@ -157,20 +158,42 @@ async function synthAudio(client, createHash, retrieveHash, logger, stats, { acc
} }
} }
const key = makeSynthKey({ const key = makeSynthKey({
account_sid, account_sid,
vendor, vendor,
language: language || '', language: language || '',
voice: voice || deploymentId, voice: voice || deploymentId,
engine, engine,
text text,
renderForCaching
}); });
let filePath; let filePath;
filePath = makeFilePath(vendor, key, salt); filePath = makeFilePath({vendor, key, salt, renderForCaching});
debug(`synth key is ${key}`); debug(`synth key is ${key}`);
let cached; let cached;
if (!disableTtsCache) { if (!disableTtsCache) {
cached = await client.get(key); cached = await client.get(key);
/**
* If we are using tts streaming and also precaching audio, audio could have been cached by streaming (r8)
* or here in speech-utils due to precaching (mp3), so we need to check for both keys.
*/
if (!cached && JAMBONES_EAGERLY_PRE_CACHE_AUDIO) {
const preCachekey = makeSynthKey({
account_sid,
vendor,
language: language || '',
voice: voice || deploymentId,
engine,
text,
renderForCaching: true
});
cached = await client.get(preCachekey);
if (cached) {
// Precache audio is available update filpath with precache file extension.
filePath = makeFilePath({vendor, key, salt, renderForCaching: true});
}
}
} }
if (cached) { if (cached) {
// found in cache - extend the expiry and use it // found in cache - extend the expiry and use it
+9 -7
View File
@@ -16,29 +16,31 @@ const debug = require('debug')('jambonz:realtimedb-helpers');
*/ */
//const nuanceClientMap = new Map(); //const nuanceClientMap = new Map();
function makeSynthKey({account_sid = '', vendor, language, voice, engine = '', text}) { function makeSynthKey({
account_sid = '', vendor, language, voice, engine = '', text,
renderForCaching = false}) {
const hash = crypto.createHash('sha1'); const hash = crypto.createHash('sha1');
hash.update(`${language}:${vendor}:${voice}:${engine}:${text}`); hash.update(`${language}:${vendor}:${voice}:${engine}:${text}`);
const hexHashKey = hash.digest('hex'); const hexHashKey = hash.digest('hex');
const accountKey = account_sid ? `:${account_sid}` : ''; const accountKey = account_sid ? `:${account_sid}` : '';
const namespace = vendor.startsWith('custom') ? vendor : getFileExtension(vendor); const namespace = vendor.startsWith('custom') ? vendor : getFileExtension({vendor, renderForCaching});
const key = `tts${accountKey}:${namespace}:${hexHashKey}`; const key = `tts${accountKey}:${namespace}:${hexHashKey}`;
return key; return key;
} }
function makeFilePath(vendor, key, salt = '') { function makeFilePath({vendor, key, salt = '', renderForCaching = false}) {
const extension = getFileExtension(vendor); const extension = getFileExtension({vendor, renderForCaching});
return `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt}`)}.${extension}`; return `${TMP_FOLDER}/${key.replace('tts:', `tts-${salt}`)}.${extension}`;
} }
function getFileExtension(vendor) { function getFileExtension({vendor, renderForCaching = false}) {
const mp3Extension = 'mp3'; const mp3Extension = 'mp3';
const r8Extension = 'r8'; const r8Extension = 'r8';
switch (vendor) { switch (vendor) {
case 'azure': case 'azure':
case 'microsoft': case 'microsoft':
if (!JAMBONES_DISABLE_TTS_STREAMING || JAMBONES_TTS_TRIM_SILENCE) { if (!renderForCaching && !JAMBONES_DISABLE_TTS_STREAMING || JAMBONES_TTS_TRIM_SILENCE) {
return r8Extension; return r8Extension;
} else { } else {
return mp3Extension; return mp3Extension;
@@ -46,7 +48,7 @@ function getFileExtension(vendor) {
case 'deepgram': case 'deepgram':
case 'elevenlabs': case 'elevenlabs':
case 'rimlabs': case 'rimlabs':
if (!JAMBONES_DISABLE_TTS_STREAMING) { if (!renderForCaching && !JAMBONES_DISABLE_TTS_STREAMING) {
return r8Extension; return r8Extension;
} else { } else {
return mp3Extension; return mp3Extension;
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "@jambonz/speech-utils", "name": "@jambonz/speech-utils",
"version": "0.1.13", "version": "0.1.15",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@jambonz/speech-utils", "name": "@jambonz/speech-utils",
"version": "0.1.13", "version": "0.1.15",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@aws-sdk/client-polly": "^3.496.0", "@aws-sdk/client-polly": "^3.496.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@jambonz/speech-utils", "name": "@jambonz/speech-utils",
"version": "0.1.13", "version": "0.1.15",
"description": "TTS-related speech utilities for jambonz", "description": "TTS-related speech utilities for jambonz",
"main": "index.js", "main": "index.js",
"author": "Dave Horton", "author": "Dave Horton",