Skip to content

Instantly share code, notes, and snippets.

@2chanhaeng
Created November 23, 2024 02:40
Show Gist options
  • Select an option

  • Save 2chanhaeng/c9f31358bb3691f197789d88ee6493ed to your computer and use it in GitHub Desktop.

Select an option

Save 2chanhaeng/c9f31358bb3691f197789d88ee6493ed to your computer and use it in GitHub Desktop.
GIF to MP4 converter component
import { useState, useMemo } from "react";
import { FFmpeg } from "@ffmpeg/ffmpeg";
import { guarantee, method, pipe, tapAsync } from "utils"; // jsr:@chomu/utils
export default function GifToMp4Converter() {
const ffmpeg = useMemo(() => new FFmpeg(), []);
const [gifFile, setGifFile] = useState<File | null>(null);
const [videoUrl, setVideoUrl] = useState("");
const convertGifToVideo = async () => {
const INPUT = "input.gif";
const OUTPUT = "output.mp4";
const command = [
"-i",
INPUT,
"-vf",
"crop=floor(iw/2)*2:floor(ih/2)*2:0:0", // width, height가 홀수일 경우 오류 발생
"-pix_fmt",
"yuv420p", // 브라우저 호환성을 위해 yuv420p로 설정
OUTPUT,
];
pipe(
guarantee<File>,
method("arrayBuffer")<Promise<ArrayBuffer>, File>,
(buffer) => new Uint8Array(buffer),
tapAsync(async () => !ffmpeg.loaded && ffmpeg.load()),
tapAsync((array) => ffmpeg.writeFile(INPUT, array)),
tapAsync(() => ffmpeg.exec(command)),
() => ffmpeg.readFile(OUTPUT),
(data) => new Blob([data], { type: "video/mp4" }),
URL.createObjectURL,
setVideoUrl
)(gifFile).catch(console.error);
/*
// 위 코드는 다음과 동일
if (gifFile) {
const buffer = await gifFile.arrayBuffer();
const array = new Uint8Array(buffer);
if (!ffmpeg.loaded) await ffmpeg.load();
await ffmpeg.writeFile(INPUT, array);
await ffmpeg.exec(command);
const data = await ffmpeg.readFile(OUTPUT);
const blob = new Blob([data], { type: "video/mp4" });
const url = URL.createObjectURL(blob);
setVideoUrl(url);
}
*/
};
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setGifFile(e.target.files?.[0] || null);
};
return (
<div>
<h2>GIF를 비디오로 변환</h2>
<input type="file" accept="image/gif" onChange={handleFileChange} />
<button onClick={convertGifToVideo}>변환</button>
{videoUrl && (
<video controls>
<source src={videoUrl} type="video/mp4" />
</video>
)}
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment