Skip to content

Instantly share code, notes, and snippets.

@lancejpollard
Created August 21, 2023 02:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lancejpollard/31d0880fb8c2a392e728aa855289af83 to your computer and use it in GitHub Desktop.
Save lancejpollard/31d0880fb8c2a392e728aa855289af83 to your computer and use it in GitHub Desktop.
Amazon Polly Snippet JS
import 'dotenv/config'
import {
PollyClient,
SynthesizeSpeechCommand,
} from '@aws-sdk/client-polly'
import fs from 'fs'
import read from '@nerdbond/read'
import TERM_MAP from '~/configurations/terms'
// a client can be shared by different commands.
const client = new PollyClient({
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
region: 'us-east-1',
})
;(async () => {
for (const term in TERM_MAP) {
const path = `public/words/${term.replace(/C/g, '$')}.mp3`
if (fs.existsSync(path)) {
continue
}
console.log(term)
const vowelMatch = term.match(/[aeiou]/g)
const vowelAtEnd = term.match(/[aeiou]$/)
let text = term
if (vowelMatch?.length == 3) {
text = term.replace(
/([aeiou])(.+[aeiou])(.+[aeiou])/,
(_, $1, $2, $3) => `${$1}${$2}^${$3}`,
)
} else if (vowelMatch?.length == 2) {
if (vowelAtEnd) {
text = term.replace(
/([aeiou])(.+[aeiou])/,
(_, $1, $2) => `${$1}^${$2}`,
)
} else {
text = term.replace(
/([aeiou])(.+[aeiou])/,
(_, $1, $2) => `${$1}${$2}^`,
)
}
}
text = `<phoneme alphabet="ipa" ph="${
read.talk.toIPA(text).replace(/ɔ/g, 'a')
// .replace(/r/, 'ɾ')
}">${text}</phoneme>`
const input = {
Engine: 'neural',
// LanguageCode: 'en-ZA',
LanguageCode: 'en-US',
OutputFormat: 'mp3', // required
Text: `<speak>${text}</speak>`,
TextType: 'ssml',
// VoiceId: 'Arlet',
// VoiceId: 'Ayanda',
// VoiceId: 'Elin',
VoiceId: 'Salli',
// VoiceId: 'Salli',
}
const command = new SynthesizeSpeechCommand(input)
const response = await client.send(command)
const bytes = await response.AudioStream?.transformToByteArray()
if (bytes) {
fs.writeFileSync(path, bytes)
}
}
})()
const keys = fs
.readdirSync('public/words')
.filter(x => x.endsWith('.mp3'))
.map(x => ` ${x.split('.')[0]}: '/words/${x}',`)
.sort()
fs.writeFileSync(
'data/termSound.ts',
`const SOUND_MAP = {
${keys.join('\n')}
}
export default SOUND_MAP`,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment