How do I save an audio file (about 10K) from IBM Watson Text-to-speech to Firebase Cloud Storage? Here's my code, copied from the IBM Watson documentation :
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
var TextToSpeechV1 = require('watson-developer-cloud/text-to-speech/v1');
var fs = require('fs');
exports.TextToSpeech = functions.firestore.document('Test_Value').onUpdate((change, context) => {
var textToSpeech = new TextToSpeechV1({
username: 'groucho',
password: 'swordfish',
url: 'https://stream.watsonplatform.net/text-to-speech/api'
});
var synthesizeParams = {
text: 'Hello world',
accept: 'audio/wav',
voice: 'en-US_AllisonVoice'
};
textToSpeech.synthesize(synthesizeParams).on('error', function(error) {
console.log(error);
}).pipe(fs.createWriteStream('hello_world.wav')); // what goes here?
const file = ?????
file.download()
.then(function(data) {
console.log("File downloaded."
})
.catch(error => {
console.error(error);
});
});
The missing code is between
}).pipe(fs.createWriteStream('hello_world.wav'));
and
file.download()
Somehow I have to convert the file provided by IBM Watson into a file that Firebase Cloud Storage recognizes. Is fs
not allowed in Google Cloud Functions?
Also, shouldn't line 6 be
var fs = require('fs-js');
not
var fs = require('fs');
According to NPM the fs
package is deprecated.
Is pipe
allowed in Google Cloud Functions? If so, what do I pipe the file to? I need something that looks like this:
}).pipe(file);
file.download()
Okay, reviewing the documentation for file.download()
, I think you can make this work with little change to your code. file
needs to be type File
from the Google Storage library (you'll need to install this library ). This type has a method called createWriteStream
that you can stream the results of synthesize
to. I didn't test this but I believe it should be correct or should at least point you in the right direction:
// looks like you'll need to require this package also
const { Storage } = require('@google-cloud/storage');
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
var TextToSpeechV1 = require('watson-developer-cloud/text-to-speech/v1');
var fs = require('fs');
const storage = new Storage();
const myBucket = storage.bucket('my-bucket');
exports.TextToSpeech = functions.firestore.document('Test_Value').onUpdate((change, context) => {
var textToSpeech = new TextToSpeechV1({
username: 'groucho',
password: 'swordfish',
url: 'https://stream.watsonplatform.net/text-to-speech/api'
});
var synthesizeParams = {
text: 'Hello world',
accept: 'audio/wav',
voice: 'en-US_AllisonVoice'
};
const file = myBucket.file('my-file'); // name your file something here
textToSpeech
.synthesize(synthesizeParams)
.on('error', function(error) {
console.log(error);
})
.pipe(file.createWriteStream()) // the File object has a `createWriteStream` method for writing streams to it
.on('error', function(err) {
console.log(err);
})
.on('finish', function() {
// The file upload is complete.
file.download()
.then(function(data) {
console.log("File downloaded.");
})
.catch(error => {
console.error(error);
});
});
});
For the record:
pipe()
should be allowed in Google Cloud Functions and it is async. This is why you need to listen for the finish
event before downloading the file fs
is only deprecated on public NPM but that is not the package you were importing, the fs
(file system) module is one of Node's core built-in packages . That said, it looks like you might not need it in your code at all Thanks dpopp07, I got it!
exports.TextToSpeech = functions.firestore.document('Test_Word').onUpdate((change, context) => {
if (change.after.data().word != undefined) {
myWord = change.after.data().word;
myWordFileType = myWord + '.ogg';
var synthesizeParams = {
text: myWord,
accept: 'audio/ogg',
voice: 'en-US_AllisonVoice'
};
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const bucket = storage.bucket('myapp.appspot.com');
const file = bucket.file('Test_Folder' + myWordFileType);
var TextToSpeechV1 = require('watson-developer-cloud/text-to-speech/v1');
var textToSpeech = new TextToSpeechV1({
username: 'groucho',
password: 'swordfish',
url: 'https://stream.watsonplatform.net/text-to-speech/api'
});
textToSpeech.synthesize(synthesizeParams).on('error', function(error) {
console.log(error);
}).pipe(file.createWriteStream({contentType: 'auto'}))
.on('error', function(err) {})
.on('finish', function() {
console.log("Complete.");
});
}
return 0;
});
The function triggers when a new word is written to a Firestore location, then extracts the word and calls it myWord
. Adding .ogg makes myWordFileType
. The functions sends an HTTP request to IBM Watson Text-to-speech, which returns a callback, not a promise, so the code is a bit ugly. The crux is where the HTTP response goes through Node command pipe
to the send the file to the Google Cloud Storage command file.createWriteStream . The contentType
must be set to get a readable file, but auto
makes this easy. The file is then written to the bucket, which is set to my Firebase Cloud Storage folder Test_Folder
and the filename is myWordFileType
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.