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

如何将fluent-ffmpeg转换后的视频直接上传至S3而不存储在本地?

ffmpeg输出直接写入S3实现方案

完全可以实现ffmpeg转码结果直接存入S3,不需要生成本地临时文件,核心是利用ffmpeg的流输出能力对接S3的流式上传接口。

你现有代码的问题是先把转码结果写到本地磁盘,再读取文件上传,额外增加了磁盘IO开销,大文件场景下效率极低还容易占满本地存储空间,优化后的实现代码如下:

const AWS = require('aws-sdk');
const ffmpeg = require('fluent-ffmpeg');
const { PassThrough } = require('stream');

// S3实例初始化逻辑和你原有代码保持一致即可
const s3 = new AWS.S3({
    endpoint: 's3-ap-south-1.amazonaws.com',
    accessKeyId: S3_ACCESS_KEY_ID,
    secretAccessKey: S3_ACCESS_SECRET_KEY,
    signatureVersion: 'v4',
    region: 'ap-south-1'
});

const signedUrlExpireSeconds = 3600; // 替换为你自己的签名有效期
const S3_BUCKET_NAME = '你的存储桶名'; // 替换为实际值
const S3_STORE_PATH = '你的S3路径前缀'; // 替换为实际值

var params = {
    Bucket: S3_BUCKET_NAME,
    Delimiter: '',
    Prefix: S3_STORE_PATH
};

s3.listObjects(params, function (err, data) {
    if (err) throw err;
    data.Contents.forEach(async function (obj, index) {
        const file_name = obj.Key;
        const type = "mp4";
        const url = s3.getSignedUrl('getObject', {
            Bucket: S3_BUCKET_NAME,
            Key: obj.Key,
            Expires: signedUrlExpireSeconds
        });
        const filename = file_name.split('.').slice(0, -1).join('.');
        const outputKey = `${filename}.${type}`;

        // 创建中转流,对接ffmpeg输出和S3上传
        const passThroughStream = new PassThrough();
        
        // 启动S3上传,直接把流作为Body参数
        const uploadPromise = s3.upload({
            Bucket: S3_BUCKET_NAME,
            Key: outputKey,
            Body: passThroughStream,
            ContentType: 'video/mp4'
        }).promise();

        // 执行ffmpeg转码,输出直接写入中转流,不生成本地文件
        await new Promise((resolve, reject) => {
            ffmpeg()
                .input(url)
                .toFormat('mp4')
                // 输出到流,而不是本地文件
                .output(passThroughStream, { end: true })
                .on('end', () => {
                    resolve();
                })
                .on('error', (err) => {
                    reject(err);
                })
                .run();
        });

        // 等待S3上传完成
        await uploadPromise;
        console.log(`文件${outputKey}转码并上传成功`);
    });
});

注意事项

  • 这里使用s3.upload而非putObject,支持自动分块上传,大视频文件不会占用过高内存,上传稳定性更高
  • 全程没有本地文件读写操作,转码后的数据流直接传递给S3上传接口,资源占用更低
  • 生产环境建议补充异常捕获逻辑,处理转码失败、上传失败的场景,避免进程崩溃
  • 可以根据业务需求添加ffmpeg的编码参数,比如分辨率、码率、帧率配置,不影响流输出逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:09:05