diff --git a/src/components/VideoUploadModal.tsx b/src/components/VideoUploadModal.tsx index 069fe4a..440ec9b 100644 --- a/src/components/VideoUploadModal.tsx +++ b/src/components/VideoUploadModal.tsx @@ -1,4 +1,4 @@ -import { type ChangeEvent, Fragment, useState } from "react"; +import React, { type ChangeEvent, Fragment, useRef, useState } from "react"; import { Dialog, Transition } from "@headlessui/react"; import { api } from "~/utils/api"; import axios from "axios"; @@ -13,6 +13,7 @@ export default function VideoUploadModal() { const [file, setFile] = useState(); const getSignedUrl = api.video.getUploadUrl.useMutation(); const apiUtils = api.useContext(); + const videoRef = useRef(null); const handleFileChange = (e: ChangeEvent): void => { if (e.target.files) { @@ -20,6 +21,16 @@ export default function VideoUploadModal() { } }; + const generateThumbnail = async (video: HTMLVideoElement) => { + const canvas = document.createElement("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + canvas + .getContext("2d") + ?.drawImage(video, 0, 0, canvas.width, canvas.height); + return await new Promise((resolve) => canvas.toBlob(resolve)); + }; + function closeModal() { setOpen(false); } @@ -27,14 +38,26 @@ export default function VideoUploadModal() { const handleSubmit = async (): Promise => { if (!file) return; setSubmitting(true); - const { signedUrl, id } = await getSignedUrl.mutateAsync({ - key: file.name, - }); + const { signedVideoUrl, signedThumbnailUrl, id } = + await getSignedUrl.mutateAsync({ + key: file.name, + }); await axios - .put(signedUrl, file.slice(), { + .put(signedVideoUrl, file.slice(), { headers: { "Content-Type": file.type }, }) + .then(async () => { + if (!videoRef.current) return; + return axios.put( + signedThumbnailUrl, + await generateThumbnail(videoRef.current), + { + headers: { "Content-Type": "image/png" }, + } + ); + }) .then(() => { + setOpen(false); void router.push("share/" + id); }) .catch((err) => { @@ -66,6 +89,14 @@ export default function VideoUploadModal() {