Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support tts cartesia #370

Merged
merged 5 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions db/reset_admin_password.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ const sqlInsert = `INSERT into users
(user_sid, name, email, hashed_password, force_change, provider, email_validated)
values (?, ?, ?, ?, ?, ?, ?)
`;
const sqlInsertAdminToken = `INSERT into api_keys
(api_key_sid, token)
values (?, ?)`;
const sqlQueryAccount = 'SELECT * from accounts LEFT JOIN api_keys ON api_keys.account_sid = accounts.account_sid';
const sqlAddAccountToken = `INSERT into api_keys (api_key_sid, token, account_sid)
VALUES (?, ?, ?)`;

const sqlInsertPermissions = `
INSERT into user_permissions (user_permissions_sid, user_sid, permission_sid)
VALUES (?,?,?)`;
Expand All @@ -36,23 +31,13 @@ const doIt = async() => {
1
]
);
await promisePool.execute(sqlInsertAdminToken, [uuidv4(), uuidv4()]);

/* assign all permissions to the admin user */
const [p] = await promisePool.query('SELECT * from permissions');
for (const perm of p) {
await promisePool.execute(sqlInsertPermissions, [uuidv4(), sid, perm.permission_sid]);
}

/* create admin token for single account */
const [r] = await promisePool.query({sql: sqlQueryAccount, nestTables: true});
if (1 === r.length && r[0].api_keys.api_key_sid === null) {
const api_key_sid = uuidv4();
const token = uuidv4();
const {account_sid} = r[0].accounts;
await promisePool.execute(sqlAddAccountToken, [api_key_sid, token, account_sid]);
}

process.exit(0);
};

