问题
多个视频同时压缩时,第一个视频压缩成功后读取不出来
部分代码
const compressVideo = async (file) => {
console.log(1)
const inputFileName = file.name;
const outputFileName = 'compressed_' + inputFileName;
await ffmpegRef.current.load();
await ffmpegRef.current.writeFile(inputFileName, await fetchFile(file)); //慢
console.log(2)
// 执行 FFmpeg 命令
await ffmpegRef.current.exec(['-i', inputFileName, '-vf', 'scale=320:240', outputFileName]); //慢
console.log(3)
const compressedVideo =await ffmpegRef.current.readFile(outputFileName); //快
console.log(4)
const blob = new Blob([compressedVideo.buffer], { type: 'video/mp4' });
const compressedFile = new File([blob], outputFileName, { type: 'video/mp4' });
console.log(5)
// 重置状态
ffmpegRef.current.terminate;
};
打印结果
结果分析说明
5个1:五个文件同时成功调用该方法;
2:第一个文件写入成功;
3:第一个文件压缩成功;
四个2:余下四个文件写入成功;
四个3:余下四个文件压缩成功;
4:第二个文件读取成功;(为什么知道是第二个呢,因为页面上第一个视频没有显示,则第一个视频在某一步被干掉了);
5:第二个视频转换文件类型成功;
...
解决方案
主要修改部分为try catch,timeout,options三个
-
修改代码如下:
const compressVideo = async (file) => { try { console.log(1); const inputFileName = "origin_" + file.name; const outputFileName = "compressed_" + inputFileName; await ffmpegRef.current.load(); await ffmpegRef.current.writeFile(inputFileName, await fetchFile(file)); //慢 console.log(2); // 执行 FFmpeg 命令 // 配置对象,用于捕获标准输出和标准错误输出 const options = { captureStdout: true, captureStderr: true, }; const result = await ffmpegRef.current.exec([ "-i", inputFileName, "-vf", "scale=320:240", outputFileName, ],undefined,options); //慢 console.log(result, 3); if (result !== 0) { console.error(`FFmpeg process exited with code ${result}`); // 打印标准输出和标准错误输出 console.log('FFmpeg stdout:', options.captureStdout); console.error('FFmpeg stderr:', options.captureStderr); } else { console.log('FFmpeg process completed successfully.'); } const compressedVideo = await ffmpegRef.current.readFile(outputFileName); //快 console.log(4); const blob = new Blob([compressedVideo.buffer], { type: "video/mp4" }); const compressedFile = new File([blob], outputFileName, { type: "video/mp4", }); console.log(5); // 重置状态 ffmpegRef.current.terminate; }catch(error){ console.error('Error executing FFmpeg command:', error); } };
-
相关源码部分:
* @returns `0` if no error, `!= 0` if timeout (1) or error. * @category FFmpeg */ exec: (args: string[], timeout?: number, { signal }?: FFMessageOptions) => Promise<number>; - args: 必需参数,类型为数组。包含传递给FFmpeg命令行的所有参数。 - timeout: 可选参数,表示命令执行的超时时间(通常以毫秒为单位)。如果超时,Promise将被拒绝。 - __namedParameters: 可选参数,通常是一个对象,包含额外的配置选项。 - Promise<number>: 返回一个Promise,成功时返回一个数字(通常表示命令的退出代码),失败时返回一个错误。
-
控制台输出结果: