问题描述
我最近学习了 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);
之前放置 awaitconst convertToGif = async () => {
videos.forEach((video) => {
await batchConvert(video);
}
);