微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我最近学习了 Fireship.io 的教程,详细介绍了如何制作一个 React 应用程序,该应用程序使用户能够输入视频文件并将其转换为 gif。这是来源GitHub Repo

项目使用的包是 @ffmpeg/ffmpeg@ffmpeg/core,它们负责将视频转换为 GIF(尽管这可以更改为任何内容,例如 FFmpeg CLI 工具)。>

我想更进一步,让我可以一次转换多个视频,每个视频都转换为自己单独的 gif,但是,当第一个任务完成时,我无法运行下一个任务。

这是我发现的关于 documentation 包的 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','-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 函数一次只运行一个实例,无论是函数外部或内部。

谢谢!

解决方法

我认为您需要在 batchConvert(video);

之前放置 await
const convertToGif = async () => {
    videos.forEach((video) => {
        await batchConvert(video);
    }
);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。