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

Node.js中使用FFmpeg生成视频截图后无法找到文件的问题求助

问题:fluent-ffmpeg截图日志显示成功但文件不存在

实现代码

const ffmpegPath = require('@ffmpeg-installer/ffmpeg');
import ffmpeg from 'fluent-ffmpeg';
import path from 'path';
const os = require('os');
ffmpeg.setFfmpegPath(ffmpegPath.path);

export const generateThumbnailFromVideo = async (mp4Buffer) => {
    console.log('generateThumbnailFromVideo is triggered');
    const timePosition = '00:00:00.500';
    const filename = `temp/temp-${new Date().getTime()}.png`;
    return new Promise((resolve, reject) => {
        ffmpeg({
            source: bufferToStream(mp4Buffer)
        })
        .on('error', (err) => {
            console.error('An error occurred: ' + err.message);
            reject(err);
        })
        .on('end', () => {
            console.log('Thumbnail generated successfully');
            fs.readFile(filename, (err, data) => {
                if (err) {
                    console.error('An error occurred while reading the thumbnail file:', err);
                    reject(err);
                    return;
                }
                fs.unlink(filename);
                uploadBuffer(data, filename, data.length)
            })
            resolve(filename);
        })
        .screenshots({
            timestamps: [timePosition],
            filename: filename,
            folder: 'temp/',
            size: '320x240',
        });
    });
}

运行日志

generateThumbnailFromVideo is triggered
Thumbnail generated successfully
createProjectMedia is triggered
userId:  1
projectId:  25
mediaArray:  [
  {
    mediaUrl: 'medias/1/1686843801535/medias_1_1684753043519_1_(1)_(4)_(1).mp4',
    thumbnailUrl: 'medias/1/1686843801535/medias_1_1684753043519_1_(1)_(4)_(1)_thumbnail.jpg',
    mediaType: 2
  }
]
An error occurred while reading the thumbnail file: [Error: ENOENT: no such file or directory, open 'temp/temp-1686843802255.png'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'temp/temp-1686843802255.png'
}

问题细节

  • 日志打印Thumbnail generated successfully,但项目根目录的temp文件夹始终为空,找不到生成的png文件
  • 尝试用__dirname和os.tmpdir()设置绝对路径,无效
  • 已确认temp目录存在:删除temp会触发目录不存在的错误,重建后该错误消失
  • 移除fs.unlink(filename)语句后,情况依旧

解决方案

1. 修复路径拼接冲突

你在screenshots配置中同时设置了带路径的filename和folder参数,fluent-ffmpeg会自动拼接两个路径,最终生成的文件路径是temp/temp/temp-xxxxxx.png(而非预期的temp/temp-xxxxxx.png),这就是根目录temp为空的原因。

两种修改方式:

方式一:保留folder,filename仅写文件名

const filename = `temp-${new Date().getTime()}.png`;
// ...
.screenshots({
    timestamps: [timePosition],
    filename: filename,
    folder: 'temp/',
    size: '320x240',
});

方式二:移除folder,filename写完整路径

const filename = `temp/temp-${new Date().getTime()}.png`;
// ...
.screenshots({
    timestamps: [timePosition],
    filename: filename,
    size: '320x240',
});

2. 纠正Promise.resolve的时机

当前代码在end事件中先调用resolve(filename),再执行文件读取逻辑,会导致Promise提前完成,后续操作可能中断。需要把resolve移到文件读取成功的回调内:

.on('end', () => {
    console.log('Thumbnail generated successfully');
    fs.readFile(filename, (err, data) => {
        if (err) {
            console.error('An error occurred while reading the thumbnail file:', err);
            reject(err);
            return;
        }
        fs.unlink(filename, (unlinkErr) => {
            if (unlinkErr) {
                console.error('Failed to delete temp file:', unlinkErr);
            }
            uploadBuffer(data, filename, data.length);
            resolve(filename); // 移至此处
        });
    });
})

3. 增加文件生成校验

添加filenames事件监听实际生成的文件路径,方便排查:

.on('filenames', (filenames) => {
    console.log('实际生成的文件路径:', filenames);
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:40:31