使用Google Cloud Storage将音频文件从Google文本语音转换到Firebase存储吗?

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

我们正在尝试使用Google Cloud Function从Google文本到语音转换获取音频文件并将其保存到Firebase存储。 Google文本到语音转换的documentation显示如何获取音频文件并将其保存在本地:

// Performs the Text-to-Speech request
const [response] = await client.synthesizeSpeech(request);
// Write the binary audio content to a local file
const writeFile = util.promisify(fs.writeFile);
await writeFile('output.mp3', response.audioContent, 'binary');
console.log('Audio content written to file: output.mp3');

这将导致错误消息Error: EROFS: read-only file system。 Google云端存储不允许在本地写入文件。

使用Firebase存储bucket.upload()有一些问题:

   const destinationPath = 'Audio/Spanish' + filename.ogg;
   // Performs the Text-to-Speech request
   const [response] = await client.synthesizeSpeech(request);
   // response.audioContent is the downloaded file
   await bucket.upload(response.audioContent, {
      destination: destinationPath
   ));

错误消息是TypeError: Path must be a stringbucket.upload()的第一个参数是The fully qualified path to the file you wish to upload to your bucket.,并且应为字符串,因此response.audioContent不起作用。

documentationbucket.upload()表示destination: destinationPath是我们应放置Firebase存储位置的路径。这是正确的吗?

我们如何从Google文本语音转换(response.audioContent)中获取音频文件并将其另存为bucket.upload()可以访问的字符串?还是应该使用其他内容代替bucket.upload()

这是我们的完整云功能:

exports.Google_T2S = functions.firestore.document('Users/{userID}/Spanish/T2S_Request').onUpdate((change, context) => {
  if (change.after.data().word != undefined) {

    // Performs the Text-to-Speech request
    async function test() {
      try {
        const word = change.after.data().word; // the text
        const longLanguage = 'Spanish';
        const audioFormat = '.mp3';
        // copied from https://cloud.google.com/text-to-speech/docs/quickstart-client-libraries#client-libraries-usage-nodejs
        const fs = require('fs');
        const util = require('util');
        const textToSpeech = require('@google-cloud/text-to-speech'); // Imports the Google Cloud client library
        const client = new textToSpeech.TextToSpeechClient(); // Creates a client

        let myWordFile = word.replace(/ /g,"_"); // replace spaces with underscores in the file name
        myWordFile = myWordFile.toLowerCase(); // convert the file name to lower case
        myWordFile = myWordFile + audioFormat; // append .mp3 to the file name;

        // copied from https://cloud.google.com/blog/products/gcp/use-google-cloud-client-libraries-to-store-files-save-entities-and-log-data
        const {Storage} = require('@google-cloud/storage');
        const storage = new Storage();
        const bucket = storage.bucket('myProject-cd99d.appspot.com');
        const destinationPath = 'Audio/Spanish/' + myWordFile;

        const request = { // Construct the request
          input: {text: word},
          // Select the language and SSML Voice Gender (optional)
          voice: {languageCode: 'es-ES', ssmlGender: 'FEMALE'},
          // Select the type of audio encoding
          audioConfig: {audioEncoding: 'MP3'},
        };

        const [response] = await client.synthesizeSpeech(request);
        // Write the binary audio content to a local file
        const writeFile = util.promisify(fs.writeFile);
        await writeFile('output.mp3', response.audioContent, 'binary');
        console.log('Audio content written to file: output.mp3')
        // response.audioContent is the downloaded file

        await bucket.upload(response.audioContent, {
          destination: destinationPath
        });
      }
      catch (error) {
        console.error(error);
      }
    }
    test();
  } // close if
  return 0; // prevents an error message "Function returned undefined, expected Promise or value"
});
node.js firebase google-cloud-functions firebase-storage google-text-to-speech
1个回答
2
投票

file.save()是答案。 util.promisify是不必要的,并且会导致有关original的错误消息。这是完成的云功能:

exports.Google_T2S = functions.firestore.document('Users/{userID}/Spanish/T2S_Request').onUpdate((change, context) => {
  if (change.after.data().word != undefined) {

    async function textToSpeechRequest() {
      try {
        const word = change.after.data().word; // the text
        const longLanguage = 'Spanish';
        const audioFormat = '.mp3';
        // copied from https://cloud.google.com/text-to-speech/docs/quickstart-client-libraries#client-libraries-usage-nodejs
        const util = require('util');
        const textToSpeech = require('@google-cloud/text-to-speech'); // Imports the Google Cloud client library
        const client = new textToSpeech.TextToSpeechClient(); // Creates a client

        let myWordFile = word.replace(/ /g,"_"); // replace spaces with underscores in the file name
        myWordFile = myWordFile.toLowerCase(); // convert the file name to lower case
        myWordFile = myWordFile + audioFormat; // append .mp3 to the file name;

        // copied from https://cloud.google.com/blog/products/gcp/use-google-cloud-client-libraries-to-store-files-save-entities-and-log-data
        const {Storage} = require('@google-cloud/storage');
        const storage = new Storage();
        const bucket = storage.bucket('myProject-cd99d.appspot.com');
        var file = bucket.file('Audio/Spanish/' + myWordFile);

        const request = { // Construct the request
          input: {text: word},
          // Select the language and SSML Voice Gender (optional)
          voice: {languageCode: 'es-ES', ssmlGender: 'FEMALE'},
          // Select the type of audio encoding
          audioConfig: {audioEncoding: 'MP3'},
        };

        const options = { // construct the file to write
          metadata: {
            contentType: 'audio/mpeg',
            metadata: {
              source: 'Google Text-to-Speech'
            }
          }
        };

        // copied from https://cloud.google.com/text-to-speech/docs/quickstart-client-libraries#client-libraries-usage-nodejs
        const [response] = await client.synthesizeSpeech(request);
        // Write the binary audio content to a local file
        // response.audioContent is the downloaded file
        return await file.save(response.audioContent, options)
        .then(function() {
          console.log("File written to Firebase Storage.")
        })
        .catch(function(error) {
          console.error(error);
        });
    } // close try
    catch (error) {
      console.error(error);
    } // close catch
  } // close async
  textToSpeechRequest();
} // close if
}); // close Google_T2S

我们收到错误TypeError: [ERR_INVALID_ARG_TYPE]: The "original" argument must be of type function at Object.promisify。该错误似乎并未影响云功能。

要重申无效的内容,fs.createWriteStream无效,因为Google Cloud Functions无法处理Node file system命令。相反,Google Cloud Functions具有自己的methods,用于包装Node文件系统命令。 bucket.upload()会将本地文件上传到存储桶,但是本地文件的路径必须是字符串,而不是来自API的缓冲区或流。 file.save()记录为

将任意数据写入文件。

这是包装File#createWriteStream的便捷方法。

这就是我想要的!如果我的数据有问题,那是任意的。或天生相反。之后,我们只需要理顺contentTypeaudio/mpeg,而不是mp3)和文件路径。

© www.soinside.com 2019 - 2024. All rights reserved.