且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 Google Cloud Storage 将音频文件从 Google Text-to-Speech 保存到 Firebase Storage?

更新时间:2022-06-24 21:55:45

file.save() 就是答案.util.promisify 是不必要的,并且会导致关于 original 的错误消息.这是完成的云函数:

file.save() was the answer. util.promisify was unnecessary, and causes an error message about original something. Here's the finished cloud function:

const functions = require('firebase-functions');

// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
//  response.send("Hello from Firebase!");
// });

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(() => {
                  console.log("File written to Firebase Storage.")
                  return;
                })
                .catch((error) => {
                  console.error(error);
                });
            } // close try
            catch (error) {
              console.error(error);
            } // close catch
    } // close async function declaration

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


    }); // close Google_T2S

我们收到一个错误TypeError: [ERR_INVALID_ARG_TYPE]: The "original" argument must be of type function at Object.promisify.此错误似乎不会影响云功能.

We're getting an error TypeError: [ERR_INVALID_ARG_TYPE]: The "original" argument must be of type function at Object.promisify. This error doesn't appear to effect the cloud function.

重申那些不起作用的东西,fs.createWriteStream 不起作用,因为 Google Cloud Functions 无法处理 节点文件系统 命令.相反,Google Cloud Functions 有自己的 方法Node 文件系统命令.bucket.upload() 将上传本地文件到存储桶,但本地文件的路径必须是字符串,而不是缓冲区或来自 API 的流.file.save() 记录为

To reiterate the stuff that didn't work, fs.createWriteStream didn't work because Google Cloud Functions can't handle Node file system commands. Instead, Google Cloud Functions have their own methods that wrap the Node file system commands. bucket.upload() will upload a local file to a bucket, but the path to the local file has to be a string, not a buffer or a stream coming from an API. file.save() is documented as

将任意数据写入文件.

这是一个包装File#createWriteStream的便捷方法.

This is a convenience method which wraps File#createWriteStream.

这就是我想要的!如果我的数据有一件事,那是任意的.或者可能是天生相反.之后我们只需要理顺contentType(audio/mpeg,而不是mp3)和文件路径.

That's what I want! If there's one thing about my data, it's arbitrary. Or maybe contrary by nature. After that we just had to straighten out the contentType (audio/mpeg, not mp3) and the file path.