【问题标题】:Downloading an API file to Firebase Cloud Storage?将 API 文件下载到 Firebase 云存储?
【发布时间】:2018-11-07 22:57:06
【问题描述】:

如何将 IBM Watson Text-to-speech 中的音频文件(大约 10K)保存到 Firebase Cloud Storage?这是我的代码,复制自 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);
  });
});

缺少的代码在之间

}).pipe(fs.createWriteStream('hello_world.wav'));

file.download()

不知何故,我必须将 IBM Watson 提供的文件转换为 Firebase Cloud Storage 可识别的文件。 fs 不允许在 Google Cloud Functions 中使用吗?

另外,第 6 行不应该是

var fs = require('fs-js');

不是

var fs = require('fs'); 

根据NPMfs 包已弃用。

Google Cloud Functions 中是否允许使用 pipe?如果是这样,我将文件传送到什么?我需要看起来像这样的东西:

}).pipe(file);
file.download()

【问题讨论】:

  • 我可以帮忙,但我首先有一个问题 - 你需要 file 是什么类型的变量? Buffer?我主要想知道,download() 函数来自哪里 - 还是那个伪代码?
  • 您需要从您的函数中返回一个承诺,当所有工作完成时,该承诺会解决。 pipe 可能是一个异步函数,这意味着您需要开始更仔细地考虑要如何在函数中进行异步编程。
  • Doug,IBM Watson textToSpeech.synthesize 返回一个回调,而不是一个承诺。我会研究谷歌文本到语音,如果它返回一个承诺,它会更容易编码吗?
  • 根据stackoverflow.com/questions/20085513/using-pipe-in-node-js-net,“[Node 中] 的 pipe() 函数在可读流可用时读取数据并将其写入目标可写流。”我想写入文件。我会看看是否有管道到文件节点命令。
  • stackoverflow.com/questions/20085513/using-pipe-in-node-js-net 中的另一个答案说“pipe() 从可读流中读取并写入可写流,就像 Unix 管道一样。它在此过程中会做所有“合理”的事情,但会出错,文件结束,如果一侧落后等。”这听起来像是异步的。

标签: node.js google-cloud-functions firebase-storage text-to-speech ibm-watson


【解决方案1】:

好的,查看file.download() 的文档,我认为您只需对代码稍作改动即可完成这项工作。 file 需要输入来自 Google Storage 库的 File(您需要安装 this library)。这种类型有一个名为createWriteStream 的方法,您可以将synthesize 的结果流式传输到该方法。我没有对此进行测试,但我相信它应该是正确的,或者至少应该为您指明正确的方向:

// 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);
        });
    });
});

记录在案:

  • pipe() 应该在 Google Cloud Functions 中被允许并且它异步的。这就是为什么您需要在下载文件之前监听finish 事件
  • fs 仅在公共 NPM 上被弃用,但这不是您要导入的包,fs(文件系统)模块是 Node's core built-in packages 之一。也就是说,您的代码中似乎根本不需要它

【讨论】:

  • 谢谢,我只是在阅读文档并看到了 file.createWriteStream。运行您的代码,我在 file.createWriteStream 行收到错误消息“文件未定义”。该文档包括“const file = myBucket.file('my-file');”。我会继续努力的。
  • 再次感谢,我已经编写了工作代码作为答案并支持您的答案。
【解决方案2】:

谢谢dpopp07,我明白了!

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;
    });

当一个新单词被写入 Firestore 位置时,该函数会触发,然后提取该单词并将其命名为 myWord。添加 .ogg 会生成 myWordFileType。这些函数向 IBM Watson Text-to-speech 发送一个 HTTP 请求,它返回一个回调,而不是一个承诺,所以代码有点难看。关键是 HTTP 响应通过 Node 命令pipe 将文件发送到 Google Cloud Storage 命令file.createWriteStreamcontentType 必须设置为获得可读文件,但auto 使这变得容易。然后将该文件写入存储桶,该存储桶设置为我的 Firebase Cloud Storage 文件夹Test_Folder,文件名为myWordFileType

【讨论】:

    猜你喜欢
    • 2019-11-15
    • 2020-11-01
    • 2019-10-29
    • 2019-04-26
    • 2017-08-20
    • 2017-08-22
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多