Skip to content

MindDock/mj-dance-analyzer

Repository files navigation

MJ Dance Studio

用普通摄像头或本地视频,获得专业级 MJ 舞步评分。

依托 MediaPipe BlazePose 实时追踪 33 个人体关键点,逐关节提取角度,自动对比内置的 MJ 标准骨骼参考,每一帧动作立即量化反馈。无需传感器,无需后端,打开浏览器即用。

MediaPipe React TypeScript Vite License


Features

Feature Detail
🦴 Virtual Reference Dancer 8 signature MJ moves encoded as canonical 33-landmark keyframe sequences, interpolated to BPM and rendered as a live AR skeleton
📷 Live Camera Mode MediaPipe BlazePose at 60 fps, 33 joints, fully on-device — no data leaves the browser
🎬 Video Analysis Mode Upload any MP4 / MOV / WebM recording of yourself; pose detection and scoring run frame-by-frame
📐 Joint-Weighted Scoring Each move weights joints differently — Smooth Criminal grades torso lean hardest; Robot Lock grades elbow angles
📊 Real-time Analytics Per-joint radar chart, smoothed S→D grade gauge, combo counter, coach feedback
▶️ YouTube Reference Panel Pin any YouTube live performance to any move; persists in localStorage

Moves Catalog

Move 中文名 Era Difficulty
The Moonwalk 月球漫步 Motown 25 · 1983 Signature
Anti-Gravity Lean 反重力倾斜 Smooth Criminal · 1988 Master
Toe Stand 足尖站立 Heal The World Tour · 1992 Intermediate
Pelvic Snap 招牌动作 Bad Tour · 1987 Signature
The Spin 招牌旋转 Dangerous Tour · 1992 Master
Side Slide 侧滑 This Is It · 2009 Beginner
Sidewalk 侧步 Bad Tour · 1987 Intermediate
Robot Lock 机器人锁定 Dancing Machine · 1974 Beginner

Quick Start

git clone https://github.com/MindDock/mj-dance-analyzer.git
cd mj-dance-analyzer
npm install
npm run dev

Open http://localhost:5173 — no API keys, no backend, no sensor hardware required.


How It Works

┌─────────────────────────────────────────────────────────────────┐
│                           Browser                               │
│                                                                 │
│  ┌─────────────────┐      ┌──────────────────────────────────┐  │
│  │ Reference Dancer│      │         Your Input               │  │
│  │                 │      │  ┌───────────┐  ┌─────────────┐  │  │
│  │  Canonical KFs  │      │  │  Webcam   │  │ Video file  │  │  │
│  │  BPM-animated   │      │  │ (mirrored)│  │ (MP4/MOV…)  │  │  │
│  │  AR skeleton    │      │  └─────┬─────┘  └──────┬──────┘  │  │
│  └────────┬────────┘      │        └────────┬───────┘         │  │
│           │               │                 │                  │  │
│    extractAngles()        │    MediaPipe BlazePose @ 60fps     │  │
│    (reference)            │    extractAngles() (user)          │  │
│           │               │                 │                  │  │
│           └───────────────┼────── scoreFrame() ───────────────┘  │
│                           │   joint-weighted diff                 │
│                           │   → overall 0-100 · S/A/B/C/D        │
│                           │   → per-joint radar                   │
│                           └──────────────────────────────────────┘
└─────────────────────────────────────────────────────────────────┘

Scoring

Each joint has a tolerance window (degrees). Per-joint score:

score = max(0, 100 × (1 - |ref_angle - user_angle| / (tolerance × 2.2)))

Overall score is a weighted average — focus joints for the current move carry higher weight, defined per move in src/data/mjMoves.ts.


Project Structure

src/
├── data/
│   ├── keyframes.ts        # Canonical 33-landmark keyframe sequences (8 moves)
│   └── mjMoves.ts          # Move metadata: BPM, difficulty, breakdown, focus weights
├── lib/
│   ├── poseMath.ts         # Angle extraction, interpolation, scoring, smoothing
│   ├── poseTypes.ts        # Pose33, Landmark, AngleMap, JointKey, Keyframe
│   ├── skeleton.ts         # Canvas: bone glow, joint circles, angle annotations
│   ├── mediapipeLoader.ts  # Lazy CDN loader (no bundled WASM)
│   └── youtube.ts          # YouTube URL parser + localStorage persistence
├── components/
│   ├── ReferenceDancer.tsx    # BPM-animated canonical skeleton canvas
│   ├── LivePoseCanvas.tsx     # Webcam/video → MediaPipe → skeleton overlay
│   ├── ScoreGauge.tsx         # Animated arc gauge with grade letter
│   ├── JointRadar.tsx         # SVG spider chart of per-joint accuracy
│   ├── YouTubeFrame.tsx       # YouTube embed with pinnable videoId
│   ├── MoveCard.tsx           # Library grid card with live dancer preview
│   └── Header.tsx             # Sticky nav
└── pages/
    ├── Landing.tsx      # Hero + feature overview
    ├── Library.tsx      # Filterable move catalog grid
    ├── MoveDetail.tsx   # Demo, breakdown steps, angles, YouTube reference
    └── Studio.tsx       # Live training: reference + camera/video + scoring

Tech Stack

  • Framework — React 19, TypeScript 6, Vite 8
  • Pose detectionMediaPipe BlazePose (CDN, WASM on-device)
  • Fonts — Fraunces (display) · Inter (body) · JetBrains Mono (data)
  • No UI framework — pure CSS custom properties + canvas

Privacy

All pose tracking runs entirely in the browser. No video frames, landmarks, or scoring data are sent to any server.

External requests (on demand only):

  • Google Fonts — typography
  • jsDelivr CDN — MediaPipe WASM model files (loaded once, cached by browser)
  • YouTube — only if you pin a performance video

License

MIT © MindDock

About

Real-time MJ dance training in the browser — MediaPipe BlazePose, canonical keyframe reference dancer, joint-weighted scoring

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages