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

使用FFMPEG.js转换Base64 PNG帧为MP4时遇输入无效错误求助

FFMPEG.js转换Canvas PNG帧序列为MP4时"Invalid data found"错误的解决方法

问题概述

尝试将Canvas捕获的Base64编码PNG帧序列通过ffmpeg.js转换为MP4时,出现错误:frame0000.png: Invalid data found when processing input。已验证单帧PNG格式正确,但ffmpeg无法识别输入数据。

环境信息

  • OS: Ubuntu Linux 21.04 (Hirsute Hippo)
  • NPM Version: 9.5.0
  • ffmpeg.js Version: ^2.8.9001
  • Browser: Chromium 125.0.6422.60 snap

核心错误点及修正方案

1. 无效的MEMFS文件写入逻辑

你循环调用ffmpeg({MEMFS: [file], ...})试图“写入”文件,但ffmpeg.js的每次调用都是独立的沙箱实例,前一次的MEMFS数据不会被保留到下一次调用中。这段代码完全无意义,直接删除即可。

2. 错误的FFMPEG命令构建

当前代码为每个帧单独添加-i参数,这会让ffmpeg将每个PNG视为独立的输入流,而非连续的帧序列。正确的做法是使用通配符语法让ffmpeg自动识别编号连续的帧序列:

修正前错误命令构建:

let command = `-loglevel debug -framerate 30`;
inputFiles.forEach((buffer, index) => {
    command += ` -i frame${index.toString().padStart(4, '0')}.png`;
});
command += ` -c:v libx264 -pix_fmt yuv420p ${outputFileName}`;

修正后的命令构建(用数组避免字符串拆分问题):

const command = [
  '-loglevel', 'debug',
  '-framerate', '30',
  '-i', 'frame%04d.png', // 匹配4位编号的帧文件(frame0000.png ~ frame0024.png)
  '-c:v', 'libx264',
  '-pix_fmt', 'yuv420p',
  outputFileName
];

3. 优化Base64转换的鲁棒性(可选)

虽然你的签名验证通过,但可以对转换函数做小优化,兼容带DataURL前缀和纯Base64两种格式:

#base64ToUint8Array(base64) {
    // 兼容带DataURL前缀和纯Base64两种格式
    const base64Data = base64.includes(',') ? base64.split(',')[1] : base64;
    const binaryString = atob(base64Data);
    const bytes = new Uint8Array(binaryString.length);
    for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
    }
    return bytes;
}

修正后的完整执行代码

import ffmpeg from 'ffmpeg.js/ffmpeg-mp4.js';

// 转换帧为MEMFS格式
const inputFiles = videoFrames.map((dataUrl, index) => ({
    name: `frame${index.toString().padStart(4, '0')}.png`,
    data: this.#base64ToUint8Array(dataUrl)
}));

// 验证PNG签名(保留原有逻辑)
inputFiles.forEach(file => {
    if (!this.#isValidPNG(file.data)) {
        throw new Error(`Invalid PNG file: ${file.name}`);
    }
});

// 构建正确的FFMPEG命令
const command = [
  '-loglevel', 'debug',
  '-framerate', '30',
  '-i', 'frame%04d.png',
  '-c:v', 'libx264',
  '-pix_fmt', 'yuv420p',
  outputFileName
];

// 执行转换
const result = ffmpeg({
    MEMFS: inputFiles,
    arguments: command,
    stdin: () => { },
});

额外检查点

  • 确保所有帧文件名严格符合frame%04d.png格式(你的padStart(4, '0')已经正确实现)
  • 如果仍有问题,查看ffmpeg的debug日志,确认MEMFS中文件的大小与预期一致,排除数据截断问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:12:07