Skip to content

Commit

Permalink
chore(texttospeech): modernize quickstart for texttospeech (GoogleClo…
Browse files Browse the repository at this point in the history
…udPlatform#3726)

* chore(texttospeech): modernize quickstart for texttospeech

* chore(texttospeech): add testing

* chore: update filename

* chore: match filename across files and don't conflict with original

* chore: updating package manifest

* chore(texttospeech): rev versions of node

* fix(texttospeech): cleaning up comments

* refactor: remove chai, enhance consistency, idiomatic usage

---------

Co-authored-by: Adam Ross <adamross@google.com>
Co-authored-by: Tony Pujals <tonypujals@google.com>
  • Loading branch information
3 people authored Aug 11, 2024
1 parent c56d4ce commit 620fb04
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 105 deletions.
12 changes: 6 additions & 6 deletions texttospeech/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
"name": "nodejs-docs-samples-text-to-speech",
"private": true,
"license": "Apache-2.0",
"author": "Google Inc.",
"author": "Google LLC",
"repository": "googleapis/nodejs-text-to-speech",
"files": [
"*.js"
],
"engines": {
"node": ">=16.0.0"
"node": ">=18.0.0"
},
"scripts": {
"test": "c8 mocha -p -j 2 --timeout=60000"
"test": "c8 mocha -p -j 2 --timeout=60000",
"lint": "gts lint"
},
"dependencies": {
"@google-cloud/text-to-speech": "^5.0.0",
"@google-cloud/text-to-speech": "^5.3.0",
"yargs": "^17.0.0"
},
"devDependencies": {
"c8": "^8.0.0",
"chai": "^4.2.0",
"c8": "^9.0.0",
"mocha": "^10.0.0"
}
}
19 changes: 12 additions & 7 deletions texttospeech/quickstart.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@

'use strict';

