AWS Polly v3:SynthesizeSpeech 'mp3',AudioStream 不是 instanceOf Buffer

问题描述

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

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

以下 JavaScript 代码使用 v2,返回的 audio.AudioStreamBuffer 的实例:

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;
         }
     })

以下使用 v3 的 JavaScript 代码,其来自 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',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;
         }
     })

我都使用 PollyClientSynthesizeSpeechCommand 尝试了以下 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);
    });

v3 data.AudioStream内容是:

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

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

解决方法

现在是一个 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

,

就我个人而言,我发现使用 async/await 而不是流回调更容易...

 t1 <- melt(df[Dept == "CA"],id.vars=c("Manager","PF","Yearlybonus","Quaterlybonus","monthlybonus"))
  

注意:我使用的是 node14,因此可以在顶部使用 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() ,但您也可以轻松使用 import