GitHub - stym06/reelstudio: Get Instagram Reel transcripts locally using OpenAI/Whisper

5 min read Original article ↗

ReelStudio

Transcribe Instagram Reels instantly with AI-powered speech recognition.

Features

  • Instant Transcription - Paste any Instagram Reel URL and get accurate transcripts
  • Multi-language Support - Automatically detects and transcribes in multiple languages
  • Timestamps - Get word-by-word timestamps for easy navigation
  • Shareable Links - Share transcript pages with anyone
  • No Login Required - Start transcribing immediately

Tech Stack

  • Frontend: Next.js 14, React, TypeScript, Tailwind CSS, Shadcn UI
  • Backend: Next.js API Routes, Prisma ORM
  • Worker: Go, yt-dlp, Whisper (Python)
  • Database: PostgreSQL

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                                  CLIENT                                      │
│                            (Browser / User)                                  │
└─────────────────────────────────┬───────────────────────────────────────────┘
                                  │
                                  │ HTTP
                                  ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           NEXT.JS SERVER                                     │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                         App Router                                     │  │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                   │  │
│  │  │   Home (/)  │  │ /transcript │  │   /api/*    │                   │  │
│  │  │             │  │    /[id]    │  │             │                   │  │
│  │  └─────────────┘  └─────────────┘  └──────┬──────┘                   │  │
│  └───────────────────────────────────────────┼───────────────────────────┘  │
│                                              │                               │
│  ┌───────────────────────────────────────────┼───────────────────────────┐  │
│  │                      API Routes           │                            │  │
│  │  ┌─────────────────┐  ┌─────────────────┐ │ ┌─────────────────┐       │  │
│  │  │ POST /transcribe│  │ GET /task/[id]  │ │ │ GET /thumbnail/ │       │  │
│  │  │                 │  │                 │ │ │    [filename]   │       │  │
│  │  │ Create Task     │  │ Poll Status     │ │ │ Serve Images    │       │  │
│  │  └────────┬────────┘  └────────┬────────┘ │ └────────┬────────┘       │  │
│  └───────────┼────────────────────┼──────────┼──────────┼────────────────┘  │
└──────────────┼────────────────────┼──────────┼──────────┼────────────────────┘
               │                    │          │          │
               │                    │          │          │ Read Files
               ▼                    ▼          │          ▼
┌──────────────────────────────────────────────┼──────────────────────────────┐
│                        POSTGRESQL            │                               │
│  ┌────────────────────────────────────────┐  │                               │
│  │              tasks table               │  │                               │
│  │  ┌──────────┬─────────┬─────────────┐  │  │                               │
│  │  │    id    │ status  │ source_url  │  │  │                               │
│  │  │ (uuid)   │ PENDING │ instagram.. │  │  │                               │
│  │  │          │ PROCESS │             │  │  │                               │
│  │  │          │ DONE    │             │  │  │                               │
│  │  │          │ FAILED  │             │  │  │                               │
│  │  └──────────┴─────────┴─────────────┘  │  │                               │
│  └────────────────────────────────────────┘  │                               │
└──────────────────────┬───────────────────────┼───────────────────────────────┘
                       │                       │
                       │ Poll for PENDING      │
                       ▼                       │
┌──────────────────────────────────────────────┼───────────────────────────────┐
│                       GO WORKER              │                               │
│  ┌────────────────────────────────────────┐  │                               │
│  │              Main Loop                 │  │                               │
│  │                                        │  │                               │
│  │  1. Claim PENDING task                 │  │                               │
│  │  2. Download video (yt-dlp)            │  │                               │
│  │  3. Transcribe (Whisper)               │  │                               │
│  │  4. Download thumbnail                 │  │                               │
│  │  5. Mark task DONE                     │  │                               │
│  └────────────────────────────────────────┘  │                               │
│                                              │                               │
│  ┌────────────────────────────────────────┐  │  ┌─────────────────────────┐  │
│  │           downloads/                   │  │  │     External APIs       │  │
│  │  ┌───────────┐ ┌───────────┐          │  │  │  ┌─────────────────┐    │  │
│  │  │ thumbnails│ │transcripts│ ◄────────┼──┘  │  │   Instagram     │    │  │
│  │  │  /*.jpg   │ │  /*.json  │          │     │  │   (via yt-dlp)  │    │  │
│  │  └───────────┘ └───────────┘          │     │  └─────────────────┘    │  │
│  └────────────────────────────────────────┘     └─────────────────────────┘  │
└──────────────────────────────────────────────────────────────────────────────┘

Flow

User                    Server                  Database                Worker
 │                        │                        │                       │
 │  1. Submit URL         │                        │                       │
 │───────────────────────>│                        │                       │
 │                        │  2. Create Task        │                       │
 │                        │───────────────────────>│                       │
 │  3. Return taskId      │                        │                       │
 │<───────────────────────│                        │                       │
 │                        │                        │                       │
 │  4. Poll /task/[id]    │                        │  5. Claim Task        │
 │───────────────────────>│                        │<──────────────────────│
 │                        │  6. Get Status         │                       │
 │                        │───────────────────────>│  7. Download Video    │
 │  8. Status: PROCESSING │                        │  8. Transcribe        │
 │<───────────────────────│                        │  9. Save Files        │
 │                        │                        │                       │
 │  ... keep polling ...  │                        │ 10. Mark DONE         │
 │                        │                        │<──────────────────────│
 │                        │                        │                       │
 │ 11. Poll /task/[id]    │                        │                       │
 │───────────────────────>│ 12. Get Status + Data  │                       │
 │                        │───────────────────────>│                       │
 │ 13. Status: DONE       │                        │                       │
 │     + transcript       │                        │                       │
 │<───────────────────────│                        │                       │
 │                        │                        │                       │
 │ 14. Redirect to        │                        │                       │
 │     /transcript/[id]   │                        │                       │
 ▼                        ▼                        ▼                       ▼

Project Structure

reelstudio/
├── server/                 # Next.js frontend & API
│   ├── app/               # App router pages
│   │   ├── api/           # API routes
│   │   └── transcript/    # Transcript view pages
│   ├── components/        # React components
│   │   └── ui/           # Shadcn UI components
│   ├── lib/              # Utilities
│   └── prisma/           # Database schema
│
└── worker/                # Go worker for processing
    ├── cmd/worker/       # Entry point
    ├── internal/         # Internal packages
    ├── downloads/        # Downloaded media & thumbnails
    │   ├── thumbnails/   # Cached thumbnails
    │   ├── transcripts/  # Transcript JSON files
    │   └── tmp/          # Temporary video files
    └── scripts/          # Python transcription scripts

Getting Started

Prerequisites

  • Node.js 18+
  • Go 1.21+
  • Python 3.10+
  • PostgreSQL
  • yt-dlp
  • ffmpeg

Environment Variables

Create .env files in both server/ and worker/ directories:

server/.env

DATABASE_URL="postgresql://user:password@localhost:5432/reelstudio"

worker/.env

DATABASE_URL="postgresql://user:password@localhost:5432/reelstudio"

Installation

  1. Clone the repository

    git clone https://github.com/stym06/reelstudio.git
    cd reelstudio
  2. Set up the database

    cd server
    npm install
    npx prisma generate
    npx prisma db push
  3. Start the frontend

  4. Set up the worker

    cd worker
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
    make run

Usage

  1. Paste an Instagram Reel URL in the input field
  2. Click "Get Transcript" and wait for processing
  3. View your transcript with timestamps
  4. Copy or share the transcript link

API Endpoints

Endpoint Method Description
/api/transcribe POST Submit a new transcription task
/api/task/[id] GET Get task status and transcript
/api/thumbnail/[filename] GET Serve cached thumbnails

License

MIT