A modern, high-quality screen recording application with cloud storage, video trimming, and instant sharing capabilities.
- π¬ High-Quality Recording - 8 Mbps video, 128 kbps audio
- βοΈ Video Trimming - Browser-based trimming with progress tracking
- βοΈ Cloud Storage - Direct-to-cloud uploads via Supabase
- π Analytics - View counts and completion rate tracking
- π Instant Sharing - Generate shareable links immediately
- π¨ Modern UI - Beautiful, responsive design with toast notifications
- π Fast Uploads - Presigned URLs bypass server limits
- Frontend: Next.js 16, React, TypeScript, TailwindCSS
- Backend: Next.js API Routes
- Database: Supabase (PostgreSQL)
- Storage: Supabase Storage (S3-compatible)
- Video Processing: Canvas API + MediaRecorder
- Notifications: Sonner (toast notifications)
- Node.js 18+ and npm
- Supabase account (supabase.com)
- Vercel account (for deployment, optional)
git clone https://github.com/RahulKumar9988/sCapture.git
cd sCapturenpm install- Go to supabase.com
- Create a new project
- Wait for the database to initialize
- Go to SQL Editor in Supabase Dashboard
- Copy the contents of
supabase-migration-trim.sql(contact me for complete migration file) - Paste and run the SQL script
- This creates the
videostable with all required columns and policies
Need the migration file? If you don't have
supabase-migration-trim.sql, please contact me:
- π¬ GitHub Discussions: Open a discussion
- π§ Email: rahulkrwhy000@gmail.com
- π Issues: Report an issue
- Go to Storage in Supabase Dashboard
- Create a new bucket named
videos - Set bucket to Public (or configure RLS policies)
- Go to Project Settings β API
- Copy your Project URL and anon key
- Go to Storage β Settings β S3 Access Keys
- Generate new S3 access keys
Create a .env.local file in the root directory:
# Supabase Configuration
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Supabase S3 Storage (for direct uploads)
SUPABASE_S3_ENDPOINT=https://your-project.supabase.co/storage/v1/s3
SUPABASE_ACCESS_KEY_ID=your-s3-access-key
SUPABASE_SECRET_ACCESS_KEY=your-s3-secret-key
SUPABASE_BUCKET_NAME=videos
SUPABASE_REGION=us-east-1
# Optional: App URL (for sharing links)
NEXT_PUBLIC_APP_URL=http://localhost:3000.env.local to Git!
npm run devOpen http://localhost:3000 to see the app.
sCapture/
βββ app/
β βββ api/
β β βββ upload/
β β β βββ presigned/route.ts # Generate presigned URLs
β β βββ video/
β β βββ [id]/
β β β βββ stream/route.ts # Video proxy
β β β βββ view/route.ts # View counter
β β β βββ progress/route.ts # Analytics
β β βββ create/route.ts # Save video metadata
β βββ record/page.tsx # Recording interface
β βββ watch/[id]/page.tsx # Video player
β βββ page.tsx # Landing page
βββ lib/
β βββ db.ts # Supabase client
β βββ storage.ts # S3 client
βββ supabase-migration-trim.sql # Database schema
- User clicks "Start Recording"
- Browser captures screen + audio (MediaRecorder API)
- Video is recorded at 8 Mbps quality
- User can preview and trim the recording
- User clicks "Upload"
- If trimmed: Browser re-encodes video using Canvas API
- App requests presigned URL from
/api/upload/presigned - Video uploads directly to Supabase Storage (bypasses server)
- Metadata saved to database via
/api/video/create - User gets shareable link
- User opens watch page
- Video streams via
/api/video/[id]/stream(proxy) - If trimmed: Player auto-seeks to
trim_startand stops attrim_end - View count increments automatically
- Completion rate tracked on pause/end
- β Server-side rendering for better SEO
- β API Routes eliminate need for separate backend
- β File-based routing simplifies navigation
- β Built-in optimization (images, fonts, code splitting)
- β Real-time capabilities for future features
- β Built-in authentication (ready for user accounts)
- β S3-compatible storage with presigned URLs
- β Row Level Security for data protection
- β Free tier suitable for MVP
- β No server load - processing happens in browser
- β High quality - direct capture without compression
- β Privacy - video never touches server until user uploads
- β Browser compatibility - requires modern browsers
- β Bypasses server limits - Vercel's 4.5MB limit avoided
- β Faster uploads - direct to storage, no proxy
- β Scalable - no server bandwidth consumption
- β Secure - temporary, scoped URLs
- β No external dependencies - pure browser APIs
- β Free - no FFmpeg licensing or server costs
- β Client-side - no server processing needed
- β Performance - can be slow for long videos
- β Quality loss - re-encoding reduces quality slightly
-
Metadata-Based Trimming
- Store
trim_startandtrim_endin database - Video player respects these values
- No file re-encoding needed (fast!)
- Similar to YouTube's approach
- Store
-
Direct-to-Storage Uploads
- Generate presigned URL server-side
- Upload directly from browser to Supabase
- Save metadata after upload completes
- Prevents server bottlenecks
-
Optimistic UI Updates
- Show loading states immediately
- Update UI before server confirms
- Better perceived performance
-
Progressive Enhancement
- Core features work without JavaScript
- Enhanced features for modern browsers
- Graceful degradation
Current State: Anyone can upload (security risk)
Production Solution:
// Add Supabase Auth
import { createServerClient } from "@supabase/ssr";
// Protect upload routes
if (!session) {
return new Response("Unauthorized", { status: 401 });
}Benefits:
- User-specific video libraries
- Delete own videos
- Private/public videos
- Prevent abuse
Current State: No upload limits
Production Solution:
// Use Upstash Redis + Vercel Edge Config
import { Ratelimit } from "@upstash/ratelimit";
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(10, "1 h"), // 10 uploads per hour
});Benefits:
- Prevent spam
- Reduce storage costs
- Protect against abuse
Current State: Browser-based trimming (slow, quality loss)
Production Solution:
- Option A: Server-side FFmpeg on VPS
# Deploy to DigitalOcean/AWS with FFmpeg ffmpeg -i input.webm -ss 5 -t 15 -c copy output.mp4 - Option B: Use Mux/Cloudinary API
// Cloudinary video transformation cloudinary.video("video_id", { start_offset: 5, end_offset: 20, });
Benefits:
- Faster processing
- Better quality
- No browser freezing
- Consistent results
Current State: Videos served directly from Supabase
Production Solution:
// Use Cloudflare CDN
const videoUrl = `https://cdn.scapture.com/${videoId}`;
// Or Vercel Edge Network
export const config = {
runtime: "edge",
};Benefits:
- Faster global delivery
- Reduced bandwidth costs
- Better caching
- DDoS protection
Current State: Console.log only
Production Solution:
// Add Sentry
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
});Benefits:
- Real-time error alerts
- Stack traces
- User context
- Performance monitoring
Current State: Basic view counts
Production Solution:
// Add Vercel Analytics + PostHog
import { Analytics } from "@vercel/analytics/react";
import posthog from "posthog-js";
// Track user behavior
posthog.capture("video_uploaded", {
duration: videoDuration,
trimmed: isTrimmed,
});Benefits:
- User behavior insights
- Conversion tracking
- Performance metrics
- A/B testing capability
Current State: Full video download
Production Solution:
// Implement HLS/DASH streaming
import Hls from "hls.js";
const hls = new Hls();
hls.loadSource("video.m3u8");
hls.attachMedia(video);Benefits:
- Adaptive bitrate
- Faster initial load
- Better mobile experience
- Reduced bandwidth
Current State: Basic queries
Production Solution:
-- Add indexes
CREATE INDEX idx_videos_created_at ON videos(created_at DESC);
CREATE INDEX idx_videos_views ON videos(views DESC);
-- Add materialized views for analytics
CREATE MATERIALIZED VIEW video_stats AS
SELECT
DATE(created_at) as date,
COUNT(*) as uploads,
AVG(views) as avg_views
FROM videos
GROUP BY DATE(created_at);Benefits:
- Faster queries
- Better analytics
- Reduced database load
Current State: No caching
Production Solution:
// Add Redis caching
import { Redis } from "@upstash/redis";
// Cache video metadata
const cached = await redis.get(`video:${id}`);
if (cached) return cached;
// Cache for 1 hour
await redis.setex(`video:${id}`, 3600, videoData);Benefits:
- Reduced database queries
- Faster page loads
- Lower costs
Production Solution:
- Manual review queue for first-time users
- AI moderation (Google Cloud Vision API)
- Report/flag system for inappropriate content
- DMCA takedown process
Production Solution:
- GDPR compliance - data deletion requests
- Cookie consent banner
- Privacy policy and terms of service
- Data encryption at rest and in transit
Production Solution:
- Cloudflare proxy
- Rate limiting on all endpoints
- CAPTCHA for uploads
- IP blocking for abusers
Current State: Unlimited storage
Production Solution:
// Auto-delete old videos
const OLD_VIDEO_DAYS = 90;
// Cron job
export async function cleanupOldVideos() {
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - OLD_VIDEO_DAYS);
await supabase
.from("videos")
.delete()
.lt("created_at", cutoff.toISOString())
.eq("views", 0); // Only delete unwatched videos
}Benefits:
- Reduced storage costs
- Faster queries
- Better performance
For 1M+ videos:
- Partition by date/region
- Read replicas for analytics
- Separate database for metadata vs. analytics
For high traffic:
- Separate upload service
- Dedicated transcoding service
- Analytics service
- API gateway (Kong/Nginx)
- Supabase: $25/month (Pro plan)
- Vercel: $20/month (Pro plan)
- Cloudflare: $0 (Free tier)
- Total: ~$45/month
- Supabase: $599/month (Team plan)
- Vercel: $20/month (Pro plan)
- Cloudflare: $20/month (Pro plan)
- Mux/Cloudinary: $200/month (video processing)
- Total: ~$839/month
- AWS/GCP: Custom pricing
- CDN: $500+/month
- Video Processing: $2,000+/month
- Database: $1,000+/month
- Total: $5,000+/month
Frontend:
βββ Next.js 16 (App Router)
βββ TypeScript
βββ TailwindCSS
βββ Vercel (hosting)
Backend:
βββ Next.js API Routes
βββ Supabase (database + auth + storage)
βββ Redis (caching)
Video Processing:
βββ Mux or Cloudinary (transcoding)
βββ FFmpeg (server-side, if self-hosted)
Monitoring:
βββ Sentry (error tracking)
βββ Vercel Analytics (performance)
βββ PostHog (product analytics)
Infrastructure:
βββ Cloudflare (CDN + DDoS protection)
βββ Upstash (Redis + rate limiting)
βββ GitHub Actions (CI/CD)
This project is licensed under the MIT License - see the LICENSE file for details.
Note: This project was created as an assignment/portfolio piece. Feel free to use it for learning, evaluation, or reference purposes.
- Powered by Supabase
- UI components from Lucide Icons
- Toast notifications by Sonner
Made with β€οΈ by RahulKumar9988