Expand Down
25 changes: 24 additions & 1 deletion lib/routes/api/speech-credentials.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const {decryptCredential, testWhisper, testDeepgramTTS,
testRimelabs,
testVerbioTts,
testVerbioStt,
testSpeechmaticsStt} = require('../../utils/speech-utils');
testSpeechmaticsStt,
testCartesia} = require('../../utils/speech-utils');
const {DbErrorUnprocessableRequest, DbErrorForbidden, DbErrorBadRequest} = require('../../utils/errors');
const {
testGoogleTts,
Expand Down Expand Up @@ -251,6 +252,12 @@ const encryptCredential = (obj) => {
const playhtData = JSON.stringify({api_key, user_id, voice_engine, options});
return encrypt(playhtData);

case 'cartesia':
assert(api_key, 'invalid cartesia speech credential: api_key is required');
assert(model_id, 'invalid cartesia speech credential: model_id is required');
const cartesiaData = JSON.stringify({api_key, model_id, options});
return encrypt(cartesiaData);

case 'rimelabs':
assert(api_key, 'invalid rimelabs speech credential: api_key is required');
assert(model_id, 'invalid rimelabs speech credential: model_id is required');
Expand Down Expand Up @@ -804,6 +811,22 @@ router.get('/:sid/test', async(req, res) => {
SpeechCredential.ttsTestResult(sid, false);
}
}
} else if (cred.vendor === 'cartesia') {
if (cred.use_for_tts) {
try {
await testCartesia(logger, synthAudio, credential);
results.tts.status = 'ok';
SpeechCredential.ttsTestResult(sid, true);
} catch (err) {
let reason = err.message;
// if error is from bent, let get the body
try {
reason = await err.text();
} catch {}
results.tts = {status: 'fail', reason};
SpeechCredential.ttsTestResult(sid, false);
}
}
} else if (cred.vendor === 'rimelabs') {
if (cred.use_for_tts) {
try {
Expand Down
301 changes: 301 additions & 0 deletions lib/utils/speech-data/tts-cartesia.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
/* eslint-disable max-len */
module.exports = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these only used if the API to list voices failed? Because we can get these from the api riught?

{
value: 'en',
name: 'English',
voices: [
{
value: '79f8b5fb-2cc8-479a-80df-29f7a7cf1a3e',
name: 'Nonfiction Man - This voice is smooth, confident, and resonant, perfect for narrating educational content',
},
{
value: 'e00d0e4c-a5c8-443f-a8a3-473eb9a62355',
name: 'Friendly Sidekick - This voice is friendly and supportive, designed for voicing characters in games and videos',
},
{
value: '3b554273-4299-48b9-9aaf-eefd438e3941',
name: 'Indian Lady - This voice is young, rich, and curious, perfect for a narrator or fictional character',
},
{
value: '71a7ad14-091c-4e8e-a314-022ece01c121',
name: 'British Reading Lady - This is a calm and elegant voice with a British accent, perfect for storytelling and narration',
},
{
value: '4d2fd738-3b3d-4368-957a-bb4805275bd9',
name: 'British Narration Lady - This is a neutral voice with a British accent, perfect for narrations ',
},
{
value: '15a9cd88-84b0-4a8b-95f2-5d583b54c72e',
name: 'Reading Lady - This voice is monotone and deliberate, perfect for a slower-paced and more serious reading voice',
},
{
value: 'd46abd1d-2d02-43e8-819f-51fb652c1c61',
name: 'Newsman - This voice is neutral and educational, perfect for a news anchor',
},
{
value: '2ee87190-8f84-4925-97da-e52547f9462c',
name: 'Child - This voice is young and full, perfect for a child',
},
{
value: 'cd17ff2d-5ea4-4695-be8f-42193949b946',
name: 'Meditation Lady - This voice is calm, soothing, and relaxing, perfect for meditation',
},
{
value: '5345cf08-6f37-424d-a5d9-8ae1101b9377',
name: 'Maria - This voice is laid back, natural, and conversational, like you\'re catching up with a good friend',
},
{
value: '41534e16-2966-4c6b-9670-111411def906',
name: '1920\'s Radioman - This voice is energetic and confident, great for an entertainer or radio host',
},
{
value: 'bf991597-6c13-47e4-8411-91ec2de5c466',
name: 'Newslady - This voice is authoritative and educational, perfect for a news anchor',
},
{
value: '00a77add-48d5-4ef6-8157-71e5437b282d',
name: 'Calm Lady - This voice is calm and nurturing, perfect for a narrator',
},
{
value: '156fb8d2-335b-4950-9cb3-a2d33befec77',
name: 'Helpful Woman - This voice is friendly and conversational, designed for customer support agents and casual conversations',
},
{
value: '36b42fcb-60c5-4bec-b077-cb1a00a92ec6',
name: 'Pilot over Intercom - This voice sounds like a British Pilot character speaking over an Intercom',
},
{
value: 'f146dcec-e481-45be-8ad2-96e1e40e7f32',
name: 'Reading Man - Male with calm narrational voice.',
},
{
value: '34575e71-908f-4ab6-ab54-b08c95d6597d',
name: 'New York Man - This voice is compelling and husky, with a New York accent, perfect for sales pitches and motivational content',
},
{
value: 'a0e99841-438c-4a64-b679-ae501e7d6091',
name: 'Barbershop Man - This voice is smooth and relaxing, perfect for a casual conversation',
},
{
value: '638efaaa-4d0c-442e-b701-3fae16aad012',
name: 'Indian Man - This voice is smooth with an Indian accent, perfect for a narrator',
},
{
value: '41f3c367-e0a8-4a85-89e0-c27bae9c9b6d',
name: 'Australian Customer Support Man - This voice is warm with an Australian accent, perfect for customer support agents',
},
{
value: '421b3369-f63f-4b03-8980-37a44df1d4e8',
name: 'Friendly Australian Man - This voice is rich and deep, with an Australian accent, perfect for casual conversations with a friend',
},
{
value: 'b043dea0-a007-4bbe-a708-769dc0d0c569',
name: 'Wise Man - This is a deep and deliberate voice, suited for educational content and conversations',
},
{
value: '69267136-1bdc-412f-ad78-0caad210fb40',
name: 'Friendly Reading Man - This voice is energetic and friendly, like having your friend read his favorite book to you',
},
{
value: 'a167e0f3-df7e-4d52-a9c3-f949145efdab',
name: 'Customer Support Man - This voice is clear and calm, perfect for a call center',
},
{
value: '4f8651b0-bbbd-46ac-8b37-5168c5923303',
name: 'Kentucky Woman - This voice is energetic and upbeat, with a slight Kentucky accent, perfect for speeches and rallies',
},
{
value: 'daf747c6-6bc2-4083-bd59-aa94dce23f5d',
name: 'Middle Eastern Woman - This voice is clear with a Middle Eastern Accent, perfect for a narrator',
},
{
value: '694f9389-aac1-45b6-b726-9d9369183238',
name: 'Sarah - This voice is natural and expressive with an American accent, perfect for a wide range of conversational use cases including customer support, sales, reception, and more.',
},
{
value: '794f9389-aac1-45b6-b726-9d9369183238',
name: 'Sarah Curious - This voice is similar to Sarah, but has improved emphasis for questions.',
},
{
value: '21b81c14-f85b-436d-aff5-43f2e788ecf8',
name: 'Laidback Woman - This voice is laid back and husky, with a slight Californian accent',
},
{
value: 'a3520a8f-226a-428d-9fcd-b0a4711a6829',
name: 'Reflective Woman - This voice is even, full, and reflective, perfect for a young narrator for an audiobook or movie',
},
{
value: '829ccd10-f8b3-43cd-b8a0-4aeaa81f3b30',
name: 'Customer Support Lady - This voice is polite and helpful, perfect for customer support agents',
},
{
value: '79a125e8-cd45-4c13-8a67-188112f4dd22',
name: 'British Lady - This voice is elegant with a slight British accent, perfect for storytelling and narrating',
},
{
value: 'c8605446-247c-4d39-acd4-8f4c28aa363c',
name: 'Wise Lady - This voice is wise and authoritative, perfect for a confident narrator',
},
{
value: '8985388c-1332-4ce7-8d55-789628aa3df4',
name: 'Australian Narrator Lady - This voice is even and neutral, with an Australian accent, designed for narrating content and stories',
},
{
value: 'ff1bb1a9-c582-4570-9670-5f46169d0fc8',
name: 'Indian Customer Support Lady - This voice is clear and polite, with an Indian accent, suitable for customer support agents',
},
{
value: '820a3788-2b37-4d21-847a-b65d8a68c99a',
name: 'Salesman - This voice is smooth and persuasive, perfect for sales pitches and phone conversations',
},
{
value: 'f114a467-c40a-4db8-964d-aaba89cd08fa',
name: 'Yogaman - This voice is calm, soothing, and stable, perfect for a yoga instructor',
},
{
value: 'c45bc5ec-dc68-4feb-8829-6e6b2748095d',
name: 'Movieman - This voice is deep, resonant, and assertive, perfect for a movie narrator',
},
{
value: '87748186-23bb-4158-a1eb-332911b0b708',
name: 'Wizardman - This voice is wise and mysterious, perfect for a Wizard character',
},
{
value: '043cfc81-d69f-4bee-ae1e-7862cb358650',
name: 'Australian Woman - This voice is deliberate and confident, with a slight Australian accent, perfect for inspiring characters in videos and stories',
},
{
value: '5619d38c-cf51-4d8e-9575-48f61a280413',
name: 'Announcer Man - This voice is deep and inviting, perfect for entertainment and broadcasting content',
},
{
value: '42b39f37-515f-4eee-8546-73e841679c1d',
name: 'Wise Guide Man - This voice is deep and deliberate, perfect for inspiring and guiding characters in games and videos',
},
{
value: '565510e8-6b45-45de-8758-13588fbaec73',
name: 'Midwestern Man - This voice is neutral and smooth, with a slight midwestern accent, perfect for narrations',
},
{
value: '726d5ae5-055f-4c3d-8355-d9677de68937',
name: 'Kentucky Man - This voice is laidback and smooth, with a Kentucky accent, perfect for a casual conversation',
},
{
value: '63ff761f-c1e8-414b-b969-d1833d1c870c',
name: 'Confident British Man - This voice is disciplined with a British accent, perfect for a commanding character or narrator',
},
{
value: '98a34ef2-2140-4c28-9c71-663dc4dd7022',
name: 'Southern Man - This voice is warm with a Southern accent, perfect for a narrator',
},
{
value: '95856005-0332-41b0-935f-352e296aa0df',
name: 'Classy British Man - This voice is light and smooth with a British accent, perfect for casual conversation',
},
{
value: 'ee7ea9f8-c0c1-498c-9279-764d6b56d189',
name: 'Polite Man - This voice is polite and conversational, with a slight accent, designed for customer support and casual conversations',
},
{
value: '40104aff-a015-4da1-9912-af950fbec99e',
name: 'Alabama Male - This voice has a strong Southern Accent, perfect for conversations and instructional videos',
},
{
value: '13524ffb-a918-499a-ae97-c98c7c4408c4',
name: 'Australian Male - This voice is smooth and disciplined, with an Australian Accent, suited for narrating educational content',
},
{
value: '1001d611-b1a8-46bd-a5ca-551b23505334',
name: 'Anime Girl - This voice is expressive and has a high pitch, suitable for anime or gaming characters',
},
{
value: 'e3827ec5-697a-4b7c-9704-1a23041bbc51',
name: 'Sweet Lady - This voice is sweet and passionate, perfect for a character in a game or book',
},
{
value: 'c2ac25f9-ecc4-4f56-9095-651354df60c0',
name: 'Commercial Lady - This voice is inviting, enthusiastic, and relatable, perfect for a commercial or advertisement',
},
{
value: '573e3144-a684-4e72-ac2b-9b2063a50b53',
name: 'Teacher Lady - This voice is neutral and clear, perfect for narrating educational content',
},
{
value: '8f091740-3df1-4795-8bd9-dc62d88e5131',
name: 'Princess - This voice is light, freindly and has a flourish, perfect for character work in videos and games',
},
{
value: '7360f116-6306-4e9a-b487-1235f35a0f21',
name: 'Commercial Man - This voice is upbeat and enthusiastic, perfect for commercials and advertisements',
},
{
value: '03496517-369a-4db1-8236-3d3ae459ddf7',
name: 'ASMR Lady - This voice is calming and soft, perfect for guided meditations and soothing content',
},
{
value: '248be419-c632-4f23-adf1-5324ed7dbf1d',
name: 'Professional Woman - This voice is neutral and calm, perfect for a call center',
},
{
value: 'bd9120b6-7761-47a6-a446-77ca49132781',
name: 'Tutorial Man - This voice is inviting and calming, perfect for tutorials',
},
{
value: '34bde396-9fde-4ebf-ad03-e3a1d1155205',
name: 'New York Woman - This voice commands authority, with a New York accent, perfect for a commanding narrator or character',
},
{
value: '11af83e2-23eb-452f-956e-7fee218ccb5c',
name: 'Midwestern Woman - This voice is neutral and deliberate, with a midwestern accent, suitable for news broadcasts and narration',
},
{
value: 'ed81fd13-2016-4a49-8fe3-c0d2761695fc',
name: 'Sportsman - This voice is energetic and enthusiastic, perfect for a sports broadcaster',
},
{
value: '996a8b96-4804-46f0-8e05-3fd4ef1a87cd',
name: 'Storyteller Lady - This voice is neutral and smooth, with a slight Canadian accent, perfect for narrations',
},
{
value: 'fb26447f-308b-471e-8b00-8e9f04284eb5',
name: 'Doctor Mischief - This is an expressive character voice, suited to whimsical characters for games and educational content',
},
{
value: '50d6beb4-80ea-4802-8387-6c948fe84208',
name: 'The Merchant - This voice is playful and quirky, designed for character work in games and videos',
},
{
value: 'e13cae5c-ec59-4f71-b0a6-266df3c9bb8e',
name: 'Madame Mischief - This voice is mischeivious and playful, suitable for voicing characters for kids content and games',
},
{
value: '5c42302c-194b-4d0c-ba1a-8cb485c84ab9',
name: 'Female Nurse - This voice is clear and firm, perfect for nurse characters and instructional videos',
},
{
value: 'f9836c6e-a0bd-460e-9d3c-f7299fa60f94',
name: 'Southern Woman - This voice is friendly and inviting, with a slight Southern Accent, perfect for conversations and phone calls',
},
{
value: 'a01c369f-6d2d-4185-bc20-b32c225eab70',
name: 'British Customer Support Lady - This voice is friendly and polite, with a British accent, perfect for phone conversations',
},
{
value: 'b7d50908-b17c-442d-ad8d-810c63997ed9',
name: 'California Girl - This voice is enthusiastic and friendly, perfect for a casual conversation between friends',
},
{
value: 'f785af04-229c-4a7c-b71b-f3194c7f08bb',
name: 'John - This voice is natural and empathetic with an American accent, perfect for use cases like demos and customer support calls.',
},
{
value: '729651dc-c6c3-4ee5-97fa-350da1f88600',
name: 'Pleasant Man - A pleasant male voice that\'s good for use cases like demos and customer support calls',
},
{
value: '91b4cf29-5166-44eb-8054-30d40ecc8081',
name: 'Anna - This voice is natural and expressive with an American accent, perfect for use cases like interviews and customer support calls.',
},
],
},
];
Loading
Loading