Skip to content

Repository files navigation

🎬 Recast

Turn any viral video into your next winning ad — in seconds.

Paste a Reel, Short, TikTok, or Facebook Ad → get an on-brand script, hook, caption, and visual direction powered by Gemini 2.5 Flash.

Next.js 16 TypeScript Tailwind CSS Gemini AI shadcn/ui MIT License

GitHub stars PRs welcome Made with love in India

Live Demo Documentation Report Bug Request Feature


Stop reverse-engineering virality — let AI recast what already works into ads that sound like you.

Recast demo


✨ Features

📥 Input

🔗 Multi-Platform Ingest Paste any Reel, Short, TikTok, or FB Ad URL — one input, four sources.

🎧 Audio-Only or Full Video Toggle between lightning-fast transcript mode and deep multimodal analysis.

🛍️ Product URL Scraping Drop a product link — brand context auto-extracts in the background.

🧠 Intelligence

⚡ Gemini 2.5 Flash Core State-of-the-art multimodal reasoning over video, audio, and brand data.

🌐 Native Language Preservation Hindi stays Hindi. Tamil stays Tamil. No forced English translation.

🎬 Scene-Aware Direction Understands pacing, hooks, and structure — not just words on screen.

🎨 Output & UX

📋 One-Click Copy Every card, every output — copy-to-clipboard on tap.

🌓 System-Aware Dark Mode Cal.com-inspired monochrome that respects your OS theme.

🎥 Inline Source Preview Watch the original video right next to your generated assets.


🎯 What You Get

Five production-ready assets, generated from a single URL.

# Output What It Delivers
1 📊 Video Summary Hook breakdown + format + tone + narrative structure — the anatomy of why it works.
2 🎯 Adapted Hook A rewritten sub-10-second opener, retuned for your brand voice.
3 📝 Adapted Script A 30–45s script with inline [VISUAL CUE] markers, ready to shoot.
4 📱 Instagram Caption 100–150 words + hashtag set + CTA — drop-in ready.
5 🎬 Visual Direction 2–3 scenes mapped with camera angles, overlays, and mood.

Note

🌐 Original language is always preserved. If the source reel is in Hindi, your script comes back in Hindi. Tamil stays Tamil. Hinglish stays Hinglish. No tone is lost in translation.


💡 Use Cases

👤 Persona 🎬 Scenario 🚀 Outcome
Solo Founder Spotted a viral Reel at 11pm — needs an on-brand version live by tomorrow. $0 spent on copywriters. Ship ads at the speed of inspiration.
D2C Marketing Team Testing 20 ad creatives a week across IG, TikTok, and YouTube Shorts. Brand at scale. Consistent voice across every platform, every variant.
Social Media Agency Managing 15 client accounts, each with a unique tone and product line. 10x faster swipe-file building. Turn competitor scans into client decks in minutes.
Content Creator Wants to remix trending formats without copying — needs a fresh angle fast. Trend-native, never derivative. Hook templates retuned for your niche.

🚀 Quick Start

Get Recast running locally in under 5 minutes.


1. 📦 Install Prerequisites

You'll need Node.js 18+, yt-dlp, and ffmpeg installed on your system.

🍎 macOS
# Install Node.js (if not already installed)
$ brew install node

# Install yt-dlp and ffmpeg
$ brew install yt-dlp ffmpeg
🐧 Linux (Ubuntu / Debian)
# Install Node.js 18+
$ curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
$ sudo apt-get install -y nodejs

# Install ffmpeg
$ sudo apt-get install -y ffmpeg

# Install yt-dlp via pip
$ pip install yt-dlp
🪟 Windows
# Install Node.js from https://nodejs.org (LTS recommended)

# Install ffmpeg and yt-dlp via winget
> winget install Gyan.FFmpeg
> winget install yt-dlp.yt-dlp

# Or via Chocolatey
> choco install ffmpeg yt-dlp

You'll also need a Google API key — grab one from Google AI Studio.


2. 📥 Clone & Install

$ git clone https://github.com/thegauravmahto/recast.git
$ cd recast
$ npm install

3. 🔑 Configure & Run

Create a .env file in the project root and add your API key:

$ echo "GOOGLE_API_KEY=your_api_key_here" > .env
$ npm run dev

Open http://localhost:3000 — you're live! 🎉


⚙️ Environment Variables

Configure Recast by setting these in your .env file:

Variable Required Default Description
GOOGLE_API_KEY ✅ Yes Your Gemini API key used for script generation via Gemini 2.5 Flash.
YTDLP_PATH ⚪ No yt-dlp (from $PATH) Absolute path to the yt-dlp binary. Override if it's not on your system PATH.
FFMPEG_PATH ⚪ No ffmpeg (from $PATH) Absolute path to the ffmpeg binary. Override if it's not on your system PATH.

Tip

Don't have a Gemini API key yet? Generate one for free at aistudio.google.com/apikey — it takes about 30 seconds.


🐳 Run with One Command

For the impatient — clone, install, and launch in a single shot:

git clone https://github.com/thegauravmahto/recast.git && \
  cd recast && \
  npm install && \
  echo "GOOGLE_API_KEY=your_api_key_here" > .env && \
  npm run dev

Important

Replace your_api_key_here with your actual key from Google AI Studio before running, or edit .env afterwards and restart the dev server.


🧠 How It Works

flowchart LR
    A[👤 User Pastes<br/>Video URL] --> B[📥 yt-dlp<br/>Downloads Video]
    B -->|standard mode| D[☁️ Gemini Files API<br/>Upload & Poll]
    B -->|audio mode| C[🎵 ffmpeg<br/>Extract Audio]
    C --> D
    D -->|file ready| E[🧠 Gemini 2.5 Flash<br/>System Prompt Analysis]
    E -->|markdown response| F[📝 Markdown Parser<br/>Split by Headers]
    F -->|5 sections| G[📦 JSON Payload]
    G --> H[💎 React UI<br/>Result Cards + Copy]

    style E fill:#8b5cf6,stroke:#6d28d9,stroke-width:3px,color:#fff
    style A fill:#0ea5e9,stroke:#0369a1,color:#fff
    style H fill:#10b981,stroke:#047857,color:#fff
Loading
  1. Paste & Submit — User drops a video URL into the dashboard input and hits analyze.
  2. Downloadyt-dlp pulls the video locally into a temp directory on the server.
  3. Optional Audio Extract — If audio mode is enabled, ffmpeg strips the audio track to shrink the upload payload.
  4. Upload to Gemini — The file is pushed to the Gemini Files API and polled until the processing state turns ACTIVE.
  5. AI Analysis — Gemini 2.5 Flash runs with a specialized system prompt and returns structured markdown with 5 canonical headers.
  6. Parse & Render — The markdown is split into a JSON object keyed by section and rendered as copy-ready cards in the React UI.

🛠️ Tech Stack

🎨 Frontend

Tool Purpose
Next.js App Router, server actions, route handlers
React Component model for the dashboard UI
TypeScript End-to-end type safety across routes & components
Tailwind Utility-first styling with custom design tokens
shadcn/ui Accessible, copy-paste primitives (cards, buttons, inputs)
next-themes Class-based theme switching with no flash

🧠 AI & Backend

Tool Purpose
Gemini Multimodal LLM that watches the video and writes the analysis
Gemini Files API Handles large media uploads and processing state
Next.js Route Handlers /api/analyze orchestrates the full pipeline server-side

🔧 Tooling

Tool Purpose
yt-dlp Reliable video downloader across hundreds of sources
ffmpeg Audio extraction for the lightweight "audio mode" path
npm Package management

📁 Project Structure

Recast is a small, focused codebase — here's the lay of the land:

recast/
├── app/
│   ├── layout.tsx                  # Root layout: theme provider, fonts, metadata
│   ├── page.tsx                    # Home route — renders the <Dashboard /> client
│   ├── globals.css                 # Tailwind layers, design tokens, Cal.com-style shadows
│   └── api/
│       ├── analyze/
│       │   └── route.ts            # POST: yt-dlp → (ffmpeg) → Gemini upload → parse → JSON
│       └── video/
│           └── [filename]/
│               └── route.ts        # GET: streams downloaded videos back to the client
├── components/
│   ├── dashboard.tsx               # Main UI — URL input, loading skeletons, results grid
│   ├── result-card.tsx             # Reusable card with title, markdown body, copy-to-clipboard
│   ├── theme-provider.tsx          # Thin next-themes wrapper for the App Router
│   └── theme-toggle.tsx            # Sun/moon button bound to the theme provider
├── DESIGN.md                       # Design system reference — tokens, spacing, motion
└── .env.example                    # GOOGLE_API_KEY and other env var templates

Architecture philosophy: the /api/analyze route does all the heavy lifting — downloading, transcoding, uploading, polling, and parsing — so the client stays a thin, stateless rendering layer. Components are small and composable (<ResultCard /> knows nothing about Gemini), and the entire flow is request/response — no websockets, no queues, no state machines to babysit.


📱 Supported Platforms

Instagram

Instagram
Reels & video posts
YouTube

YouTube
Shorts & long-form
TikTok

TikTok
Public videos
Facebook

Facebook
Ads Library & videos

Tip

1000+ more sites supported via yt-dlp — Twitter/X, LinkedIn, Vimeo, Twitch, Reddit, and far beyond. See the full list of supported sites.


🎬 Example: Input → Output

Input

