Last active
May 10, 2024 16:19
-
-
Save officialrobert/156a1cb6bdf42512f531df711ca36ef0 to your computer and use it in GitHub Desktop.
How to clone a voice in elevenlabs using nodeJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import FormData from 'form-data'; | |
import axios from 'axios'; | |
import fs from 'fs'; | |
interface ICloneVoiceParams { | |
description:string; | |
name:string; | |
fileUrls: string[]; | |
labels: Record<string,string>; | |
} | |
const handleStreamEnd = (stream: fs.ReadStream): Promise<void> => { | |
return new Promise(resolve => { | |
if (!stream || stream?.closed) { | |
resolve(); | |
return; | |
} | |
stream.once('end', () => { | |
resolve(); | |
}); | |
stream.once('close', () => { | |
resolve(); | |
}); | |
}); | |
}; | |
const cloneVoiceHandler = async (params:ICloneVoiceParams): Promise<string> => { | |
const { name, description, fileUrls=[], labels={} } = params; | |
const formData = new FormData(); | |
const streams: fs.ReadStream[] = []; | |
for (let i = 0; i < fileUrls.length; i++) { | |
try { | |
const fileUrl = fileUrls[i]; | |
const mp3Response = await axios.get(fileUrl, { | |
responseType: 'stream', | |
}); | |
streams.push(mp3Response.data); // make sure to clear the streams | |
formData.append('files', mp3Response.data, { | |
contentType: 'audio/mpeg', | |
}); | |
} catch (err) { | |
// log error | |
} | |
} | |
formData.append('name', name); | |
formData.append('description', description); | |
if (typeof labels === 'object' && labels) { | |
formData.append('labels', JSON.stringify(labels)); | |
} | |
const elevenlabsUrl = ''; | |
const elevenLabsApiKey =''; | |
const elevenLabsResponse = await axios | |
.post(elevenlabsUrl, formData, { | |
headers: { | |
...formData.getHeaders(), | |
Accept: 'application/json', | |
'xi-api-key': elevenLabsApiKey, | |
'Access-Control-Allow-Origin': '*', | |
}, | |
validateStatus: function (status) { | |
return status >= 200 && status <= 500; | |
}, | |
}); | |
const voiceId = elevenLabsResponseData?.voice_id || ''; | |
for (let i = 0; i < streams.length; i++) { | |
const stream = streams[i]; | |
await handleStreamEnd(stream); | |
} | |
for (let i = 0; i < streams.length; i++) { | |
const stream = streams[i]; | |
if (stream) { | |
stream.destroy(); | |
} | |
} | |
return voiceId; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment