Peako Studio
Peako Studio is a professional video editing platform. Edit, export, and manage video workflows with a modern React-based interface powered by Remotion's compositing engine.
Live at: https://studio.shin0x.space
API at: https://peako.shin0x.space
Docs: This file + /docs/ folder
What's Inside
- Studio UI — React + Next.js app at
/studio/— login, dashboard, editor, settings, team management - API Backend — Fastify server at
/src/— video ops (trim/merge/mute/add-audio/subtitle/blur/speed-ramp), effects catalog, job queue - Remotion — Headless video composition engine at
/remotion/— renders video operations frame-by-frame - Queue — BullMQ + Redis (
peako-rediscontainer) — async job processing, status polling
Quick Start
Development (Local)
# Install dependencies
npm install
# Start backend (API server + job queue)
npm run dev
# In another terminal: start Studio frontend
npm run dev:studio
# Backend runs on http://localhost:3000
# Studio runs on http://localhost:3001
Production (Docker)
docker-compose up -d
# API: https://peako.shin0x.space (port 3000)
# Studio: https://studio.shin0x.space (port 3001)
Architecture
Frontend (/studio/src/)
Core Editor State: EditorCoreProvider + PeakoEditorCore singleton
CommandManager— undo/redo stack (Cmd+Z / Cmd+Shift+Z)TimelineManager— track + clip mutations (all wrapped as reversible Commands)PlaybackManager— Remotion Player integration (play/pause/scrub)MediaManager— asset upload/download (POST /api/assets/upload)SaveManager— 2-second debounced auto-save (POST /api/templates/:id) + status indicatorSelectionManager— multi-select clip state + UI sync
Pages:
app/login/— Google OAuth via PKCE flowapp/dashboard/— recent templates, create new, team overviewapp/edit/— full editor (3-panel: left menu | center preview | right controls + bottom timeline)app/settings/— user API keys, password reset, etc.app/teams/— create team, manage members, permissionsapp/teams/join/[token]/— invite link flow
UI Design: Paper+black color scheme
- Background:
#F5F0E8(cream paper) - Text:
#0A0A0A(deep black) - Accent:
#7A5C00(dark amber) - Shell:
#0A0A0A(black)
Backend (/src/)
Video Operations (Remotion-based)
POST /api/trim— trim video by time rangePOST /api/merge— concatenate multiple clipsPOST /api/mute— silence audio track or regionsPOST /api/add-audio— mix in audio track or musicPOST /api/subtitle— burn-in subtitles (SRT format)POST /api/blur— blur regions of videoPOST /api/speed-ramp— apply speed keyframes (FFmpeg, not Remotion)
Catalogs
GET /api/effects/catalog— all available effects with previews + paramsGET /api/transitions/catalog— transition library
Assets + Templates
POST /api/assets/upload— multipart video/audio upload, return{ url, filename, mimeType }GET /api/templates/:id— fetch template JSON (design state)POST /api/templates/:id— save template state (auto-save)POST /api/templates/:id/render— async job submission (returnsjobId, 202)POST /api/templates/:id/preview— sync preview frame render
Job Queue
GET /api/job/:jobId— poll job status (queued | active | done | failed)DELETE /api/job/:jobId— cancel queued/delayed job
Auth
GET /auth/google— OAuth initiate (state + PKCE code_challenge → Redis)GET /auth/google/callback— OAuth complete (exchange code + verifier, setpeako_sessioncookie)POST /auth/logout— clear session
Health
GET /health— live API + queue status
Deployment
Docker
# Build images
docker build -t peako-api:latest .
docker build -t peako-studio:latest -f studio.Dockerfile .
# Run with docker-compose
docker-compose up -d
# Logs
docker-compose logs -f peako-api
docker-compose logs -f peako-studio
docker-compose logs -f peako-redis
Environment Variables
# .env or credentials.env
# Server
PORT=3000
STUDIO_ORIGIN=https://studio.shin0x.space
PEAKO_ORIGIN=https://peako.shin0x.space
CORS_ORIGIN=https://studio.shin0x.space,https://peako.shin0x.space
# Google OAuth
GOOGLE_CLIENT_ID=<your-gcp-client-id>
GOOGLE_CLIENT_SECRET=<your-gcp-client-secret>
OAUTH_REDIRECT_URI=https://peako.shin0x.space/auth/google/callback
# Security
JWT_SECRET=<256-bit-random-string>
SESSION_SECRET=<random-string>
# Storage
STORAGE_TYPE=local|s3
BUNNY_API_KEY=<your-bunny-cdn-key>
BUNNY_ZONE_NAME=<your-zone>
# Redis
REDIS_URL=redis://peako-redis:6379
# Database
DATABASE_URL=sqlite:./db/peako.db
# Remotion
REMOTION_BUNDLE_PATH=/app/dist/index.js
API Response Models
Job Status
{
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "active|queued|done|failed",
"progress": 45,
"outputUrl": "https://cdn.bunny.net/peako/550e8400.mp4",
"error": null,
"createdAt": 1708852843000,
"updatedAt": 1708852890000
}
Asset Upload
{
"url": "https://peako-bucket.s3.us-east-1.amazonaws.com/assets/file.mp4",
"filename": "file.mp4",
"mimeType": "video/mp4",
"size": 5242880,
"duration": 120
}
Effects Catalog
{
"id": "fade-in",
"name": "Fade In",
"category": "appear",
"description": "Fades the clip up from black over the opening seconds.",
"preview": "https://..../fade-in.png",
"params": [
{
"name": "duration",
"type": "number",
"default": 0.5,
"min": 0.1,
"max": 5.0,
"description": "Fade duration in seconds"
}
],
"tags": ["fade", "appear", "intro"]
}
Security
- Auth: Google OAuth 2.0 with PKCE (RFC 7636) —
code_challenge_method=S256 - Session:
peako_sessioncookie (httpOnly, Secure, SameSite=Lax, Domain=.shin0x.space) - API Keys: Hashed + salted, stored in DB, rotated via
/api/user/key/rotate - CORS: Origins whitelist (
studio.shin0x.space,peako.shin0x.space) - SSRF Protection:
assertPublicUrl()on all URL inputs (trim src_url, add-audio src_url, etc.) - Path Traversal: Filenames validated as basename-only, no directory components
- Rate Limiting: 100 req/min global, 20-job per-user queue depth cap
Testing
E2E Tests (Playwright)
npm test # Run all tests
npm run test:track-f # Just QA Track F (ops + auth)
PLAYWRIGHT_BROWSERS_PATH=/opt/nops-labs/openclaw-main/config/workspace/tools/browsers npm test
Manual Testing
- Login: Go to
https://studio.shin0x.space, click "Sign in with Google" - Upload: Dashboard → New Project → Upload a video
- Edit: Drag clip to timeline, trim/cut, apply effect, add text
- Export: Click Export, choose quality (HD/4K), format (MP4/WebM), delivery (Response/CDN)
- Monitor: Jobs Dashboard shows status in real-time
Directory Structure
peako-studio/
├── src/ # Fastify backend
│ ├── routes/
│ │ ├── ops/ # /api/trim, /merge, /mute, etc.
│ │ ├── auth.ts # OAuth + session
│ │ ├── catalog.ts # Effects/transitions
│ │ ├── template.ts # Render + preview (deprecated)
│ │ ├── templates.ts # CRUD templates
│ │ ├── jobs.ts # Status + cancel
│ │ └── assets.ts # Upload endpoint
│ ├── services/
│ │ ├── remotion.ts # Remotion renderer
│ │ ├── ffmpeg.ts # FFmpeg operations
│ │ ├── storage.ts # S3/CDN uploads
│ │ ├── redis.ts # Redis client
│ │ ├── auth.ts # OAuth + JWT
│ │ └── db.ts # SQLite + schema
│ ├── effects/ # Effect registry
│ ├── queues/ # BullMQ job queues
│ ├── middleware/ # Auth + CORS
│ └── server.ts # Fastify app entry
├── studio/src/ # Next.js frontend
│ ├── app/ # Pages (login, dashboard, edit, teams)
│ ├── components/ # UI components
│ ├── core/ # PeakoEditorCore + managers
│ ├── features/ # Feature modules (editor, etc.)
│ ├── store/ # Zustand stores
│ ├── types/ # TypeScript types
│ └── lib/ # Utilities
├── remotion/ # Compositions
│ └── compositions/ops/ # TrimComp, MergeComp, etc.
├── Dockerfile # Multi-stage build (backend)
└── package.json
Contributing
- Read the API Reference
- Read the Studio User Guide
- Make your changes, test locally
- Push to
nOpsLabs/Peako-Studiomain - Tag
<@U0AF8CRD8DV>(PM Phil) in your PR
License
Proprietary — nOps Labs