Inspiration
Research confirms what we already feel: Gen Z has a lower attention span, but the content keeps getting harder. Research has also shown that newer generations find learning from the old is not as engaging anymore. Thus, there's a massive gap between what we need to learn and how we're able to learn. We built MITFE to bridge that gap, meeting students where they are, not where textbooks expect them to be.
What it does
MITFE is a website for students that adapts to their preferences with a multitude of functionalities such as: Sync Dashboard — Connect your Canvas (API URL and token in Settings). The app syncs courses, calendar events, and assignments into Supabase.
AI Lessons — Generates lessons from your course content (Featherless), with optional voiceover (MiniMax TTS) and audio-visual slides.
Study Buddy — Chat tutor and slide decks from your synced materials, with a configurable avatar and style.
Reels — Generates Instagram-style 15-second reels from what you are learning: random content from recent lessons or course materials, with MiniMax for voice and video. One button plays video and audio in sync; no server-side ffmpeg.
Progress and Memory — Track what you have studied and attach memories to courses.
How we built it
We used Next.js 14 (App Router), TypeScript, Tailwind CSS, and Supabase (Auth, Postgres, Storage). Bun handles install and scripts.
- Canvas sync — API routes call Canvas, normalize data, and store it in Supabase. Optional embeddings (local MiniLM, OpenAI, or MiniMax) for semantic search.
- Lessons — An LLM turns course material into lessons; MiniMax TTS adds voice; assets go to the lesson-audio bucket.
- Study Buddy — Chat and slide generation from synced content; MiniMax (or other) for images and chat.
- Reels — We pick random content, generate a short script (LLM), then MiniMax TTS to MP3 and MiniMax text-to-video (from a visual prompt: person talking, 3–4 different shots) to MP4. We upload both to Storage and return signed URLs. The client plays video (muted) and audio in sync with one Play button.
- Progress and Memory — Stored in Postgres with UI to view and manage them.
Challenges we ran into
Storage MIME types — The bucket initially allowed only audio. When we added reels (video and cover images), uploads failed with "mime type video/mp4 is not supported." We fixed it by updating the bucket allowed MIME types and added a script so existing deployments can do the same.
Video not playing — Sometimes the UI showed the storage URL as text. We switched to signed URLs and only set src when the value is a proper http URL.
Build and types — require('ffmpeg-static') broke ESLint; the package default export could be null. We switched to ESM import and a safe cast (e.g. via unknown) when reading the path.
Making reels feel longer — The video API max is 10 seconds. We request 10s and emphasise "long," "full-length," and "at least 10 seconds" in the visual prompt so the model uses the full duration.
Accomplishments that we're proud of
- Single pipeline for reels — One flow from random content to playable reel (script, voice, video, upload, signed URLs) with clear fallbacks (e.g. cover image and MP3 if video fails).
- No ffmpeg in production for reels — The client plays separate MP4 and MP3 in sync; simpler deployment and no binary dependency for this feature.
- Clear docs and scripts — README, env table, bucket setup, and an "update bucket MIME" script so both new and existing setups work.
- Reusable patterns — Signed URLs for media, prompt design (narration vs. visual), and handling API limits in code and prompts.
What we learned
- Supabase Storage — Bucket allowlists for MIME types matter; signed URLs give reliable inline playback for
<video>and<img>. - Video APIs — Duration limits are fixed (e.g. 6s or 10s); we use prompt design ("long," "full-length," "3–4 shots") to get the most out of that time.
- Two prompts for reels — Narration script for voice; separate visual prompt for video (who is talking, how many shots). Keeping them distinct made the pipeline easier to reason about and debug.
- ESLint and types — Prefer ESM import; use
as unknown as ...when dealing with nullable or loosely typed package exports.
What's next for MITFE
- Longer reels — If MiniMax (or another provider) supports longer clips, we will extend duration and adjust prompts.
- User choice of content — Let users pick a course, topic, or lesson before generating a reel instead of only random selection.
- Reel history and favourites — Save and list past reels, with optional "favourite" or "share" actions.
- Richer Study Buddy — Deeper integration with lesson progress and memory (e.g. "review what you struggled with" or "quiz from last week").
- Mobile-friendly UI — Optimise the reels and lesson experience for small screens and touch.
What's next for HTE
More reach, international
Log in or sign up for Devpost to join the conversation.