1

I'm working on getting an audiofile from Google Text-to-Speech and then writing the file to Firebase Storage. I don't understand where I specify the path to the location in Storage. I tried:


    const bucket = storage.bucket('myProject-cd99d.appspot.com/Audio/Spanish/test.ogg');

but I get an error message: TypeError: Path must be a string. Here's the cloud function:

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;

        // boilerplate 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/Audio/Spanish/test.ogg');

        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
        // response.audioContent is the downloaded file
        await bucket.upload(response.audioContent, {
          metadata: 'public, max-age=31536000'
        })
        .then(function() {
          console.log('Uploaded file.');
        })
        .catch(function(error) {
          console.error(error);
        });
      }
      catch (error) {
        console.error(error);
      }
    }
    test();
  } // close if
  return 0;
});

I also need to return the main function.

Thomas David Kehoe
  • 10,040
  • 14
  • 61
  • 100

1 Answers1

2

In Cloud Storage, a bucket refers to the container where your files go. It doesn't refer to a file itself. It looks like you're assuming that a bucket is actually a file, which is not correct.

Your bucket name is this:

const bucketName = 'myProject-cd99d.appspot.com'

Your file path in that bucket is this:

const filePath = '/Audio/Spanish/test.ogg'

You build a Bucket object like this:

const bucket = storage.bucket(bucketName)

Then upload a file to that path using the upload() method on Bucket:

bucket.upload(response.audioContent, {
    destination: filePath
})

Be sure to click through to all these links to the API docs so you can better understand how the APIs work.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Doug, the API documentation for bucket.upload() says that the first parameter is the file to be uploaded: upload(pathString, options, callback) The fully qualified path to the file you wish to upload to your bucket. You said, "Then upload a file to that path using the upload() method on Bucket:" I think you meant "upload a file from that path to the bucket." I've written a new question, we're looking forward to your answer: https://stackoverflow.com/questions/54241849/save-an-audiofile-from-google-text-to-speech-to-firebase-storage-using-google-cl – Thomas David Kehoe Jan 17 '19 at 18:16
  • 1
    I edited the answer here to reflect the correct usage. – Doug Stevenson Jan 17 '19 at 18:20