Получение звука последнего запроса только при выполнении нескольких запросов одновременно с использованием Google Text to Speech API - PullRequest
2 голосов
/ 29 апреля 2019

При выполнении нескольких запросов одновременно, используя Promise.all, я, похоже, получаю только audioContent последнего разрешающего запроса.

Я синтезирую большие тексты и мне нужно разделить их, используяОграничение символов в API.

У меня раньше это работало, так что я знаю, что оно должно работать, но недавно перестало работать.

Я делаю то же самое с Полли Амазонки, и там это работает.Это точно такой же код, но с другим клиентом и другими вариантами запроса.

Так, что заставило меня задуматься, может быть, это библиотека?Или проблема службы 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 голосов
/ 30 апреля 2019

Получил это работает. Библиотека, кажется, делает вещи не так, как я думал. Создание копии 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
  }
});
...