Discite
╌╌╌╌
Discite turns idle screen time into learning: a short-form video app that teaches computer science fundamentals through bite-sized, swipeable clips, built for the way people actually spend an idle minute. I built it as my Dartmouth CS98 senior capstone, and it grew into a five-part platform: a SwiftUI iOS client, a TypeScript / Express API on MongoDB, a Python ML service that cuts long lectures into clips, a recommendation engine over a vector index, and an AWS streaming tier.
The app is SwiftUI, organized MVVM with a
Views / ViewModels / Models / Service split per feature.
Authentication obtains a JWT and stores it in the Keychain (KeychainItem),
with a Google sign-in path alongside email. Watch is the core surface: an
IGList-backed feed (PlayerView, EmbeddedVideoCell, NavigationDotsView)
where a SwipeDirection enum reads the drag gesture, sideways swipes stepping
through a topic's clips and a downward swipe advancing to the next topic, all
over a CustomVideoPlayer. Explore drives topics, playlists, and search;
Account holds profiles and a Friends graph. The client keeps no business
logic; it is a consumer of the REST API.
The backend follows Express's
model–controller–router layout in TypeScript, with Passport guarding routes by
JWT (requireAuth, requireSignin, requireAdmin). Mongoose maps a small set
of collections:
user
: names, lowercase-unique email and username, bcrypt password, savedPlaylists, isAdmin, email verification
video_metadata
: title, youtubeURL, topicId[], clips[], views / likes / dislikes sets, isVectorized, isClipped
clip_metadata
: videoId, duration, thumbnailURL, clipURL pointing at a CDN manifest, and the same engagement sets
user_affinity
: per-topic affinities and complexities maps in [0, 1], plus a bounded activeAffinities buffer of recent watches
Routes cover auth (/auth/signup, /auth/signin), the social graph
(/relationships, /connections/:userId), engagement (GET /videos/:videoId,
nested comment threads, and like / dislike / toohard / tooeasy, each of
which nudges the caller's affinity), and recommendations. Around fifty Cypress
specs exercise it end to end (affinity, recommendation, vectorized-rec,
watch-history, search, user, video).
Turning lectures into clips is the job of the ML service, a Dockerized
FastAPI app. Its /split route runs process_video, pulling a YouTube video's frames
and transcript, then labels both against a topic set: CLIP
(clip-vit-base-patch32) scores each frame and BART (bart-large-mnli)
does zero-shot classification on the transcript around each second. That yields
a per-second topic time-series, which a tfidf pass reweights so keywords
common to the whole video (SELECT throughout a SQL lecture) count for less
than distinctive ones. A sliding-window change detector then compares each
window's topic mixture against a running mean or median; when the gap crosses a
threshold it marks a clip boundary. Raw segments go to S3 and their metadata is
PUT to the API.
Choosing what to play falls to the engine, a separate FastAPI service over
a Pinecone cosine index (namespace video-transcripts) and an Algolia search
index. Candidate generation queries Pinecone for videos near a seed clip;
ranking then reorders them by taste, as VideoRanker adds each viewer's
per-topic affinity to the similarity score and re-sorts. The backend also
queries Pinecone directly for its vectorized feed. Two signals from the
affinity model, interest and difficulty, together with vector-space topic
similarity, decide the next clip, and every like, dislike, toohard, or
tooeasy event feeds back into the scores so the sequence adapts as you learn.
Clips never stream from the database. Bytes
live on Amazon S3 and reach the app over HLS through CloudFront. When the client
wants a clip it asks the API for a signed .m3u8; a Lambda fetches and caches
the CloudFront private key, checks that the request is authorized, and signs the
manifest, appending signed params to every .ts segment so playback loads
progressively. The public docs and marketing site is a separate Nuxt Content
app.
Read more in the Medium write-up and the project's architecture docs.
References
╌╌ END ╌╌