ShuttleIQ is a SwiftUI-based badminton performance analysis platform designed to help players improve through video-driven feedback, session tracking, and performance visualization.
The application allows users to:
- record or upload badminton clips,
- organize sessions by training focus,
- receive real pose-derived analysis feedback from the backend,
- and track long-term progress across multiple performance categories.
Players can analyze sessions across four training categories:
- Offense
- Defense
- Footwork
- Consistency
Each category maintains its own:
- performance graph,
- session history,
- and feedback flow.
Each also has its own analyzer on the backend, scoring different pose geometry from the same extracted frame sequence.
- Dynamic focus mode selection
- Recent clip preview
- Training recommendations
- Performance summary cards
- Session feed
- Record video directly from camera
- Upload clips from photo library
- Video preview before analysis
- Session creation flow — uploads the clip to the backend
- Profile picture support
- Goal selection
- Skill level tracking (sent to the backend as
skill_level) - Persistent player profile state
- Session-based performance graphs
- Category-specific score tracking
- Dynamic graph updates from analysed sessions
- Video playback preview
- Session metadata
- Score visualization
- Focus-mode-specific coaching feedback
- Live backend analysis pipeline
- Loading, complete, and failure states with retry
- Real breakdown, findings, strengths, and next-focus data
Built using:
- SwiftUI
- AVKit
- ObservableObject / @StateObject shared state architecture
- Xcode + iOS Simulator workflow
A Python backend performs the analysis:
- video frame extraction,
- MediaPipe pose estimation,
- per-focus-mode session scoring,
- structured findings and recommendations.
Current backend stack:
- FastAPI
- OpenCV
- MediaPipe
- Python-based analysis pipeline
The app posts a clip to POST /analyze and renders the returned JSON on the Analysis screen.
ShuttleIQ/
├── backend/
│ ├── main.py # FastAPI app: /health, /analyze
│ ├── core/ # video frame extraction, MediaPipe pose
│ ├── analysis/ # one analyzer per focus mode
│ ├── schemas/ # AnalysisResult response model
│ ├── scripts/ # fetch_model.sh
│ ├── models/ # pose_landmarker.task (not committed)
│ └── requirements.txt
│
└── swiftui/ShuttleIQSwiftUI/
├── App/
├── Core/ # Theme, AppCard, ClipPreviewView
├── Features/ # Home, Record, Profile, Progress, Session, Analysis
├── Models/
├── Services/ # APIConfig, DTOs, AnalysisAPI, VideoExporter
├── Stores/
└── Info.plist
The MediaPipe pose model is a ~5.8 MB binary and is not committed. Fetch it once after cloning — the server refuses to start without it:
cd backend
./scripts/fetch_model.shThen set up and run:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload --host 0.0.0.0 --port 8000--host 0.0.0.0 matters: without it the server only accepts loopback
connections and a physical iPhone cannot reach it.
- Docs: http://localhost:8000/docs
- Health:
GET /health - Analyse:
POST /analyze—multipart/form-datawithfile,focus_mode(offense|defense|footwork|consistency), andskill_level(beginner|intermediate|elite)
Quick check:
curl -F "file=@clip.mov" -F "focus_mode=offense" -F "skill_level=intermediate" \
http://localhost:8000/analyzeA frames_analyzed of 0 means no player was detected in the clip.
Open swiftui/ShuttleIQSwiftUI/ShuttleIQSwiftUI.xcodeproj and run.
The Simulator shares the Mac's network stack, so it reaches the backend at
http://localhost:8000 with no configuration.
On a physical device, point the app at your Mac's LAN IP (see
Services/APIConfig.swift):
APIConfig.baseURLOverride = "http://192.168.1.42:8000"Info.plist permits cleartext HTTP to local addresses via NSAllowsLocalNetworking.
Planned future improvements:
- Reference-video and pose comparison scoring
- LLM-generated coaching feedback layered on the analyzer findings
- Persistent session storage (sessions are currently in-memory)
- Left-handed player support (analyzers are currently right-hand-only)
- Multi-device syncing
- Enhanced animations and performance visualization
- Advanced player analytics
Code is primarily edited using:
- Cursor
- Claude Code
- SwiftUI architecture
The application is built and run through:
- Xcode
- iOS Simulator
- physical iPhone testing
ShuttleIQ is currently in active development as an experimental AI-assisted sports analysis platform focused on badminton training and player improvement. The frontend and backend are now wired end to end; analysis is real pose-derived scoring, with LLM coaching feedback planned next.