Ask your recordings. Watch the answer.
Turn hours of recorded lectures and talks into a library you can search, question and quote, where every answer is a playable clip of the moment it was said.
Live app · How to test · Cloudinary usage · Run locally · Docs
Hackathon project by Team Code Blooded - [hackindia-team:pixels-to-products-cloudinary-ai-hackathon-2026:code-blooded]
| Hackathon | Problem statement | Track | Team |
|---|---|---|---|
| Pixels to Products: Cloudinary AI Hackathon 2026 (HackIndia × Cloudinary) | PS-03 | Track 3: Your Media-Savvy Startup | Code Blooded |
- The problem
- What Pravaha does
- Screenshots
- How Cloudinary powers it
- Business case
- Architecture
- How to test it
- Quick start
- Scripts
- Project structure
- Quality and testing
- Security
- Deployment
- Documentation
- Team
- License
Colleges, clubs and coaching institutes record hundreds of hours of lectures and talks. Almost nobody rewatches them, because you can't search a video, skim it, or quote it. The knowledge is recorded, then lost.
| Watch | Upload a raw recording. Cloudinary transcribes it, chapters it and streams it adaptively. No editing. The transcript follows along as it plays, chapters are one tap away, and Ask this session answers questions about just that recording. |
| Find | Search every session for what was said and land on the exact second. |
| Ask | Ask a question in plain language. The answer comes only from your recordings, and every claim links to a playable clip of the moment it came from. Progress streams live while it works, and the answer suggests follow-up questions. If the library doesn't cover a question, Pravaha says so instead of guessing. |
| Answer Reels | The moments an answer cites, from different speakers and sessions, stitched into one labelled video. |
| Concept Map | /concepts lines up every concept your lectures teach and how many different teachers explain it. Open one and hear the same idea from each lecturer, back to back, as one Cloudinary-spliced video, until one explanation clicks. |
| Learning Paths | /learn: type a topic and get a 3–5 step course, ordered basics first, drawn from moments across the library and edited into one video. |
| Data saver | One switch (and automatic on Save-Data or 2G/3G) serves smaller, lower-quality Cloudinary renditions: thumbnails 76% lighter, clips and reels 38–41%, and a streaming ladder that tops out at 0.9 Mbps instead of 3.4. Built for India’s mobile data. |
| Weak spots | Quiz mistakes are remembered on your device and come back as one Cloudinary reel of exactly the explanations you missed, with the answer and the second to jump to. Get a question right and it leaves the list. |
| Study notes | Every session has a study sheet at /notes/[id]: summary, key concepts, chapters and the quiz with answers, each point linked to its timestamp. Copy it as Markdown, download it, or save it as a PDF. |
| Revision reel | On /saved, the latest saved moments from any sessions play as one labelled video: a revision reel for the night before an exam. |
| Voice | Tap the microphone in the Ask bar and say the question, in English or Hindi. The browser turns speech into text, so no audio reaches Pravaha. |
| Installable | Add Pravaha to a phone's home screen; it opens full-screen and shows a friendly page when offline. |
| Study Packs | Every session gets a summary, key concepts, a quiz whose explanations play the moment the teacher explains it, and a "Session in 60 seconds" highlight reel. Pravaha generates them automatically from the transcript. |
| Moments | One tap turns any cited clip into a vertical, AI-cropped, subtitled short for WhatsApp or Instagram, with its own share page and preview card. The short is just a Cloudinary URL; nothing is rendered. |
| Insights | Organizers see what learners ask, the knowledge gaps the library can't answer yet (what to record next), and which Moments get shared. Every report downloads as CSV. Visitors can explore a read-only demo of the Studio. |
| Embed | Organizers copy one <iframe> from the Studio and put Ask inside Moodle, Canvas or any course page, for the whole library or one session. Only that route can be framed. See docs/EMBED.md. |
| Try it | Anyone can upload a short video at /try, no account: Cloudinary keeps the first 60 seconds, transcribes and chapters it, and about 20 seconds later it has a Study Pack and an Ask this session box. Trials are private and deleted after 24 hours. |
ChatGPT gives you text. Pravaha gives you the moment your professor said it.
Shown in dark mode; the light theme is one tap away in the header and follows the system setting by default.
| Home | Watch: follow-along transcript, chapters, Ask this session |
|---|---|
![]() |
![]() |
| Studio (public read-only demo): Insights | Cloudinary under the hood |
|---|---|
![]() |
![]() |
The demo library: six machine-learning lecture excerpts from four NPTEL courses.
Ask on a phone. Every screen is built mobile-first.
Cloudinary isn't just storage here; the product depends on it.
| Capability | Used for |
|---|---|
| Upload Widget + signed upload preset | Browser-to-Cloudinary video upload with real progress, no server proxy |
auto_transcription |
Word-timed transcript: the corpus for Find and Ask, plus subtitles |
auto_chaptering |
AI chapters on the player's seek bar |
Cloudinary Video Player, HLS sp_hd_lean |
Adaptive streaming (720p / 360p / 180p) that survives slow mobile data |
e_preview,fl_getinfo, fl_sprite |
The player's AI highlights graph and seek-bar previews |
e_preview:duration_6 |
AI hover previews on library cards: the session's most interesting moments in 6 silent seconds |
so_/eo_ + c_fill,ar_9:16,g_auto + timed l_text captions + f_auto,q_auto |
Moments: trimmed, subject-tracked, subtitled vertical clips |
g_auto thumbnails and poster frames |
Content-aware library cards, results and social preview cards |
q_auto:low, c_limit/w_ sizing, sp_sd streaming profile |
Data saver: every video, reel, thumbnail and the HLS ladder re-requested lighter for slow or metered connections |
l_video:…,fl_splice + timed l_text labels |
Answer Reels and Session in 60 seconds: moments from one or more sessions stitched into one video |
Webhooks (notification_url, signature-verified) |
Upload → transcribed → ready with no polling |
Incoming transformation eo_60 on a second signed preset |
Try it uploads: Cloudinary keeps only the first 60 seconds, so a public upload can't cost more |
What we built on top:
- turning transcripts into time-coded segments and indexing them
- library-wide retrieval and ranking (Postgres full-text search)
- grounded Ask, with citations checked on the server and refusal when the library doesn't cover a question
- the Moment and Reel URL composers
- the learner and organizer experience
Every session page and answer has a Cloudinary under the hood panel that lists the real URLs behind it, with each transformation explained in plain words and an Open button.
Full detail: docs/CLOUDINARY.md.
Track 3 asks for something you could pitch. Pravaha's pitch, in short (full version, with every number tagged actual, estimate or assumption: docs/BUSINESS.md):
- Who pays: coaching institutes first (their recorded classes are their product, and doubts cost teacher time), then college departments, then companies with recorded trainings.
- Why it wins: the answer is a clip of their own teacher saying it, never a chatbot's guess; it says "not covered" instead of bluffing, and that becomes a knowledge-gap report. Each institute's corpus and learner questions become a moat.
- Why Cloudinary's pricing fits: no transcoding farm, no GPUs. Transcripts, chapters, streams, crops, reels and share cards are generated on demand and cached, so cost follows what is watched, not what is stored. Hosting one hour of content is about 28.8 Cloudinary credits if every rendition is generated, and Ask costs a fraction of a cent.
- Pricing hypothesis (to validate, nobody has paid yet): a free pilot for one batch, then a one-time processing fee per content-hour plus a monthly fee per active learner.
- The binding constraint, shown live: Cloudinary credits.
/statusshows usage and warns at 80% and 95%.
flowchart TB
subgraph Org["Organizer"]
O["Studio · upload · Insights"]
end
subgraph Learn["Learner · phone or laptop"]
L["Ask · Find · Watch · Concepts · Learn · Saved · Notes"]
end
subgraph Cloudinary["Cloudinary: the media plane"]
U["Signed upload preset"]
AI["auto_transcription · auto_chaptering · hi-IN translate"]
T["Transformations on demand: Moments · Reels · cards · previews · data saver"]
S["HLS streaming · f_auto · q_auto"]
X["Tags + context + Search API"]
end
subgraph App["Next.js 16 on Vercel: the knowledge plane"]
W["Signed webhook"]
R["Retrieval · question understanding"]
G["Grounded answer + citation validation"]
P["Study Packs · Learning Paths · Concept Map · Notes"]
ST["/status · /api/health"]
end
DB[("Neon Postgres: segments · full-text index · packs · insights")]
M["Gemini → Groq fallback chain · circuit breaker"]
O -- video bytes, signed --> U
U --> AI
AI -- webhook --> W
W -- time-coded segments --> DB
W -- study pack --> P
P -- tags and context --> X
L -- question --> R
R --> DB
R --> G
G <--> M
G -- validated citations + clip URLs --> L
T -- clips · reels · shorts --> L
S -- adaptive video --> L
ST -. checks .-> DB
ST -. checks .-> M
ST -. credits .-> Cloudinary
- One Next.js 16 app (App Router: frontend and API together), deployed on Vercel.
- Neon Postgres holds sessions, time-coded segments, the full-text index and insights.
- Cloudinary handles everything to do with media.
- Gemini handles the AI, with a model fallback chain ending in Groq (
gpt-oss-120b) as a backup provider, and output validated against a Zod schema. If every model fails, Pravaha shows the most relevant clips instead of an error.
Diagrams and reasoning: docs/ARCHITECTURE.md · docs/TRD.md.
Judges:
/judgesmaps the submission requirements to the Cloudinary features, with live URLs and a 90-second test.
Open the live app at pravaha-cyan.vercel.app. Learners need no login.
-
On the home page, type a question or tap a suggestion. Try "Why should the learning rate decrease during training, and how do adaptive optimizers handle it?": live progress appears, then one answer citing two professors from two institutes, plus an Answer Reel. Or ask in Hindi: "ओवरफिटिंग क्या है?"
-
Hover or tap a citation number to preview the quote. Play a source card: the clip starts at the exact moment. Then try Watch the answer (the Answer Reel), Open full session or Share as Moment.
-
On a session page, open Study: the summary, key concepts, a quiz whose explanations play the moment, and "Session in 60 seconds".
-
Search a phrase. The results jump to the second, across sessions.
-
Ask something off-topic ("Who won the IPL?"). Pravaha says the library doesn't cover it instead of making something up.
-
Press
/orCtrl/⌘ Kanywhere to jump to the Ask bar. -
Open Try it and upload any short video with speech (up to 50 MB). Follow the live pipeline, then ask it "What is this video about?" on its page.
-
Open Studio: a read-only demo of the organizer side, with every session's pipeline output and live Insights (knowledge gaps, most asked questions, answers rated helpful). Uploading to the main library and publishing need the organizer passcode at
/studio/sign-in. -
Open Status: live database health, every AI model, and the Cloudinary credits the media runs on.
-
Tap the microphone in the Ask bar (Chrome or Safari) and ask by voice, or switch it to Hindi with the EN / हिं button.
Prerequisites:
- Node.js 20+
- pnpm 9
- Free accounts for Cloudinary, Neon and Google AI Studio
git clone https://github.com/Monolithic-Dev/Pravaha.git
cd Pravaha
pnpm install
cp .env.example .env.local # fill in the values, see SETUP.md
pnpm db:migrate
pnpm dev # http://localhost:3000SETUP.md walks through every account from zero and explains every environment variable:
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME, NEXT_PUBLIC_CLOUDINARY_API_KEY |
Public Cloudinary identifiers for the player and Upload Widget |
CLOUDINARY_API_SECRET, CLOUDINARY_UPLOAD_PRESET |
Server-side signing and the signed upload preset |
CLOUDINARY_TRIAL_PRESET, TRIALS_PER_DAY |
Optional: the /try preset (default pravaha_trial) and the daily trial cap (default 5; 0 turns trials off) |
STUDIO_DEMO |
Optional: on (default) shows visitors a read-only Studio; off keeps it behind the passcode |
DATABASE_URL |
Neon Postgres connection string |
GEMINI_API_KEY, GEMINI_MODELS |
Gemini key and the ordered model fallback chain |
GROQ_API_KEY |
Optional backup AI provider, used when every Gemini model fails |
ORGANIZER_PASSCODE, SESSION_SECRET |
Studio sign-in and the signing key for its session cookie |
APP_URL |
Public base URL (webhooks, share links, preview cards) |
| Command | What it does |
|---|---|
pnpm dev |
Start the dev server |
pnpm build / pnpm start |
Production build / serve it |
pnpm lint · pnpm typecheck |
ESLint · tsc --noEmit |
pnpm test |
Unit tests (Vitest) |
APP_URL=… pnpm test:e2e |
Playwright smoke tests against a deployed app, desktop and mobile |
pnpm eval:ask |
Evaluate Ask: grounding, citations and refusals (docs/AI_EVALUATION.md) |
pnpm db:migrate |
Apply database migrations |
pnpm preset:trial |
Create or update the 60-second trial upload preset used by /try |
src/
app/ Routes (App Router)
page.tsx Home: Ask bar, how it works, library
search/ Ask + Find results
watch/[id]/ Player, chapters, transcript, Study Pack
m/[segmentId]/ Shareable Moment page with its own preview card
studio/ Organizer: upload, publish, insights
api/ ask · search · lectures · upload-signature · webhooks · organizer · insights · events
components/ UI (client components where interactivity needs it)
lib/ Server logic: retrieval, grounded answers, citation checks, Cloudinary URL composers,
ingest, auth, rate limits, env validation
tests/
unit/ Vitest
e2e/ Playwright smoke tests
eval/ Ask evaluation set
scripts/ Migrations, eval runner, local end-to-end
docs/ Product, technical, security and process docs
openapi.yaml API specification (OpenAPI 3.0)
- CI runs lint, typecheck, unit tests and a production build on every pull request and every push to
main. - Unit tests cover the parts that decide what users see:
- citation validation and refusal
- follow-up question cleaning
- transcript segmentation
- the Moment and Reel URL composers
- Study Pack validation, chapter parsing and upload-signing policy
- webhook signatures and passcode checks
- End-to-end smoke tests run in Playwright on desktop and mobile against the live deployment:
- home page
- Find lands on the exact second
- Ask answers with a playable citation
- Ask refuses an off-topic question
- unauthenticated organizer requests and unsigned webhooks are rejected
- The AI eval (
docs/AI_EVALUATION.md) on production, Oct 2: 11/11 passed: 8/8 answerable questions cited the expected session (including one in Hindi), 3/3 off-topic questions refused, 0 fallbacks, and 31/32 citations (97%) supported their sentence on a manual check. - Accessibility: a skip link, visible focus rings, keyboard shortcuts, and every animation disabled under
prefers-reduced-motion.
- Organizer routes need a passcode session: a signed,
HttpOnlycookie. - Uploads are signed, short-lived and size-capped.
- Cloudinary webhooks are signature-verified.
- Ask is rate-limited per IP before any paid call.
- Model output is schema-validated, and citations are checked against what was actually retrieved, which defends against prompt injection.
- No credentials are committed anywhere in this repository or its history.
Details: docs/SECURITY.md.
The app deploys to Vercel: every push to main deploys production, and pull requests get preview deployments. Environment variables live in Vercel, with secrets marked Sensitive. Step-by-step: SETUP.md §7.
| Doc | What's in it |
|---|---|
docs/VISION.md |
Why this is a company: wedge, customer, growth loop, roadmap |
docs/PRD.md |
Problem, users, requirements, acceptance criteria |
docs/CLOUDINARY.md |
Every Cloudinary capability, and what breaks without it |
docs/TRD.md · docs/ARCHITECTURE.md |
Stack, reasoning, diagrams |
docs/DATABASE.md · docs/API.md · openapi.yaml |
Schema and endpoints |
docs/EMBED.md |
Putting Ask inside an LMS: snippet, sizing, framing policy |
docs/AI_EVALUATION.md |
Ask's retrieval, prompt, citation validation, fallback and eval |
docs/UX_UI.md · docs/DESIGN_SYSTEM.md |
Screens, interaction and motion, design tokens |
docs/SECURITY.md · docs/COST.md |
Trust boundaries and cost controls |
docs/TESTING.md · docs/OBSERVABILITY.md |
Test strategy, logs and events |
docs/DECISIONS.md |
Every decision with alternatives and trade-offs, including what we changed and why |
docs/IMPLEMENTATION_PLAN.md · docs/phases/ |
The 3-day build, phase by phase |
docs/GIT_WORKFLOW.md |
Branch per feature, PR, merge rules |
docs/DEMO.md · docs/SUBMISSION_CHECKLIST.md |
Demo script and submission tracking |
The live library is six 2.5–3 minute excerpts from NPTEL (IIT/IISc's National Programme on Technology Enhanced Learning) machine-learning courses, licensed CC BY-NC-SA. The excerpts are shared under the same licence, for non-commercial demonstration, with credit to:
| Session | Course | Institute |
|---|---|---|
| Overfitting, Underfitting and Regularization · From AdaGrad to RMSProp | Deep Learning, Prof. Prabir Kumar Biswas | IIT Kharagpur |
| The Bias–Variance Trade-off · Learning Rate Decay · Gradient Descent Variants and Momentum | Machine Learning for Engineering and Science Applications | IIT Madras |
| Underfitting and Overfitting in Practice | Practical Machine Learning with TensorFlow | IIT Madras |
Pravaha is built for an institution's own recordings; these public lectures stand in for them in the demo.
Code Blooded: @Mahakisore7 · @im-rk
Built in three days for Pixels to Products: Cloudinary AI Hackathon 2026, organized by HackIndia × Cloudinary.
Apache-2.0. Pravaha is built on Cloudinary, Next.js, Neon and Google Gemini.




