Lipβsync any portrait β’ Clone any voice β’ 23 languages
Glent (derived from Glint) is an AIβpowered creative studio that lets you generate lipβsynced talking avatar videos and ultraβrealistic multilingual voiceovers β all from a single photo and a short script. Powered by Hallo3 and ChatterboxTTS, Glent runs on serverless GPU infrastructure (Modal) and keeps your creations private inside Cloudflare R2 buckets.
Portfolio Project β built to demonstrate fullβstack AI integration, creditβbased payments, and realβtime job orchestration.
| Category | Highlights |
|---|---|
| Avatar Video | Animate any frontβfacing portrait with speech from a script or your own audio. 150βcharacter limit, ~10 sec videos. |
| AI Voice Studio | Generate speech in 23 languages with fineβgrained controls: exaggeration, CFG weight, temperature, seed. |
| Voice Cloning | Upload a short .wav sample to clone any voice β captures timbre, accent, emotion. |
| Credit System | 50 free credits on signβup. Buy Spark (500), Flare (1500), or Brilliance (3500) packs via Polar.sh. No subscriptions β credits never expire. |
| Quota Limits | Portfolio mode: 1 avatar video / 7 days, 2 voiceovers / 24h. Keeps GPU costs manageable while letting everyone try everything. |
| Realβtime Status | Live polling: queued β tts_generating β video_generating β completed. |
| Private Storage | All assets (avatars, voice samples, renders) live in a private R2 bucket. Access via shortβlived presigned URLs. |
| Crossβplatform | Fully responsive β works on desktop & mobile. |
- Upload/Crop a portrait photo (JPEG/PNG/WebP, β€5MB).
- Write a script (10β150 characters) and pick a voice from the library or upload a custom sample.
- Adjust settings (language, exaggeration, CFG, temperature, seed).
- Generate β Inngest triggers a Modal worker:
- TTS stage: ChatterboxTTS synthesises speech β saves
.wavin R2. - Video stage: Hallo3 animates the portrait using the generated audio β saves
.mp4.
- TTS stage: ChatterboxTTS synthesises speech β saves
- Stream or download the final video from your history.
- Similar but skips the video stage. TTS generates
.wavdirectly.
Audio mode for Avatar Video β upload a
.wavinstead of a script, and the TTS stage is bypassed entirely.
| Area | Technology |
|---|---|
| Frontend | Next.js 15 (App Router), React 19, Tailwind CSS, shadcn/ui, Lucide icons |
| Backend | Next.js API routes + Server Actions |
| Auth | BetterβAuth (email/password, multiβsession, Polar plugin) |
| Database | PostgreSQL + Prisma ORM |
| Queue / Jobs | Inngest (serverless durable execution) |
| AI Workers | Modal (GPU containers β T4 & A100β80GB) |
| Storage | Cloudflare R2 (private bucket β presigned URLs) |
| Payments | Polar.sh (checkout & webhooks for credit topβups) |
| Nodemailer (Gmail SMTP for verification) | |
| Deployment | Vercel (web app) + Modal (workers) |
glent-hey-gen-clone/
βββ web-app/ # Next.js T3 application
β βββ src/
β β βββ app/ # App router pages & layouts
β β βββ components/ # React components (modals, dashboard, history, home)
β β βββ hooks/ # Custom hooks (quota, generation status, audio player)
β β βββ lib/ # Utils, constants, R2 upload helpers
β β βββ server/ # Server actions, BetterβAuth config, Inngest functions
β β βββ styles/ # Global CSS with Tailwind & shadcn theme
β βββ public/ # Static assets (favicon, hero illustrations)
β βββ package.json # Dependencies & scripts
| βββ .env # Environment variables
| βββ .env.example # Environment variables template
β
βββ modal-workers/ # Python Modal serverless GPU workers
β βββ multilingual-tts/ # ChatterboxTTS worker
β β βββ tts.py
β β βββ utils.py
β β βββ requirements.txt
β βββ video-generation/ # Hallo3 worker
β β βββ video.py
β β βββ requirements.txt
β βββ .env # Modal secrets & R2 credentials
| βββ .env.example # Environment variables template
β
βββ README.md # The project readme
The production instance is deployed on Vercel:
- Sign up with email (no credit card required for free tier).
- Receive 50 credits instantly.
- Start generating avatar videos or voiceovers.
Note: Because this is a portfolio demo, daily/weekly quotas are enforced to manage GPU costs. Upgrade to a credit pack for more generations.
- Node.js 20+ & pnpm 10+
- PostgreSQL (local or remote, e.g., Neon.tech)
- Cloudflare R2 account (or any S3βcompatible bucket)
- Modal account (for GPU workers)
- Polar.sh account (for payments & webhooks)
- Gmail (or any SMTP) for email verification
- Inngest account (optional for local dev; events run via Inngest dev server)
Copy .env.example to .env in the web-app/ folder and fill in the values:
#Environment
NODE_ENV="development"
# App
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# Database (PostgreSQL)
DATABASE_URL="postgresql://..."
DIRECT_URL="postgresql://..."
# BetterβAuth
BETTER_AUTH_SECRET="..." # generate with `openssl rand -base64 32`
BETTER_AUTH_URL=http://localhost:3000
# Modal GPU Workers
MODAL_API_KEY="..."
MODAL_API_SECRET="..."
MODAL_MTL_TTS_API_URL="https://...modal.run/generate_speech"
MODAL_VIDEO_GEN_API_URL="https://...modal.run/generate_video"
# Cloudflare R2
R2_ACCOUNT_ID="..."
R2_ACCESS_KEY_ID="..."
R2_SECRET_ACCESS_KEY="..."
R2_PRIVATE_BUCKET=""
R2_PUBLIC_BUCKET=""
R2_PUBLIC_URL="https://pub-....r2.dev"
# Email (Gmail)
GMAIL_USER="your-email@gmail.com"
GMAIL_APP_PASSWORD="xxxx xxxx xxxx xxxx"
# Inngest (optional β for production)
INNGEST_EVENT_KEY="dummy_key_for_linting"
INNGEST_SIGNING_KEY="dummy_key_for_linting"
# Polar.sh
POLAR_ACCESS_TOKEN="..."
POLAR_WEBHOOK_SECRET="..."git clone https://github.com/KeepSerene/glent-hey-gen-clone.git
cd glent-hey-gen-clone/web-app
pnpm installpnpm db:push # pushes schema to your PostgreSQL
pnpm db:studio # (optional) opens Prisma Studiopnpm devOpen http://localhost:3000 β you're ready to go!
pnpm inngest:devThis runs the Inngest CLI locally, enabling your server actions to send events.
GPU Workers β To actually generate videos/voiceovers, you need to deploy the Modal workers first (see next section). The local dev server will still queue jobs and poll status, but the actual inference requires the Modal endpoints.
-
Install the Modal CLI and authenticate:
pip install modal modal token set --token-id YOUR_TOKEN_ID --token-secret YOUR_TOKEN_SECRET -
Navigate to
modal-workers/and set up your.envfile with the necessary R2 & Modal secrets. -
Deploy the TTS worker:
modal deploy -m multilingual-tts.tts
-
Deploy the Video worker:
modal deploy video-generation/video.py
-
Copy the deployed endpoint URLs (e.g.,
https://your-username--glent-mtl-tts-generate-speech.modal.run) into your env vars.
Important: The workers need access to your R2 bucket. The
glent-r2-secretModal secret must contain all required keys (R2_ACCOUNT_ID,R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY,R2_PRIVATE_BUCKET, plus AWS compat aliases). Seevideo.pyfor the exact names.
- Push your
web-appfolder to a GitHub repository. - Import the project on Vercel.
- Add all environment variables (the same ones from
.env). - Set the Build Command to
pnpm buildand Output Directory to.next. - Deploy β Vercel will automatically run
prisma generateandnext build.
Your Inngest functions will run in production using the
INNGEST_EVENT_KEYandINNGEST_SIGNING_KEY. Don't forget to also set theNEXT_PUBLIC_APP_URLto your production URL.
- Quotas: The first avatar video and two voiceovers are free (within the 24h/7d windows). After that, you'll see a "Limit Reached" badge.
- Credits: Buy a pack on the Pricing page β the Polar webhook should instantly add credits to your user.
- Cancellation: Queued jobs can be cancelled for a full refund. Once a worker starts, no refund.
- Dark mode: The theme automatically follows your system preference, or you can toggle via the header button.
Key models:
Userβ holdscredits(default 50).AvatarVideoβ stores job parameters, statuses, and R2 keys for the avatar, audio, and final video.Voiceoverβ similar but only audio output.GenerationEventβ tracks quota usage (type+createdAt).
All R2 keys are stored as strings; presigned URLs are generated on the fly.
This is a personal portfolio project, but issues and suggestions are welcome! Feel free to open an issue or a pull request.
- Fork the repository.
- Create your feature branch (
git checkout -b feature/amazing-idea). - Commit your changes (
git commit -m 'Add some amazing feature'). - Push to the branch (
git push origin feature/amazing-idea). - Open a Pull Request.
Dhrubajyoti Bhattacharjee
- Portfolio: math-to-dev.vercel.app
- GitHub: @KeepSerene
- LinkedIn: dhrubajyoti-bhattacharjee
- X (Twitter): @UsualLearner
This project is licensed under the Apache 2.0 License β see the LICENSE file for details.
- Hallo3 β stunning portrait animation model.
- ChatterboxTTS β multiβlingual textβtoβspeech.
- Modal Labs β serverless GPU infrastructure.
- BetterβAuth β flexible authentication.
- Inngest β durable job queues.
- Cloudflare R2 β affordable S3βcompatible storage.
- Polar.sh β noβhassle payments for developers.
- shadcn/ui β beautiful, accessible components.
Made with π§ and TypeScript.
Try Glent now β


