簡體   English   中英

從雲功能觸發器將圖像上傳到雲存儲

[英]Upload Image to Cloud Storage from Cloud Function Trigger

我目前正在尋求有關由Cloud Storage Upload觸發的Cloud Function的幫助。 它檢查文件是否為視頻,如果是,則通過ffmpeg處理該視頻,以提取單個幀以供稍后用於海報圖像。

除了將圖像上傳回Cloud Storage無效外,其他一切似乎都正常。 在我的Cloud Function所在的位置,它根本不會產生任何錯誤,因此我不知道為什么將映像上傳到Cloud Storage無效。 如果有經驗的人可以在下面查看我的Cloud Function並提供一些無法使用的功能的見解,我將不勝感激。 如果可能的話請咨詢!! 謝謝!!!! ^ _ ^

注意:代碼片段下方提供了Cloud Function Log的屏幕快照。

const admin = require('firebase-admin'); // Firebase Admin SDK
const functions = require('firebase-functions'); // Firebase Cloud Functions
const gcs = require('@google-cloud/storage')(); // Cloud Storage Node.js Client
const path = require('path'); // Node.js file and directory utility
const os = require('os'); // Node.js operating system-related utility
const fs = require('fs'); // Node.js file system API
const ffmpeg = require('fluent-ffmpeg');
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ffprobePath = require('@ffprobe-installer/ffprobe').path;

// Initialize Firebase Admin
admin.initializeApp(functions.config().firebase);

// Listen for changes in Cloud Storage bucket
exports.storageFunction = functions.storage.object()
  .onChange((event) => {
    const file = event.data; // The Storage object.
    const fileBucket = file.bucket; // The Storage bucket that contains the file.
    const filePath = file.name; // File path in the bucket.
    const fileName = path.basename(filePath); // Get the file name.
    const fileType = file.contentType; // File content type.

    if (!fileType.startsWith('video/')) {
      return;
    }

    const bucket = gcs.bucket(fileBucket);
    const tempFilePath = path.join(os.tmpdir(), fileName);
    const tempFolderPath = os.tmpdir();

    // Download video to temp directory
    return bucket.file(filePath).download({
      destination: tempFilePath
    }).then(() => {
      console.log('Video downloaded locally to', tempFilePath);

      // Generate screenshot from video
      ffmpeg(tempFilePath)
        .setFfmpegPath(ffmpegPath)
        .setFfprobePath(ffprobePath)
        .on('filenames', (filenames) => {
          console.log(`Will generate ${filenames}`);
        })
        .on('error', (err) => {
          console.log(`An error occurred: ${err.message}`);
        })
        .on('end', () => {
          console.log(`Output image created at ${tempFilePath}`);

          const targetTempFileName = `${fileName}.png`;
          const targetFilePath = path.join(path.dirname(filePath), targetTempFileName);

          console.log(targetTempFileName);
          console.log(targetFilePath);

          // Uploading the image.
          return bucket.upload(tempFilePath, { destination: targetFilePath })
          .then(() => {
            console.log('Output image uploaded to', filePath);
          })
          .catch((err) => {
            console.log(err.message);
          });
        })
        .screenshots({
          count: 1,
          folder: tempFolderPath
        });
    });
});

雲功能日志

看來您正在嘗試從ffmpeg回調API返回承諾:

.on('end', () => {
   return bucket.upload(tempFilePath, { destination: targetFilePath })
   .then(...)
})

我不知道ffmpeg API,但我幾乎可以肯定不會導致該函數等待上載完成。 取而代之的是,您需要直接從您的函數返回一個承諾,該承諾僅在所有異步工作完成后才能解析。

如果最后一項工作在回調中,而您需要等待,則可以將整個內容包裝到一個新的Promise中,並在適當的時間手動解決它。 用偽代碼:

return new Promise((resolve, reject) => {
    // ffmpeg stuff here...
    .on('end', () => {
        // the last bit of work here...
        bucket.upload(...)
        .then(() => { resolve() })
    })
})

注意如何調用新promise提供的resolve方法,以指示該promise何時應自行解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM