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");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas
.getContext("2d")
?.drawImage(video, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL();
}
return await new Promise((resolve) => canvas.toBlob(resolve));
};
const handleUpload = async () => {
if (!blob || !videoRef.current) return;
@ -169,11 +169,11 @@ export default function Recorder({ closeModal, step, setStep }: Props) {
.put(signedVideoUrl, blob.slice(), {
headers: { "Content-Type": "video/webm" },
})
.then(() => {
.then(async () => {
if (!videoRef.current) return;
return axios.put(
signedThumbnailUrl,
generateThumbnail(videoRef.current),
await generateThumbnail(videoRef.current),
{
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">
{videos &&
videos.map(({ title, id, createdAt }) => (
videos.map(({ title, id, createdAt, thumbnailUrl }) => (
<VideoCard
title={title}
id={id}
createdAt={createdAt}
thumbnailUrl={thumbnailUrl}
key={id}
/>
))}
@ -122,6 +123,7 @@ const VideoList: NextPage = () => {
interface VideoCardProps {
title: string;
id: string;
thumbnailUrl: string;
createdAt: Date;
}
@ -137,13 +139,13 @@ const VideoCardSkeleton = () => {
);
};
const VideoCard = ({ title, id, createdAt }: VideoCardProps) => {
const VideoCard = ({ title, id, createdAt, thumbnailUrl }: VideoCardProps) => {
return (
<Link href={`/share/${id}`}>
<div className="h-[240px] w-[250px] cursor-pointer overflow-hidden rounded-lg border border-[#6c668533] text-sm font-normal">
<figure>
<Image
src="https://i3.ytimg.com/vi/BuaKzm7Kq9Q/maxresdefault.jpg"
src={thumbnailUrl}
alt="video thumbnail"
width={248}
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
.input(z.object({ videoId: z.string() }))
@ -95,7 +109,7 @@ export const videoRouter = createTRPCRouter({
s3,
new PutObjectCommand({
Bucket: env.AWS_BUCKET_NAME,
Key: video.userId + "/" + video.id + "thumbnail",
Key: video.userId + "/" + video.id + "-thumbnail",
})
);