TutorLoom
The learning platform for companies, colleges and training institutes. Free and open source, with an Enterprise edition.
Turn any lesson topic into a visual, narrated lesson in English, Hindi or Kannada. Learn anything. See it clearly. Hear it in your language.
EducationGitHub @rajyyug1132OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
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 ↗Type a concept, get a narrated, animated 30–90 second lesson that plays in the browser and downloads as an MP4, in English, Hindi or Kannada. Everything runs on the laptop: no cloud AI, no CDN, Wi-Fi can be off. The local LLM only returns lesson data (JSON); all drawing code is ours.
topic ──> classify (formula?) ──> plan (Ollama qwen2.5:3b, schema-constrained JSON, English)
│ └─ guard: arithmetic check, spoken-number audit, ladder
│ 3b retry -> 7b escalation -> qualitative -> safe template
▼
IndicTrans2-200M + IndicProcessor (one batched call per language)
▼
TTS per scene: Kokoro-82M (EN/HI) · MMS-TTS (KN) -> 24 kHz WAV + 0.35 s tail, measured durations
▼
duration gate (30–90 s) ──> manifest.json (scene start/end from real audio)
▼
renderer/player.html: window.renderAtTime(t) on a 1280x720 canvas (pure function of t)
▼
Playwright frames @20 fps ──> FFmpeg image2pipe ──> lesson.mp4 (h264 yuv420p + AAC)
Code map: orchestrator/ (planner, guard, cache, pipeline) · localization/ (translation, TTS, captions) ·
renderer/ (canvas engine, 8 templates) · web/ (UI) · exporter/ (MP4 export, FastAPI, harness).
Follow these steps to run the full application locally on your machine.
v1)git clone https://github.com/rajyyug1132/blue-visual-teacher
cd blue-visual-teacher
python -m venv .venv
.\.venv\Scripts\pip install -r requirements.txt
ollama pull qwen2.5:3b
# Ensure FFmpeg is installed and accessible on your PATH (ffmpeg -version)
.\.venv\Scripts\python.exe -m playwright install chromium
# Download and pre-cache Hugging Face weights (IndicTrans2, Kokoro, MMS-TTS) while online:
.\.venv\Scripts\python.exe -c "from localization.warmup import run_all_warmups; run_all_warmups()"
Note: All subsequent generation runs operate completely offline with HF_HUB_OFFLINE=1.
Terminal 1 — Lesson Server (Backend on :8000):
powershell -ExecutionPolicy Bypass -File run_demo.ps1
Terminal 2 — Next.js Product UI (:3000):
npm install
npm run dev
Open http://localhost:3000 in your browser.
v1)git clone https://github.com/rajyyug1132/blue-visual-teacher
cd blue-visual-teacher
python3 -m venv .venv
./.venv/bin/pip install -r requirements.txt
ollama pull qwen2.5:3b
# Ensure FFmpeg is installed and accessible on PATH (ffmpeg -version)
./.venv/bin/python -m playwright install chromium
# Download and pre-cache Hugging Face weights while online:
./.venv/bin/python -c "from localization.warmup import run_all_warmups; run_all_warmups()"
Terminal 1 — Lesson Server (Backend on :8000):
./run_demo.sh
Terminal 2 — Next.js Product UI (:3000):
npm install
npm run dev
Open http://localhost:3000 in your browser.
npm start: Production build and start (next build && next start).npm run server: Run the legacy standalone static mock demo on :3000 (web/ + ?mock=1).python scripts/precache.py: Pre-generates the 10 example topics into cache/artifacts for instant demo playback.run_demo automatically pins qwen2.5:3b with keep_alive=-1, warms the translator and TTS once, and serves exporter.app:app at :8000.Checks: python -m pytest tests/ (includes tests/test_e2e_offline.py, which blocks outbound sockets) and
python -m orchestrator.done_checks (BLUEPRINT DONE list D1–D10, evidence in logs/).
| Component | Model / package | Role | License | Notes |
|---|---|---|---|---|
| LLM planner | qwen2.5:3b (escalation qwen2.5:7b) via Ollama | English JSON lesson planning | Apache 2.0 (Qwen2.5 3B: Qwen Research License) | Runs locally through the Ollama daemon; no external API |
| Indic translation | ai4bharat/indictrans2-en-indic-dist-200M + IndicTransToolkit | English to Hindi, Kannada (Tamil, Telugu) | MIT | One batched call per language; formulas protected from translation |
| EN and HI speech | hexgrad/Kokoro-82M + misaki + espeak-ng | 24 kHz speech synthesis | Apache 2.0 (espeak-ng: GPL-3.0, invoked as a separate program) | Voices af_heart (EN), hf_alpha (HI) |
| KN speech | facebook/mms-tts-kan (VITS) | 16 kHz speech, resampled to 24 kHz | CC-BY-NC 4.0 | Non-commercial; fine for the hackathon, swap for ai4bharat/indic-parler-tts (Apache 2.0) commercially |
| Indic typography | Noto Sans, Noto Sans Devanagari, Noto Sans Kannada (+ Tamil, Bengali) | Script shaping on the canvas | SIL Open Font License 1.1 | Bundled in assets/fonts (OFL.txt included); the app serves them at /renderer/assets/fonts, zero CDN calls |
| Video and web stack | Playwright (Chromium), FFmpeg (libx264), FastAPI, Pydantic | Frame capture, MP4 muxing, API, schema validation | Apache 2.0 / LGPL-GPLv2+ (libx264 GPL) / MIT / MIT | Invoked locally; libx264 via the FFmpeg binary |
renderAtTime(t) is a pure function of time: no setInterval, no unseeded random,
no clock reads. The same frame twice gives the same pixels, so export and preview match.LessonPlan.model_json_schema(); Pydantic validates.check {expr, result}; Python evaluates it with an
AST whitelist (never eval), fixes a wrong result where it is stated, and makes the narration say the answer.logs/ and STATUS.md; this README does not claim results the logs don't show.Yyug (orchestrator), Tarun (localization), Farhan (renderer and UI), Ayush (export, API, tests).