function main() {
async function main() {
// [START tts_quickstart]
// Imports the Google Cloud client library
const textToSpeech = require('@google-cloud/text-to-speech');

// Import other required libraries
const fs = require('fs');
const util = require('util');
const {writeFile} = require('node:fs/promises');

// Creates a client
const client = new textToSpeech.TextToSpeechClient();

async function quickStart() {
// The text to synthesize
const text = 'hello, world!';
Expand All @@ -39,13 +40,17 @@ function main() {

// Performs the text-to-speech request
const [response] = await client.synthesizeSpeech(request);
// Write the binary audio content to a local file
const writeFile = util.promisify(fs.writeFile);

// Save the generated binary audio content to a local file
await writeFile('output.mp3', response.audioContent, 'binary');
console.log('Audio content written to file: output.mp3');
}
quickStart();

await quickStart();
// [END tts_quickstart]
}

main(...process.argv.slice(2));
main().catch(err => {
console.error(err);
process.exitCode = 1;
});
47 changes: 47 additions & 0 deletions texttospeech/quickstart.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {writeFile} from 'node:fs/promises';
import {TextToSpeechClient} from '@google-cloud/text-to-speech';

async function main() {
// Create a Text-to-Speech client instance
const client = new TextToSpeechClient();

// The text that should be converted to speech
const text = 'hello, world!';

const outputFile = 'quickstart_output.mp3';

// Configure the text-to-speech request
const request = {
input: {text},
// Select the language and SSML voice gender (optional)
voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
// Configure the audio format of the output
audioConfig: {audioEncoding: 'MP3'},
};

// Performs the text-to-speech request
const [response] = await client.synthesizeSpeech(request);

// Save the generated binary audio content to a local file
await writeFile(outputFile, response.audioContent, 'binary');
console.log(`Audio content written to file: ${outputFile}`);
}

main().catch(err => {
console.error(err);
process.exitCode = 1;
});
9 changes: 6 additions & 3 deletions texttospeech/ssmlAddresses.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

'use strict';

function main(
async function main(
inFile = 'resources/example.txt',
outFile = 'resources/example.mp3'
) {
Expand Down Expand Up @@ -119,8 +119,11 @@ function main(
}
// [END tts_ssml_address_ssml]
const ssml = textToSsml(inFile);
ssmlToAudio(ssml, outFile);
await ssmlToAudio(ssml, outFile);
// [END tts_ssml_address_test]
}

main(...process.argv.slice(2));
main(...process.argv.slice(2)).catch(err => {
console.error(err.stack);
process.exitCode = 1;
});
44 changes: 27 additions & 17 deletions texttospeech/test/audioProfile.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,44 @@

'use strict';

const fs = require('fs');
const {assert} = require('chai');
const {describe, it, after} = require('mocha');
const cp = require('child_process');
const assert = require('node:assert/strict');
const cp = require('node:child_process');
const {existsSync, unlinkSync} = require('node:fs');

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const {after, before, describe, it} = require('mocha');

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const cmd = 'node audioProfile.js';
const text =
'"Hello Everybody! This is an Audio Profile Optimized Sound Byte."';
const outputFile = 'phonetest.mp3';

function removeOutput() {
try {
// Remove if outputFile exists
unlinkSync(outputFile);
} catch {
// OK to ignore error if outputFile doesn't exist already
}
}

describe('audio profile', () => {
before(() => {
// Remove file if it already exists
removeOutput();
});

after(() => {
function unlink(outputFile) {
try {
fs.unlinkSync(outputFile);
} catch (err) {
// Ignore error
}
}
[outputFile].map(unlink);
// Remove file after testing
removeOutput();
});

it('should synthesize human audio using hardware profile', async () => {
assert.strictEqual(fs.existsSync(outputFile), false);
it('should synthesize human audio using hardware profile', () => {
assert.equal(existsSync(outputFile), false);
const output = execSync(`${cmd} ${text} ${outputFile}`);
assert.match(output, new RegExp('Audio content written to file:'));
assert.ok(fs.existsSync(outputFile));
assert.ok(
new RegExp(`Audio content written to file: ${outputFile}`).test(output)
);
assert.ok(existsSync(outputFile));
});
});
8 changes: 4 additions & 4 deletions texttospeech/test/listVoices.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@

'use strict';

const {assert} = require('chai');
const assert = require('node:assert/strict');
const cp = require('node:child_process');

const {describe, it} = require('mocha');
const cp = require('child_process');

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});

const cmd = 'node listVoices.js';

describe('list voices', () => {
it('should list voices', async () => {
it('should list voices', () => {
const stdout = execSync(`${cmd} list-voices`);
assert.match(stdout, /SSML Voice Gender: FEMALE/);
assert.match(stdout, /Natural Sample Rate Hertz: 24000/);
Expand Down
35 changes: 23 additions & 12 deletions texttospeech/test/quickstart.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,39 @@

'use strict';

const fs = require('fs');
const {assert} = require('chai');
const {describe, it, after} = require('mocha');
const cp = require('child_process');
const assert = require('node:assert/strict');
const cp = require('node:child_process');
const {existsSync, unlinkSync} = require('node:fs');

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const {after, beforeEach, describe, it} = require('mocha');

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const outputFile = 'output.mp3';

function removeOutput() {
try {
// Remove if outputFile exists
unlinkSync(outputFile);
} catch {
// OK to ignore error if outputFile doesn't exist already
}
}

describe('quickstart', () => {
// Remove file if it already exists
beforeEach(() => {
removeOutput();
});

// Remove file after testing
after(() => {
try {
fs.unlinkSync(outputFile);
} catch (err) {
// Ignore error
}
removeOutput();
});

it('should synthesize speech to local mp3 file', () => {
assert.strictEqual(fs.existsSync(outputFile), false);
assert.equal(existsSync(outputFile), false);
const stdout = execSync('node quickstart');
assert.match(stdout, /Audio content written to file: output.mp3/);
assert.ok(fs.existsSync(outputFile));
assert.ok(existsSync(outputFile));
});
});
57 changes: 57 additions & 0 deletions texttospeech/test/quickstart.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import assert from 'node:assert/strict';
import {existsSync, unlinkSync} from 'node:fs';
import * as cp from 'node:child_process';

import {after, beforeEach, describe, it} from 'mocha';

const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
const outputFile = 'quickstart_output.mp3';

function removeOutput() {
try {
// Remove if outputFile exists
unlinkSync(outputFile);
} catch {
// OK to ignore error if outputFile doesn't exist already
}
}

describe('quickstart', () => {
// Remove file if it exists
beforeEach(() => {
removeOutput();
});

// Remove file after testing
after(() => {
removeOutput();
});

it('should synthesize speech to local mp3 file', () => {
// Verifies that outputFile doesn't exist
assert.equal(
existsSync(outputFile),
false,
`found pre-existing ${outputFile}, please rename or remove and retry the test`
);
const output = execSync('node quickstart.mjs');
assert.ok(
new RegExp(`Audio content written to file: ${outputFile}`).test(output)
);
assert.ok(existsSync(outputFile));
});
});
Loading

0 comments on commit 620fb04

Please sign in to comment.