How to dub audio and generate synthetic voices using Google text to speech

You can now simply dub your audio/video in a synthetic voice using Google text to speech and AVflow. When you combine this with the transcription and translation steps, you will be able to dub your video in dozens of foreign languages super fast and with a setup that only takes a few minutes.

Here's how to setup Google TTS using a webhook trigger that accepts the text passed in the body of API request from your system, then converts it to audio using Google TTS step. Then a webhook is sent back to your system for further processing or rendering.

1. Create a Flow and add the webhook step (more info on using webhooks); then add the Google TTS step to the Flow

2. Select "Text to speech" as the action

3.  Setup TTS service options

  • Language code: the code associated with the source texts language (refer here for code)
  • Speaking Rates: An array of a valid numbers from 0 to 4 specifies the speaking speed for each text. This step is optional and if no value is set, the default is 0.
  • Voices: An array of accepted voices (optional, refer to the column "Voice name" here for valid values)
  • Gender (optional): An array to choose the gender of the synthetic voice. A valid value is MALE or FEMALE
  • Google TTS Credential: Google TTS key that can be retrieved during enabling service in Google Console.
const fs = require('fs');
const https = require('https');
const request = require('request');

async function main (service, context) {
for (let i = 0; i < service.files.length; i++) {
let source_file = `./text-to-speech-service/${service.files[i]}`;
let dest_file = `${service.files[i]}`;

let presignedURL = await generatePresignedUrl(service.dstRegion, service.dstBucket, service.dstFolder, dest_file, service.awsKeyId);
console.log(presignedURL);
try {
if (fs.existsSync(source_file)) {
await uploadToS3(presignedURL.data.url, source_file);
} else {
console.log(`File not found: ${source_file}`);
}
} catch(err) {
console.log('file error');
console.error(err)
}
}


return {
result: "SUCCESS"
};
}

async function generatePresignedUrl(dstRegion, dstBucket, dstFolder, dstFile, awsKeyId , upload = true) {
const sdkGeneratePresignedUrlEndpoint = 'https://tb1dvngz1i.execute-api.us-east-1.amazonaws.com/production/s3-signed-url';
const data = {
region: dstRegion,
bucket: dstBucket,
objectKey: dstFolder + '/' + dstFile,
keyId: awsKeyId,
isPresigned: upload
}
return await new Promise((resolve, reject) => {
request({
method: 'POST',
uri: sdkGeneratePresignedUrlEndpoint,
body: data,
json: true
}, function (error, request, body) {
// console.log('signedUrl', body);
resolve(body);
});
});
}


async function uploadToS3(presignedUrl, srcFile) {
const fileContent = fs.readFileSync(srcFile);

// console.log(fileContent);

if (!fs.existsSync(srcFile)) {
console.log(`Source file not found.`);
reject('Source file not found');
}

return new Promise((resolve, reject) => {
request({
method: 'PUT',
uri: presignedUrl,
body: fileContent
}, function (error, request, body) {
if(error) {
console.log('Error: ', error);
return reject(error);
}

// console.log(body);
resolve(body);
});
});
}

module.exports = main;

Inputs:

[
{
key: 'files',
dataType: 'array'
},
{
key: 'awsKeyId',
dataType: 'referenceKey'
},
{
key: 'dstBucket',
dataType: 'string'
},
{
key: 'dstFolder',
dataType: 'string'
},
{
key: 'dstRegion',
dataType: 'string'
}
]

Outputs:

[
{
key: 'result',
dataType: 'string'
}
]

Packages:

[
]

5.  Webhook to your system to update the result when Flow runs successfully.

6. Save, Enable, then trigger the Flow and check the log for the result.

TaDa! You now having dubbing enabled!