add thumbnails to videos

This commit is contained in:
MarconLP 2023-04-22 04:46:53 +02:00
parent 822d9ba225
commit 2b648bd8e6
No known key found for this signature in database
GPG key ID: A08A9C8B623F5EA5
3 changed files with 26 additions and 10 deletions

View file

@ -143,15 +143,15 @@ export default function Recorder({ closeModal, step, setStep }: Props) {
} }
}; };
function generateThumbnail(video: HTMLVideoElement) { const generateThumbnail = async (video: HTMLVideoElement) => {
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
canvas.width = video.videoWidth; canvas.width = video.videoWidth;
canvas.height = video.videoHeight; canvas.height = video.videoHeight;
canvas canvas
.getContext("2d") .getContext("2d")
?.drawImage(video, 0, 0, canvas.width, canvas.height); ?.drawImage(video, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL(); return await new Promise((resolve) => canvas.toBlob(resolve));
} };
const handleUpload = async () => { const handleUpload = async () => {
if (!blob || !videoRef.current) return; if (!blob || !videoRef.current) return;
@ -169,11 +169,11 @@ export default function Recorder({ closeModal, step, setStep }: Props) {
.put(signedVideoUrl, blob.slice(), { .put(signedVideoUrl, blob.slice(), {
headers: { "Content-Type": "video/webm" }, headers: { "Content-Type": "video/webm" },
}) })
.then(() => { .then(async () => {
if (!videoRef.current) return; if (!videoRef.current) return;
return axios.put( return axios.put(
signedThumbnailUrl, signedThumbnailUrl,
generateThumbnail(videoRef.current), await generateThumbnail(videoRef.current),
{ {
headers: { "Content-Type": "image/png" }, headers: { "Content-Type": "image/png" },
} }

View file

@ -94,11 +94,12 @@ const VideoList: NextPage = () => {
) : ( ) : (
<div className="flex-start grid w-full max-w-[1300px] grid-cols-[repeat(auto-fill,250px)] flex-row flex-wrap items-center justify-center gap-14 px-4 pb-16"> <div className="flex-start grid w-full max-w-[1300px] grid-cols-[repeat(auto-fill,250px)] flex-row flex-wrap items-center justify-center gap-14 px-4 pb-16">
{videos && {videos &&
videos.map(({ title, id, createdAt }) => ( videos.map(({ title, id, createdAt, thumbnailUrl }) => (
<VideoCard <VideoCard
title={title} title={title}
id={id} id={id}
createdAt={createdAt} createdAt={createdAt}
thumbnailUrl={thumbnailUrl}
key={id} key={id}
/> />
))} ))}
@ -122,6 +123,7 @@ const VideoList: NextPage = () => {
interface VideoCardProps { interface VideoCardProps {
title: string; title: string;
id: string; id: string;
thumbnailUrl: string;
createdAt: Date; createdAt: Date;
} }
@ -137,13 +139,13 @@ const VideoCardSkeleton = () => {
); );
}; };
const VideoCard = ({ title, id, createdAt }: VideoCardProps) => { const VideoCard = ({ title, id, createdAt, thumbnailUrl }: VideoCardProps) => {
return ( return (
<Link href={`/share/${id}`}> <Link href={`/share/${id}`}>
<div className="h-[240px] w-[250px] cursor-pointer overflow-hidden rounded-lg border border-[#6c668533] text-sm font-normal"> <div className="h-[240px] w-[250px] cursor-pointer overflow-hidden rounded-lg border border-[#6c668533] text-sm font-normal">
<figure> <figure>
<Image <Image
src="https://i3.ytimg.com/vi/BuaKzm7Kq9Q/maxresdefault.jpg" src={thumbnailUrl}
alt="video thumbnail" alt="video thumbnail"
width={248} width={248}
height={139.5} height={139.5}

View file

@ -22,7 +22,21 @@ export const videoRouter = createTRPCRouter({
}, },
}); });
return videos; const videosWithThumbnailUrl = await Promise.all(
videos.map(async (video) => {
const thumbnailUrl = await getSignedUrl(
ctx.s3,
new GetObjectCommand({
Bucket: env.AWS_BUCKET_NAME,
Key: video.userId + "/" + video.id + "-thumbnail",
})
);
return { ...video, thumbnailUrl };
})
);
return videosWithThumbnailUrl;
}), }),
get: publicProcedure get: publicProcedure
.input(z.object({ videoId: z.string() })) .input(z.object({ videoId: z.string() }))
@ -95,7 +109,7 @@ export const videoRouter = createTRPCRouter({
s3, s3,
new PutObjectCommand({ new PutObjectCommand({
Bucket: env.AWS_BUCKET_NAME, Bucket: env.AWS_BUCKET_NAME,
Key: video.userId + "/" + video.id + "thumbnail", Key: video.userId + "/" + video.id + "-thumbnail",
}) })
); );