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

使用ffmpeg.wasm输出图片组时如何提取生成的文件?

解决ffmpeg.wasm生成批量缩略图无法读取文件的问题

问题背景

开发视频上传功能时,已通过ffmpeg.wasm完成视频编码环节,当前需实现DPlayer播放器要求的100张缩略图雪碧图生成功能。执行生成命令后无法提取文件,报错信息:
Uncaught (in promise) Error: ffmpeg.FS('readFile', 'thumbnail%d.png') error. Check if the path exists

问题原因

使用thumbnail%d.png作为输出文件名时,ffmpeg.wasm会生成一系列带序号的独立文件(如thumbnail1.png、thumbnail2.png……),但代码中直接以通配符路径thumbnail%d.png读取文件,该路径并不实际存在,因此触发读取失败。

解决步骤

1. 创建专属输出目录(推荐)

先在ffmpeg文件系统中创建目录存放缩略图,避免文件混乱:

var in_name = "upload.mp4";
var out_dir = "thumbnails";
var out_pattern = `${out_dir}/thumbnail%d.png`;

(async () => {
    await ffmpeg.load();
    // 创建输出目录
    ffmpeg.FS('mkdir', out_dir);
    // 写入待处理视频文件
    ffmpeg.FS('writeFile', in_name, await fetchFile(original_video_file));
    // 执行缩略图生成命令,160秒视频生成100张,即每1.6秒1张
    await ffmpeg.run('-i', in_name, '-vf', 'fps=1/(160/100)', out_pattern);
})();

2. 遍历读取所有生成的缩略图

生成完成后,通过读取目录列表获取所有缩略图文件,再逐个读取:

// 接上述代码
// 获取目录下所有文件
const files = ffmpeg.FS('readdir', out_dir);
// 过滤出png格式的缩略图文件
const thumbnailFiles = files.filter(file => file.endsWith('.png'));
// 逐个读取并转为Blob对象
const thumbnails = thumbnailFiles.map(file => {
    const fileData = ffmpeg.FS('readFile', `${out_dir}/${file}`);
    return new Blob([fileData.buffer], { type: 'image/png' });
});
console.log(thumbnails);

3. 合成DPlayer所需的雪碧图

DPlayer需要单张雪碧图,可通过Canvas将所有缩略图合成:

// 将Blob转为Image对象
function blobToImage(blob) {
    return new Promise((resolve) => {
        const img = new Image();
        img.onload = () => resolve(img);
        img.src = URL.createObjectURL(blob);
    });
}

// 合成雪碧图(按10行10列排列,适配100张图)
async function generateSpriteSheet(thumbnails) {
    const imageElements = await Promise.all(thumbnails.map(blobToImage));
    const singleWidth = imageElements[0].width;
    const singleHeight = imageElements[0].height;
    
    const canvas = document.createElement('canvas');
    canvas.width = singleWidth * 10;
    canvas.height = singleHeight * 10;
    const ctx = canvas.getContext('2d');
    
    imageElements.forEach((img, index) => {
        const x = (index % 10) * singleWidth;
        const y = Math.floor(index / 10) * singleHeight;
        ctx.drawImage(img, x, y);
    });
    
    // 生成雪碧图Blob
    canvas.toBlob(blob => {
        // 此处可处理雪碧图,比如上传或预览
        console.log('雪碧图生成完成', blob);
    }, 'image/png');
}

// 调用合成函数
generateSpriteSheet(thumbnails);

注意事项

  • 确保使用最新稳定版ffmpeg.wasm,避免版本兼容性问题;
  • 若视频时长变动,需动态计算fps参数:fps=1/(视频总时长/100);
  • 处理大量图片时需注意浏览器内存占用,避免崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:35:01