You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Cloud Storage的WritableStream是否有文档?如何等待上传完成?

关于Google Cloud Storage WritableStream的文档与上传完成等待方案

一、WritableStream的文档说明

bucket.file(dstFile).createWriteStream()返回的其实是Node.js原生的stream.Writable对象,GCS的Node.js客户端只是基于这个原生流做了封装,用来和GCS存储服务交互,所以核心的流操作逻辑完全遵循Node.js的标准流规范,相关细节可以参考Node.js官方的Stream模块文档。

二、等待上传完成的具体实现

你遇到的问题本质是GCF异步执行特性导致的:ffmpeg处理完输出后,流可能还在后台向GCS上传数据,这时候直接返回函数会让上传过程被中断,最终导致目标文件未完全生成。下面两种方法可以帮你解决这个问题:

方法1:用Promise包裹流事件监听

把流的finish(上传完成)和error(上传出错)事件转换成Promise,配合async/await确保上传完成后再结束函数:

const { Storage } = require('@google-cloud/storage');
const storage = new Storage();
const ffmpeg = require('fluent-ffmpeg');

exports.transcodeVideo = async (req, res) => {
  const srcBucket = storage.bucket('你的源存储桶名称');
  const dstBucket = storage.bucket('你的目标存储桶名称');
  const srcFile = '源文件路径';
  const dstFile = '转码后目标文件路径';

  // 创建GCS写入流
  const remoteWriteStream = dstBucket.file(dstFile).createWriteStream();

  // 用Promise封装流的完成与错误事件
  const waitForUpload = new Promise((resolve, reject) => {
    remoteWriteStream.on('finish', resolve);
    remoteWriteStream.on('error', reject);
  });

  // 执行ffmpeg转码并将输出管道到GCS写入流
  ffmpeg(srcBucket.file(srcFile).createReadStream())
    .outputOptions('-vcodec', 'libx264', '-acodec', 'aac') // 示例转码参数,可按需调整
    .pipe(remoteWriteStream);

  try {
    // 等待上传完成
    await waitForUpload;
    res.status(200).send('转码并上传完成');
  } catch (err) {
    console.error('上传失败:', err);
    res.status(500).send('转码上传失败');
  }
};

方法2:使用stream/promises的finished方法(Node.js 15+支持)

如果你的GCF运行环境Node.js版本在15及以上,可以用Node.js原生的stream/promises模块简化代码,它提供的finished方法可以直接等待流完成:

const { Storage } = require('@google-cloud/storage');
const { finished } = require('stream/promises');
const storage = new Storage();
const ffmpeg = require('fluent-ffmpeg');

exports.transcodeVideo = async (req, res) => {
  // ... 前面的存储桶、文件路径定义和方法1一致

  const remoteWriteStream = dstBucket.file(dstFile).createWriteStream();

  ffmpeg(srcBucket.file(srcFile).createReadStream())
    .outputOptions('-vcodec', 'libx264', '-acodec', 'aac')
    .pipe(remoteWriteStream);

  try {
    // 等待流完成
    await finished(remoteWriteStream);
    res.status(200).send('转码并上传完成');
  } catch (err) {
    console.error('上传失败:', err);
    res.status(500).send('转码上传失败');
  }
};

注意事项

  • 务必监听error事件,避免上传出错时函数静默失败,同时未处理的错误会导致GCF异常终止。
  • 如果你的GCF环境Node.js版本较低(低于15),建议用第一种方法,或者手动安装stream-finished第三方包来替代原生的stream/promises功能。

内容的提问来源于stack exchange,提问作者GaryO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:59:03