-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added video generation successfully also
- Loading branch information
1 parent
536bba7
commit d33aa0a
Showing
3 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import * as z from "zod"; | ||
|
||
export const formSchema = z.object({ | ||
prompt: z.string().min(1, { | ||
message: "Prompt is required." | ||
}), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
"use client"; | ||
|
||
import { zodResolver } from "@hookform/resolvers/zod"; | ||
import axios from "axios"; | ||
import { VideoIcon } from "lucide-react"; | ||
import { useRouter } from "next/navigation"; | ||
import { useState } from "react"; | ||
import { useForm } from "react-hook-form"; | ||
import { toast } from "react-hot-toast"; | ||
import * as z from "zod"; | ||
|
||
import { Heading } from "@/components/heading"; | ||
import { Loader } from "@/components/loader"; | ||
import { Button } from "@/components/ui/button"; | ||
import { Empty } from "@/components/ui/empty"; | ||
import { Form, FormControl, FormField, FormItem } from "@/components/ui/form"; | ||
import { Input } from "@/components/ui/input"; | ||
// import { useProModal } from "@/hooks/use-pro-modal"; | ||
|
||
import { formSchema } from "./constants"; | ||
|
||
const VideoPage = () => { | ||
const router = useRouter(); | ||
// const proModal = useProModal(); | ||
const [video, setVideo] = useState<string>(); | ||
|
||
const form = useForm<z.infer<typeof formSchema>>({ | ||
resolver: zodResolver(formSchema), | ||
defaultValues: { | ||
prompt: "", | ||
} | ||
}); | ||
|
||
const isLoading = form.formState.isSubmitting; | ||
|
||
const onSubmit = async (values: z.infer<typeof formSchema>) => { | ||
try { | ||
setVideo(undefined); | ||
|
||
const response = await axios.post('/api/video', values); | ||
|
||
setVideo(response.data[0]); | ||
form.reset(); | ||
} catch (error: any) { | ||
if (error?.response?.status === 403) { | ||
// proModal.onOpen(); | ||
} else { | ||
toast.error("Something went wrong."); | ||
} | ||
} finally { | ||
router.refresh(); | ||
} | ||
} | ||
|
||
return ( | ||
<div> | ||
<Heading | ||
title="Video Generation" | ||
description="Turn your prompt into video." | ||
icon={VideoIcon} | ||
iconColor="text-orange-700" | ||
bgColor="bg-orange-700/10" | ||
/> | ||
|
||
<div className="px-4 lg:px-8"> | ||
<Form {...form}> | ||
<form | ||
onSubmit={form.handleSubmit(onSubmit)} | ||
className="rounded-lg border w-full p-4 px-3 md:px-6 focus-within:shadow-sm grid grid-cols-12 gap-2" | ||
> | ||
<FormField | ||
name="prompt" | ||
render={({ field }) => ( | ||
<FormItem className="col-span-12 lg:col-span-10"> | ||
<FormControl className="m-0 p-0"> | ||
<Input | ||
className="border-0 outline-none focus-visible:ring-0 focus-visible:ring-transparent" | ||
disabled={isLoading} | ||
placeholder="Clown fish swimming in a coral reef" | ||
{...field} | ||
/> | ||
</FormControl> | ||
</FormItem> | ||
)} | ||
/> | ||
<Button className="col-span-12 lg:col-span-2 w-full" type="submit" disabled={isLoading} size="icon"> | ||
Generate | ||
</Button> | ||
</form> | ||
</Form> | ||
|
||
{isLoading && ( | ||
<div className="p-20"> | ||
<Loader /> | ||
</div> | ||
)} | ||
|
||
{!video && !isLoading && ( | ||
<Empty label="No video files generated." /> | ||
)} | ||
|
||
{video && ( | ||
<video controls className="w-full aspect-video mt-8 rounded-lg border bg-black"> | ||
<source src={video} /> | ||
</video> | ||
)} | ||
|
||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default VideoPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import Replicate from "replicate"; | ||
import { auth } from "@clerk/nextjs"; | ||
import { NextResponse } from "next/server"; | ||
|
||
// import { incrementApiLimit, checkApiLimit } from "@/lib/api-limit"; | ||
// import { checkSubscription } from "@/lib/subscription"; | ||
|
||
const replicate = new Replicate({ | ||
auth: process.env.REPLICATE_API_TOKEN!, | ||
}); | ||
|
||
export async function POST(req: Request) { | ||
try { | ||
const { userId } = auth(); | ||
const body = await req.json(); | ||
const { prompt } = body; | ||
|
||
if (!userId) { | ||
return new NextResponse("Unauthorized", { status: 401 }); | ||
} | ||
|
||
if (!prompt) { | ||
return new NextResponse("Prompt is required", { status: 400 }); | ||
} | ||
|
||
// const freeTrial = await checkApiLimit(); | ||
// const isPro = await checkSubscription(); | ||
|
||
// if (!freeTrial && !isPro) { | ||
// return new NextResponse("Free trial has expired. Please upgrade to pro.", { status: 403 }); | ||
// } | ||
|
||
const response = await replicate.run( | ||
"anotherjesse/zeroscope-v2-xl:71996d331e8ede8ef7bd76eba9fae076d31792e4ddf4ad057779b443d6aea62f", | ||
{ | ||
input: { | ||
prompt, | ||
} | ||
} | ||
); | ||
|
||
// if (!isPro) { | ||
// await incrementApiLimit(); | ||
// } | ||
|
||
return NextResponse.json(response); | ||
} catch (error) { | ||
console.log('[VIDEO_ERROR]', error); | ||
return new NextResponse("Internal Error", { status: 500 }); | ||
} | ||
}; |