Product Context: A 7-day Notion productivity course for solo founders.
                 Promises 10 hours/week back. Price: $49.
Source Video:    https://www.instagram.com/reel/EXAMPLE/
                 (a fitness coach explaining how she structures her training week)

Output — Recast adapts the source video's structure, pacing, and hook style to your product:

🧠 1. Video Summary

A 38-second Reel where a fitness coach breaks down her "non-negotiable 3-day split." The hook calls out a common mistake (training every day), then walks through her weekly system with quick B-roll of workouts. Closes with a soft CTA to her training program. Tone is confident, direct, no-fluff.

🎯 2. Adapted Hook

"Stop 'hustling' 7 days a week. Here's the exact 3-day system I use to run my company in 20 hours flat."

Why it works: Mirrors the source's pattern-interrupt ("Stop training every day") and applies it to founder burnout — the pain point your course solves.

📝 3. Adapted Script

[VISUAL CUE: Close-up, founder looking tired at laptop, harsh overhead light] Stop "hustling" 7 days a week. It's why you're stuck.

[VISUAL CUE: Hard cut — same founder, now energized, clean desk, soft natural light] Here's the exact 3-day system I built in Notion to run my company in 20 hours.

[VISUAL CUE: Screen recording — Notion dashboard with 3 colored blocks: Build / Sell / Rest] Day 1: Build. Day 2: Sell. Day 3: Rest. That's it. Everything else is noise.

[VISUAL CUE: Quick montage — calendar dragging, Slack closing, phone face-down] No context switching. No 14 open tabs. No "quick check" at 11pm.

[VISUAL CUE: Founder smiling, holding coffee, end card with course mockup] I packaged the whole system into a 7-day course. Link in bio — it's $49 and it'll buy you back 10 hours this week.

📱 4. Instagram Caption

The 3-day founder week that replaced my 7-day grind 👇

I used to "work" every single day and ship nothing. Then I built this Notion system. Now I run the whole company in 20 hours and actually take weekends.

7-day course. $49. Link in bio.

#solopreneur #notiontemplate #founderlife #productivityhacks #buildinpublic #indiehacker #notionsetup #startuplife #timemanagement #worklessdomore

🎥 5. Visual Direction
Shot Camera Lighting Notes
Opening Tight close-up, eye-level, 35mm Cold, overhead, slightly harsh Sells the "stuck" feeling
Reveal Medium shot, same angle, jump cut Warm natural window light Mirror the source's hard cut energy
System walkthrough Screen recording, 1080x1920, 1.2x speed N/A Highlight blocks with subtle zoom-ins
Montage Handheld, fast cuts (~0.4s each) Matches reveal Builds momentum
Close Medium-wide, slight smile, end card overlay Warm CTA must appear by 0:32 to retain

Aspect ratio: 9:16 · Length target: 35–40s · Captions: burned-in, bottom-third, max 5 words per frame.


📸 Screenshots

Clean dashboard input
Clean dashboard input
Skeleton loading state
Skeleton loading state
Generated results — light mode
Generated results (light mode)
Generated results — dark mode
Generated results (dark mode)

Note

Screenshots above are clean SVG mockups designed to match the actual UI exactly (rendered natively by GitHub). Swap them with real PNG/JPG captures any time — just drop them into /public/screenshots/ and update the extensions.


🛠️ Troubleshooting

Hit a snag? Expand the relevant section below.

yt-dlp: command not found

Recast shells out to yt-dlp to fetch videos. Install it for your OS:

# macOS
$ brew install yt-dlp

# Linux (via pip)
$ pip install yt-dlp

# Windows
> winget install yt-dlp.yt-dlp

Already installed but still failing? Set YTDLP_PATH in your .env to the absolute binary path (e.g. /usr/local/bin/yt-dlp).

ffmpeg: command not found

ffmpeg is required for audio/video processing. Install it for your OS:

# macOS
$ brew install ffmpeg

# Linux (Ubuntu/Debian)
$ sudo apt-get install -y ffmpeg

# Windows
> winget install Gyan.FFmpeg

If installed in a non-standard location, set FFMPEG_PATH in your .env to the absolute binary path.

⚠️ Gemini API quota exceeded

The Gemini free tier has rate limits (currently 15 requests/min and 1,500 requests/day for Gemini 2.5 Flash). If you hit them:

⚠️ Video download failed

This usually means one of the following:

  • 🔒 The video is private or requires login
  • 🌍 The video is region-locked in your area
  • 🗑️ The video has been deleted or made unavailable
  • 📡 yt-dlp is out of date — update it:
    $ pip install -U yt-dlp
    # or
    $ brew upgrade yt-dlp

Try a different public video URL to confirm your setup is working.

⚠️ Port 3000 already in use

Another process is using port 3000. Either stop that process, or run Recast on a different port:

