57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import { useState, useRef } from "react";
|
|
import { FFmpeg } from "@ffmpeg/ffmpeg";
|
|
import { toBlobURL, fetchFile } from "@ffmpeg/util";
|
|
|
|
function App() {
|
|
const [loaded, setLoaded] = useState(false);
|
|
const ffmpegRef = useRef(new FFmpeg());
|
|
const videoRef = useRef(null);
|
|
const messageRef = useRef(null);
|
|
|
|
const load = async () => {
|
|
const baseURL = "https://unpkg.com/@ffmpeg/core-mt@0.12.2/dist/esm";
|
|
const ffmpeg = ffmpegRef.current;
|
|
ffmpeg.on("log", ({ message }) => {
|
|
messageRef.current.innerHTML = message;
|
|
});
|
|
// toBlobURL is used to bypass CORS issue, urls with the same
|
|
// domain can be used directly.
|
|
await ffmpeg.load({
|
|
coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, "text/javascript"),
|
|
wasmURL: await toBlobURL(
|
|
`${baseURL}/ffmpeg-core.wasm`,
|
|
"application/wasm"
|
|
),
|
|
workerURL: await toBlobURL(
|
|
`${baseURL}/ffmpeg-core.worker.js`,
|
|
"text/javascript"
|
|
),
|
|
});
|
|
setLoaded(true);
|
|
};
|
|
|
|
const transcode = async () => {
|
|
const videoURL = "https://ffmpegwasm.netlify.app/video/video-15s.avi";
|
|
const ffmpeg = ffmpegRef.current;
|
|
await ffmpeg.writeFile("input.avi", await fetchFile(videoURL));
|
|
await ffmpeg.exec(["-i", "input.avi", "output.mp4"]);
|
|
const data = await ffmpeg.readFile("output.mp4");
|
|
videoRef.current.src = URL.createObjectURL(
|
|
new Blob([data.buffer], { type: "video/mp4" })
|
|
);
|
|
};
|
|
|
|
return loaded ? (
|
|
<>
|
|
<video ref={videoRef} controls></video>
|
|
<br />
|
|
<button onClick={transcode}>Transcode avi to mp4</button>
|
|
<p ref={messageRef}></p>
|
|
</>
|
|
) : (
|
|
<button onClick={load}>Load ffmpeg-core</button>
|
|
);
|
|
}
|
|
|
|
export default App;
|