在 React 应用程序中的多个输入文件上运行 ffmpeg (WASM/NodeJS)

问题描述 投票:0回答:1

我最近遵循了 Fireship.io 的教程,制作了一个 React 应用程序,使用户能够输入视频文件并将其转换为 gif。这是来源 GitHub Repo

该项目使用的软件包是

@ffmpeg/ffmpeg
@ffmpeg/core
,它们负责将视频转换为 GIF(尽管可以更改为任何内容,例如 FFmpeg CLI 工具)。

我想更进一步,让我可以一次转换多个视频,每个视频都转换成自己单独的 gif,但是,当第一个任务完成后,我在运行下一个任务时遇到了麻烦。

这里是文档我找到了关于ffmpeg wasm包。我还阅读了包提供商提供的这个example,以从单个文件中获得多个输出。

这是我的代码(App.jsx):

import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';
const ffmpeg = createFFmpeg({ log: true });

function App() {
    const [ready, setReady] = useState(false);
    const [videos, setVideos] = useState([]);
    const [gifs, setGifs] = useState([]);
    const load = async () => {
         await ffmpeg.load();
         setReady(true);
    };

   useEffect(() => {
       load();
   }, []);

   const onInputChange = (e) => {
       for (let i = 0; i < e.target.files.length; i++) {
           const newVideo = e.target.files[i];
           setVideos((videos) => [...videos, newVideo]);
       }
   };

   const batchConvert = async (video) => {
       const name = video.name.split('.mp4').join('');

       ffmpeg.FS('writeFile', name + '.mp4', await fetchFile(video));
       await ffmpeg.run(
           '-i',
           name + '.mp4',
           '-f',
           'gif',
            name + '.gif',
        );

        const data = ffmpeg.FS('readFile', name + '.gif');

        const url = URL.createObjectURL(
            new Blob([data.buffer], { type: 'image/gif' }),
        );

        setGifs((gifs) => [...gifs, url]);
    };

    const convertToGif = async () => {
        videos.forEach((video) => {
            batchConvert(video);
        }
    );

return ready ? (
<div className="App">
  {videos &&
    videos.map((video) => (
      <video controls width="250" src={URL.createObjectURL(video)}></video>
    ))}

  <input type="file" multiple onChange={onInputChange} />

  {videos && <button onClick={convertToGif}>Convert to Gif</button>}

  {gifs && (
    <div>
      <h3>Result</h3>
      {gifs.map((gif) => (
        <img src={gif} width="250" />
      ))}
    </div>
  )}
</div>
) : (
    <p>Loading...</p>
);
}

export default App;

我收到的错误类似于“无法同时运行 FFmpeg 的多个实例”,我理解这一点,但是,我不知道如何使batchConvert 函数一次只运行一个实例,无论是在外部还是在外部在函数内部。

谢谢!

node.js reactjs video ffmpeg concurrency
1个回答
-1
投票

我认为你需要将

async/await
放入
forEach

const convertToGif = async () => {
    videos.forEach(async (video) => {
        await batchConvert(video);
    }
);
© www.soinside.com 2019 - 2024. All rights reserved.