$ npm run dev -- -p 3001

Then visit http://localhost:3001.


🗺️ Roadmap

Now

  • Multi-platform support (Instagram, TikTok, YouTube Shorts, Reels)
  • Dark mode with system preference detection
  • Original language preservation in generated scripts
  • Bulk URL processing (queue up to 10 videos at once)
  • Export analysis & scripts to PDF / Notion
  • Save analysis history with searchable dashboard
  • One-click "Regenerate hook" button

Next

  • A/B variant generation — 3 hook variants per script
  • Brand voice profiles (upload past ads → match tone)
  • Slack & Discord integration for team workflows
  • Thumbnail concept generator (text-to-image via Imagen)
  • CSV export for media-buying teams
  • Custom prompt templates per niche (D2C, EdTech, SaaS)

Later

  • Direct publish to Meta Ads Manager & TikTok Ads
  • Multi-language UI (Hindi, Spanish, Portuguese, Arabic)
  • Chrome extension — analyze any video without leaving the tab
  • iOS & Android companion apps
  • Team workspaces with role-based access
  • Fine-tuned model for vertical-specific ad copy

Have an idea? Open an issue — the roadmap is shaped by the community.


🤝 Contributing

PRs, issues, and ideas are all warmly welcome. Whether you're fixing a typo or shipping a new platform integration — you belong here.

1. Fork & clone the repo

git clone https://github.com/YOUR_USERNAME/recast.git && cd recast

2. Create a feature branch

git checkout -b feat/your-amazing-feature

3. Commit using conventional commits

git commit -m "feat: add bulk URL processing"

4. Push & open a Pull Request

git push origin feat/your-amazing-feature

New here? Start with a [good first issue](https://github.com/thegauravmahto/recast/issues?q=is:open+is:issue+label:"good first issue") — they're handpicked to be friendly and well-scoped. Don't be shy, drop a comment and we'll guide you through.


❓ FAQ

Is my data private?
Yes. Videos are downloaded locally on your machine via yt-dlp, sent to Gemini only for analysis, and deleted from local storage immediately after. Nothing is stored on a Recast server — there is no Recast server. Your API key, your data, your control.
How much does it cost to run?
For most personal use, nothing. Gemini 2.5 Flash has a generous free tier (~1,500 requests/day) that covers casual creators easily. Heavy users pay Google's pay-as-you-go rate — typically less than $0.01 per video analysis. No Recast subscription, ever.
Why did my script come back in Hindi / Tamil / Spanish?
That's intentional! Recast preserves the original language of the source video by default — a Hindi reel produces a Hindi script. This keeps cultural nuance and idioms intact. Want English output regardless? Toggle "Force English" in advanced settings.
Can I use this commercially?
Absolutely — Recast is MIT licensed. Use it for client work, agency workflows, internal tools, or paid SaaS. Attribution isn't required, but a link back or a ⭐ is always appreciated.
Does it support long-form YouTube videos?
Yes, up to ~1 hour. For videos longer than 5 minutes we recommend switching to audio-only mode — it's ~10× faster, ~5× cheaper, and quality drop is minimal for ad-copy generation since the hook intelligence lives in the script, not the visuals.
Why Gemini 2.5 Flash and not GPT-4o or Claude?
Three reasons: (1) Gemini has native video understanding via the Files API — no frame extraction hacks needed. (2) The 1M-token context window swallows long videos whole. (3) Cost-per-quality is unbeatable at this tier. That said, the architecture is provider-agnostic — swapping in GPT-4o or Claude is a ~50-line change in lib/ai/provider.ts.

🙏 Acknowledgments

Recast stands on the shoulders of giants. Huge thanks to:

  • Google DeepMind — for Gemini 2.5 Flash and the Files API
  • Vercel — for Next.js 16 and effortless deployment
  • shadcn — for the beautiful, ownable UI components
  • yt-dlp team — the unsung heroes of video tooling
  • FFmpeg team — for 20+ years of media wizardry
  • Cal.com — for design inspiration and OSS-done-right vibes
  • Lucide — for the crisp icon set
  • Every contributor, issue-opener, and ⭐ giver — you make this fun.

📄 License

Released under the MIT License — free for personal and commercial use. Build cool things.

License: MIT


👋 Author

Gaurav Mahto

Gaurav Mahto

AI Product Manager · Building GenAI for education at Narayana Group


GitHub LinkedIn X / Twitter


If Recast saved you time, consider ⭐ starring the repo — it really helps!


Made with ☕ + 🤖 in India

About

AI-powered video-to-ad content generator. Paste any Instagram Reel, YouTube Short, or Facebook Ad — get adapted scripts, hooks, and captions for your brand. Built with Next.js, Gemini AI, and shadcn/ui.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages