i, r0b0t .mp3
aHR0cHM6Ly90Lmx5L3Bjd3c= is hex?
Gerar arquivos MP3 de leitura dos comentários de um post;
Nessa parte eu optei por usar o python pois achei muito mais fácil criar um cli pra chamar pelo node, do que tentar fazer direto no node.
Aqui usei uma biblioteca chamada edge-tts, nela conseguimos usar qualquer voz de qualquer lingua que o Microsoft Edge possua. Já deixei meio caminho andado para implementar um esquema de geração de vídeos em inglês e também português do Brasil.
O código recebe um texto em inglês (ou pt-br), passa para a biblioteca que por trás dos panos faz literalmente a leitura do texto e os dados dessa leitura são salvos em um arquivo MP3.
import asyncio
import argparse
import edge_tts
parser = argparse.ArgumentParser(description="Just an example", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("-t", "--text", help="text to speech")
parser.add_argument("-n", "--name", help="file name")
parser.add_argument("-tr", "--translate", help="translated text?")
VOICE_BR = "Microsoft Server Speech Text to Speech Voice (pt-BR, AntonioNeural)"
VOICE_EN = "Microsoft Server Speech Text to Speech Voice (en-US, ChristopherNeural)"
def get_voice(translate):
if (translate == 'True'):
choicedVoice = VOICE_BR
else:
choicedVoice = VOICE_EN
return choicedVoice
async def generate(text,name,voice):
try:
communicate = edge_tts.Communicate(text,voice=voice)
with open(f"output/{name}.mp3","wb") as fp:
async for chunk in communicate.stream():
if chunk["type"] == "audio":
fp.write(chunk["data"])
except Exception as error:
print(error)
raise error
async def main():
args = parser.parse_args()
config = vars(args)
voice = get_voice(config["translate"])
await generate(config["text"], config["name"], voice)
asyncio.run(main())
Depois no node eu faço a chamada da seguinte forma:
const generateVoiceClip = async (text: string, title: string, translate: boolean = false) => {
const python = spawn("python", ["lib/generate-audio-clip.py", "-t", text, "-n", title, "-tr", translate ? "True" : "False"])
python.stdout.on("data", function (data) {})
}
export const generateVoices = async (postContent: PostContent, translate?: boolean): Promise<boolean> => {
info("generating mp3 audio files")
await generateVoiceClip(postContent.title, "post", false)
for (const [index, comment] of postContent.comments.entries()) {
await generateVoiceClip(comment, index.toString(), false)
}
success("generating mp3 audio files")
return true
}
No final, são gerados arquivos MP3 dentro da pasta output do projeto.