使用Google的Text to Speech API一次执行多个请求时,仅获取最后一个请求的音频

时间:2019-04-29 16:00:06

标签: node.js google-cloud-platform text-to-speech google-text-to-speech ssml

使用Promise.all一次执行多个请求时,我似乎只得到上一个解决请求的audioContent

我正在合成大文本,需要使用API​​的字符数限制将其拆分。

我以前曾经做过这项工作,所以我知道它应该工作,但是最近停止了工作。

我正在使用Amazon的Polly进行完全相同的操作,并且在那里工作。它是完全相同的代码,但是具有不同的客户端和不同的请求选项。

那让我觉得也许是图书馆的事吗?还是Google服务问题?

我使用的是最新版本的:https://github.com/googleapis/nodejs-text-to-speech

export const googleSsmlToSpeech = async (
  index: number,
  ssmlPart: string,
  type: SynthesizerType,
  identifier: string,
  synthesizerOptions: GoogleSynthesizerOptions,
  storageUploadPath: string
) => {
  let extension = 'mp3';

  if (synthesizerOptions.audioConfig.audioEncoding === 'OGG_OPUS') {
    extension = 'opus';
  }

  if (synthesizerOptions.audioConfig.audioEncoding === 'LINEAR16') {
    extension = 'wav';
  }

  synthesizerOptions.input.ssml = ssmlPart;

  const tempLocalAudiofilePath = `${appRootPath}/temp/${storageUploadPath}-${index}.${extension}`;

  try {
    // Make sure the path exists, if not, we create it
    await fsExtra.ensureFile(tempLocalAudiofilePath);

      // Performs the Text-to-Speech request
    const [response] = await client.synthesizeSpeech(synthesizerOptions);

    // Write the binary audio content to a local file
    await fsExtra.writeFile(tempLocalAudiofilePath, response.audioContent, 'binary');

    return tempLocalAudiofilePath;
  } catch (err) {
    throw err;
  }
};
/**
 * Synthesizes the SSML parts into seperate audiofiles
 */
export const googleSsmlPartsToSpeech = async (
  ssmlParts: string[],
  type: SynthesizerType,
  identifier: string,
  synthesizerOptions: GoogleSynthesizerOptions,
  storageUploadPath: string
) => {
  const promises: Promise<string>[] = [];

  ssmlParts.forEach((ssmlPart: string, index: number) => {
    promises.push(googleSsmlToSpeech(index, ssmlPart, type, identifier, synthesizerOptions, storageUploadPath));
  });

  const tempAudioFiles = await Promise.all(promises);

  tempAudioFiles.sort((a: any, b: any) => b - a); // Sort: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 etc...

  return tempAudioFiles;
};

上面的代码使用正确的命名和索引号创建了多个文件,但是它们都包含相同的音频。那是;解决最快的音频响应。

824163ed-b4d9-4830-99da-6e6f985727e2-0.mp3
824163ed-b4d9-4830-99da-6e6f985727e2-1.mp3
824163ed-b4d9-4830-99da-6e6f985727e2-2.mp3

使用简单的Promise.all循环替换for,使其生效。但这需要更长的时间,因为它等待每个请求都得到解决。我知道Promise.all可以工作,因为我以前曾经工作过,并且希望再次看到它。

  const tempAudioFiles = [];
  for (var i = 0; i < ssmlParts.length; i++) {
    tempAudioFiles[i] = await googleSsmlToSpeech(i, ssmlParts[i], type, identifier, synthesizerOptions, storageUploadPath);
  }

我似乎无法使其与Promise.all一起使用。

1 个答案:

答案 0 :(得分:0)

使其正常工作。图书馆的工作似乎与我想象的不同。使用synthesizerOptions创建Object.assign的副本就可以了

工作代码:https://github.com/googleapis/nodejs-text-to-speech/issues/210#issuecomment-487832411

ssmlParts.forEach((ssmlPart: string, index: number) => {
  const synthesizerOptionsCopy = Object.assign({}, synthesizerOptions);
  promises.push(googleSsmlToSpeech(index, ssmlPart, type, identifier, synthesizerOptionsCopy, storageUploadPath));
});
// Inside googleSsmlToSpeech()
const ssmlPartSynthesizerOptions = Object.assign(synthesizerOptions, {
  input: {
    ssml: ssmlPart
  }
});