在我的 Web 应用程序中播放 AWS-Polly 生成的客户端语音

问题描述 投票:0回答:1

我正在使用适用于 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 上没有看到任何有用/最新的答案。

reactjs node.js amazon-s3 audio-streaming amazon-polly
1个回答
0
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.