【问题标题】:AWS Polly v3: SynthesizeSpeech 'mp3', AudioStream not instanceOf BufferAWS Polly v3:SynthesizeSpeech 'mp3',AudioStream 不是 instanceOf 缓冲区
【发布时间】:2021-01-29 18:32:29
【问题描述】:

我正在将 JavaScript(节点)中的 AWS Polly 代码从 v2 转换为 v3。

使用 AWS Polly v3 synthesizeSpeech() 时,如何将返回的 data.AudioStream 转换为 Buffer 的实例?

以下 JavaScript 代码使用 v2 工作,返回的 audio.AudioStream 是 Buffer 的一个实例:

const { Polly } = require('aws-sdk');

// Create an Polly client
const polly = new Polly({
    signatureVersion: 'v4',
    region: process.env.AWS_DEFAULT_REGION
});

const params = {
    OutputFormat: 'mp3',
    VoiceId: voiceId,
    TextType: 'ssml',
    Text: '<speak><prosody rate="85%">Hello World</prosody></speak>'
};

// ***

return await polly
    .synthesizeSpeech(params)
    .promise()
    .then(data => {
         if (data.AudioStream instanceof Buffer) {
             return data.AudioStream
         } else {
             console.error('AudioStream not instanceof Buffer');
             return null;
         }
     })

以下 JavaScript 代码使用 v3,它来自synthesizeSpeech() 的响应包含audio.AudioStream 不是Buffer 的实例,而是以IncomingMessage 开头:

const {
    Polly
} = require("@aws-sdk/client-polly");

// Create an Polly client
const polly = new Polly({
    signatureVersion: 'v4',
    region: process.env.AWS_DEFAULT_REGION
});

// ***

const params = {
    OutputFormat: 'mp3',
    VoiceId: voiceId,
    TextType: 'ssml',
    Text: '<speak><prosody rate="85%">Hello World</prosody></speak>'
};

return await polly
    .synthesizeSpeech(params)
    .then(data => {
         if (data.AudioStream instanceof Buffer) {
             return data.AudioStream
         } else {
             console.error('AudioStream not instanceof Buffer');
             return null;
         }
     })

我都使用PollyClient和SynthesizeSpeechCommand尝试了以下v3,结果相同

const {
    PollyClient,
    SynthesizeSpeechCommand
} = require("@aws-sdk/client-polly");

const client = new PollyClient({
    region: process.env.AWS_DEFAULT_REGION
});

// ***

const command = new SynthesizeSpeechCommand({
    OutputFormat: 'mp3',
    Text:'hello world, this is alex',
    VoiceId: 'Kimberly',
    TextType: 'text'
});

return client
    .send(command)
    .then((data) => {
        if (data.AudioStream instanceof Buffer) {
            return data.AudioStream
        } else {
            console.error('AudioStream not instanceof Buffer');
            console.log('data.AudioStream:', data.AudioStream);
            return null;
        }
    })
    .catch((error) => {
        console.error(error);
    });

v3data.AudioStream的内容是:

IncomingMessage {
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: BufferList { head: null, tail: null, length: 0 },
     length: 0,
     pipes: null,
     ***

感谢您的阅读,感谢任何反馈。

【问题讨论】:

    标签: node.js amazon-polly


    【解决方案1】:

    现在是一个 ReadableStream 对象。

       import { Readable } from "stream";
        //...
        if (data.AudioStream instanceof Readable) {
          console.log("Readable");
          data.AudioStream.pipe(fs.createWriteStream("fileName.mp3"));
        } else {
          console.log("no Readable");
        }
        //...
    

    您可以在此处找到有关此更改的详细信息: https://github.com/aws/aws-sdk-js-v3/issues/1096#issuecomment-620900466

    【讨论】:

      【解决方案2】:

      我个人觉得使用 async/await 比使用流回调更容易...

      import { PollyClient, SynthesizeSpeechCommand, SynthesizeSpeechInput } from "@aws-sdk/client-polly";
      import fs from 'fs';
      
      async function go() {
          const client = new PollyClient(yourClientOptions)
          const command = new SynthesizeSpeechCommand(yourCommandOptions)
          try {
              let data = await client.send(command)
              if (!data || !data.AudioStream) throw Error(`bad response`);
              await saveStream(data.AudioStream, "output.mp3")
          }
          catch(err) {
              console.log(err)
          }
      }
      
      async function saveStream(fromStream, filename) {
          return new Promise((resolve, reject) => {
              let toStream = fs.createWriteStream(filename)
              toStream.on('finish', resolve);
              toStream.on('error', reject);
              fromStream.pipe(toStream)
          })
      }
      
      go()
      

      注意:我使用的是 node14,因此可以在顶部使用 import,但您也可以轻松使用 require。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        • 2023-03-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多