UGC Reactions from Real Creators
Real creator library videos at $11 and images at $8. Custom production from $25/video with a $250 minimum. Commercial licensing included.
翻訳待ち
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗ViewScale analyzes short-form videos (TikTok, Instagram Reels, YouTube Shorts) and explains what limits their performance, with timestamped problems and exact fixes.
Next.js 16 (App Router, TypeScript, Cache Components) · Tailwind CSS v4 · shadcn/ui (Radix) · lucide-react · Framer Motion · Recharts · Supabase (auth, Postgres, Storage) · Anthropic API (analysis) · OpenAI Whisper (transcription) · Stripe (subscriptions, test mode) · Zod
npm install
cp .env.example .env.local
npm run dev # http://localhost:3000
Every variable is listed in .env.example. Secrets are only read on the server; nothing
except NEXT_PUBLIC_* reaches the browser.
Hosted project
npx supabase link --project-ref <ref> then npx supabase db push
(or paste each file in supabase/migrations/ into the SQL editor, in order)..env.local.<your-url>/auth/callback to the redirect URLs.videos bucket itself allows 200 MB.Local (Docker)
npx supabase start # applies supabase/migrations and prints local keys
Put the printed API URL, anon key and service role key in .env.local. Email
confirmation is off locally, so sign-up signs you straight in.
ANTHROPIC_API_KEY: the analysis model defaults to claude-sonnet-5-5 (override with
ANTHROPIC_MODEL).OPENAI_API_KEY: used for Whisper transcription. Without it, analyses still run from
frames only, and the report lists the missing transcript.lib/pricing.ts. Put the price IDs in
STRIPE_PRICE_CREATOR and STRIPE_PRICE_PRO..env.local.STRIPE_WEBHOOK_SECRET:
stripe listen --forward-to localhost:3000/api/stripe/webhook \
--events checkout.session.completed,invoice.paid,customer.subscription.updated,customer.subscription.deleted
In production, add the same endpoint and events in the dashboard.4242 4242 4242 4242.lib/prompts/viewscale.ts holds an interim prompt. Paste the ViewScale system prompt
into VIEWSCALE_SYSTEM_PROMPT, without its "Output format" section
(OUTPUT_FORMAT_INSTRUCTIONS replaces it), then set PROMPT_IS_PLACEHOLDER to false.
Until then, the server logs a warning on the first analysis.
"This page couldn't load" after the layout appears. A server-side part of the page
threw an error. The browser only shows a generic message (often "Minified React error
#441"). The real error is in the server logs: the terminal running npm run dev /
npm start, or your Vercel project's Logs tab. The error ID on the page matches the
digest in the log.
The usual causes, which the app now explains on screen:
NEXT_PUBLIC_* values are
baked in at build time, so a redeploy is required).supabase/migrations/*.sql in order, then create your account again if
you signed up before running them.| Script | What it does |
|---|---|
npm run dev | Dev server |
npm run build / npm start | Production build / server |
npm run typecheck | Generates route types, then runs tsc |
npm run lint | ESLint |
All video processing happens in the browser, so the server needs no ffmpeg.
POST /api/analyses checks credits, caps uploads in progress at 3, creates the row,
and returns the Storage paths.<video> + <canvas>
(lib/video/frames.ts). It samples every 0.5s for the first 3s, then every 1.5s, at
most 40 frames, as 512px-wide JPEGs. The first and last frames are always included. On
long videos the spacing after 3s widens so the whole video fits in 40 frames.lib/video/audio.ts) and uploads it.POST /api/transcribe sends the WAV to Whisper and stores timestamped segments. No
audio, silent audio or a Whisper failure is recorded, and the run continues from
frames only.POST /api/analyze takes one credit atomically (consume_credit). It then sends the
labeled frames (base64), transcript, platform, context and any real performance data
to Claude and saves the result. Any failure refunds the credit (refund_credit) and
marks the analysis failed. The upload page offers "Retry analysis".Progress is shown as Uploading → Extracting frames → Transcribing → Analyzing → Done, and every failure is shown on screen.
This is the beginning of the README. Read the rest at the original. Read the full README ↗