【问题标题】:The file I converted with FFMPEG in Firebase Cloud function is not accessable我在 Firebase Cloud 功能中使用 FFMPEG 转换的文件不可访问
【发布时间】:2020-05-06 13:23:57
【问题描述】:

以下是我的云功能代码。

    exports.increaseVolume = functions.storage.object().onFinalize(async (object) => {
    const fileBucket = object.bucket; // The Storage bucket that contains the file.
    const filePath = object.name; // File path in the bucket.
    const contentType = object.contentType; // File content type.

    // Exit if this is triggered on a file that is not an audio.
    if (!contentType.startsWith('video/mp4')) {
      console.log('This is not an audio.');
      return null;
    }

    // Get the file name.
    const fileName = path.basename(filePath);
    // Exit if the audio is already converted.
    if (fileName.endsWith('_output.mp4')) {
      console.log('Already a converted audio.');
      return null;
    }

    // Download file from bucket.
    const bucket = gcs.bucket(fileBucket);
    const tempFilePath = path.join(os.tmpdir(), fileName);
    // We add a '_output.flac' suffix to target audio file name. That's where we'll upload the converted audio.
    const targetTempFileName = fileName.replace(/\.[^/.]+$/, '') + '_output.mp4';
    const targetTempFilePath = path.join(os.tmpdir(), targetTempFileName);
    const targetStorageFilePath = path.join(path.dirname(filePath), targetTempFileName);

    await bucket.file(filePath).download({destination: tempFilePath});
    console.log('Audio downloaded locally to', tempFilePath);
    // Convert the audio to mono channel using FFMPEG.

    let command = ffmpeg(tempFilePath)
        .audioFilters([
        {
          filter: 'volume',
          options: '5dB'
        },
        {
          filter: 'afftdn'
        }
      ])
        .format('mp4')
        .output(targetTempFilePath);

    await promisifyCommand(command);
    console.log('Output audio created at', targetTempFilePath);
    // Uploading the audio.
    await bucket.upload(targetTempFilePath, {destination: targetStorageFilePath});

    console.log('Output audio uploaded to', targetStorageFilePath);

    // Once the audio has been uploaded delete the local file to free up disk space.
    fs.unlinkSync(tempFilePath);
    fs.unlinkSync(targetTempFilePath);

    return console.log('Temporary files removed.', targetTempFilePath);
  });

这是我存储桶中文件的显示方式。我在哪里可以获得下载链接或如何访问该文件?当我在浏览器中输入链接时,它会返回一个 JSON 表示 403 - 未经授权的访问。

【问题讨论】:

    标签: javascript node.js firebase google-cloud-functions google-cloud-storage


    【解决方案1】:

    你需要使用getSignedUrl()方法如下:

    const uploadResp = await bucket.upload(targetTempFilePath, {destination: targetStorageFilePath});
    
    const file = uploadResp[0];
    
    const options = {
           action: 'read',
           expires: '03-17-2025'
    };
    
    const getSignedUrlResponse = await file.getSignedUrl(options);
    const url = getSignedUrlResponse[0];
    
    //Do wathever you want with this url: save it in Firestore for example
    

    【讨论】:

      【解决方案2】:

      您面临的消息是关于权限的。谁应该有权访问什么?

      首先,您必须考虑您的业务逻辑。谁应该有权访问该文件?如果该文件应该是公开的,这很好吗?是否有可以访问文件的时间范围?数据应该保留在 Bucket 中还是可以删除?

      我认为你有两种选择:

      1. 使用public data 创建一个桶,在这种情况下,每个有权访问桶中特定文件名的人都可以访问数据。

      2. 如果以上不允许,那么您可以创建一个SignedURL,如@Renaud Tarnec link example 所述。您应该记住,SignedURL 具有时间限制的访问权限,拥有它的 URL 的每个人都将能够获取该对象。一旦时间到期,该对象将无法再访问。

      一旦你定义了这个,你可以delete the object in your Bucket programatically或者你可以设置一个Lifecycle Management。在那里,您可以设置包含一组规则的配置,例如,删除按年龄(以天为单位)创建的对象。

      【讨论】:

        猜你喜欢
        • 2018-06-20
        • 2018-03-04
        • 1970-01-01
        • 2017-11-03
        • 2020-04-18
        • 2020-04-12
        • 2020-10-20
        • 2019-12-11
        • 2017-10-27
        相关资源
        最近更新 更多