我正在使用适用于 JavaScript 的 AWS 开发工具包通过 AWS Polly 生成长格式内容。我的内容长度超过 3000 个字符,因此我使用长格式引擎并将所有生成的文件保存在 S3 存储桶中(根据需要)。每个音频文件大小低于 4Mb(最多大约 10 分钟的音频)。
我能够生成 Polly 文件并保存它们,并且我能够看到 s3 存储桶的内容,但我没有运气检索或播放这些文件。我错过了什么?
我的项目是一个 React/Node/Typescript Web 应用程序。现在,当我开发此功能时,我正在 Docker 容器中本地运行。
我应该注意,我是 AWS 新手,所以我可能缺少一些基础知识。
我想在 Polly 生成时流式传输内容,或者至少在生成完成后从 s3 流式传输内容。
首先,我尝试使用 Synthesize SpeechCommandOutput,该响应包含一个 AudioStream,它提供了一个名为 TransformToWebStream() 的函数...但是 AudioStream 和从 TransformToWebStream 函数返回的对象都没有按照我期望的可读流的方式工作工作(基于我在 Node 文件处理和流媒体方面的经验)。
const playNarration = async () => {
const stream: SynthesizeSpeechCommandOutput | undefined = await getAudiostream();
if (stream) {
console.log(stream);
const webStream: ReadableStream | undefined = stream.AudioStream?.transformToWebStream();
console.log(webStream);
if (webStream) {
webStream.on('data', (chunk: any) => { // THIS ERRORS, SAYS 'ON' IS NOT A FUNCTION
console.log(chunk);
});
}
}
我还尝试使用 StartSpeechSynthesisTaskCommand,从返回的 SynthesisTask 中获取 OutputUri 并将其发送到音频播放器 (https://www.npmjs.com/package/react-h5-audio-player)。
static getAudiostream(article: IArticle): Promise<StartSpeechSynthesisTaskCommandOutput | undefined> {
let streamUrl = '';
if (NarrationProvider.pollyClient) {
const bodyString = documentToPlainTextString(article.body);
const narrationParams = {
Engine: Engine.LONG_FORM,
LanguageCode: LanguageCode.en_US,
OutputFormat: OutputFormat.MP3,
Text: bodyString,
TextType: TextType.TEXT,
VoiceId: VoiceId.Danielle,
OutputS3BucketName: NarrationProvider.s3Bucket,
OutputS3KeyPrefix: article.slug,
};
const command = new StartSpeechSynthesisTaskCommand(narrationParams);
const stream = await NarrationProvider.pollyClient
.send(command)
.catch((error) => {
throw error;
});
if (stream?.SynthesisTask?.OutputUri) {
streamUrl = stream.SynthesisTask.OutputUri;
}
}
return Promise.resolve(undefined);
}
就是为了它,我尝试手动生成 s3 文件的预签名 url 并将其发送到音频播放器,但这也不起作用。
我可能不是唯一一个想在他们的应用程序中加入人工智能声音的人,但我在 Stack Overflow 上没有看到任何有用/最新的答案。
ReadableStream 在浏览器领域的实现与它最初在 Node.js 中的实现方式有所不同。所以,没有
on
方法。您可以在此处查看文档:https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
通常,以这种方式使用 Polly 时,您可以解码获得的缓冲区并立即使用 AudioContext 进行播放。
// Generate Speech
const pollyRes = await pollyClient.send(
new SynthesizeSpeechCommand({
Engine: Engine.LONG_FORM,
LanguageCode: LanguageCode.en_US,
OutputFormat: OutputFormat.MP3,
Text: bodyString,
VoiceId: VoiceId.Danielle
})
);
// Play Speech
const audioContext = new AudioContext();
const pollyBufferSourceNode = audioContext.createBufferSource();
pollyBufferSourceNode.buffer = await audioContext.decodeAudioData(
(await pollyRes.AudioStream.transformToByteArray()).buffer
);
pollyBufferSourceNode.connect(audioContext.destination);
pollyBufferSourceNode.start();
至于 S3 输出,我没有使用过该方法,但是是的,我完全希望您可以签署 GET URL 并执行类似的操作...
const a = new Audio(url);
a.play(); // Must be done on user click or some other interactive event