Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SpeakBalance

Privacy-conscious participation analytics experiment for online language classes.

SpeakBalance was a short technical feasibility prototype. It explored whether Zoom active-speaker metadata could estimate participation balance without recording or transcribing lesson content.

Project status: Technical feasibility prototype - concluded after identifying a platform-data limitation.

The Problem

Language teachers and teacher trainers often discuss Teacher Talk Time and Student Talk Time, but measuring that balance objectively during a live online lesson is difficult.

Recording or transcribing lessons can create privacy, consent, and data handling concerns. SpeakBalance explored whether a lighter metadata-only signal could support teacher reflection.

The Hypothesis

Could Zoom active-speaker metadata estimate participation balance without using lesson audio, video, transcripts, chat, or content analysis?

The intended data boundary was:

  • participant display name
  • participant metadata needed for in-session event identity
  • active-speaker event time
  • teacher/student role mapping
  • estimated active-speaker duration

What I Built

  • React/Vite frontend
  • Zoom Apps SDK onActiveSpeakerChange integration
  • local active-speaker capture flow
  • event normalisation and duplicate-event handling
  • speaking-segment generation
  • inactivity-timeout estimation for unclear gaps
  • teacher/student/unknown role mapping
  • per-speaker and per-role participation summaries
  • final session report view
  • plain text report export
  • sample-data demo pipeline for local review

What I Tested

The Zoom integration was tested in real Zoom desktop meetings, not only against mocked data.

The tests checked whether active-speaker events fired, whether they included usable participant metadata, how duplicate events behaved, how silence was represented, and whether speaker handovers could be detected.

What I Found

  • onActiveSpeakerChange successfully identified active participants.
  • Repeated and duplicate events required cleaning before analytics.
  • Same-speaker events could be sparse during continuous speech.
  • Zoom did not provide a sufficiently reliable stop/silence signal for exact stopwatch-style timing in this implementation.
  • Timeout logic could estimate unclear gaps, but it could not measure silence exactly.
  • Additional Zoom SDK event paths were investigated, but they did not provide a reliable replacement for exact start/stop timing.

The result is best described as estimated participation analytics, not exact talk-time measurement.

Decision

Development stopped at the feasibility stage.

The prototype proved that the app could integrate with Zoom and capture useful active-speaker metadata. It also showed that the available metadata was not granular or consistent enough for accurate speaking-duration measurement.

Building authentication, databases, backend storage, payments, deployment, or a larger product workflow on top of that assumption would have been premature. Stopping was a deliberate scope-control decision based on the technical finding.

Privacy By Design

The prototype does not record, store, upload, transcribe, or analyse lesson audio/video/content. It is designed around active-speaker metadata and local prototype processing.

SpeakBalance is privacy-conscious, not privacy-free: participant metadata still needs careful handling, consent, and clear disclosure in any future product.

Tech Stack

  • React
  • Vite
  • JavaScript
  • Zoom Apps SDK

Running Locally

Install dependencies:

npm install

Run the local app:

npm run dev

Run the sample analytics demos:

node src/analytics/demoCalculateDurations.js
node src/analytics/demoNormaliseZoomSpeakerEvents.js
node src/analytics/demoSummariseSpeakerSegments.js
node src/analytics/demoApplySpeakerRoles.js
node src/reporting/demoGenerateTextReport.js

Build the app:

npm run build

Generated text reports are written to reports/ and ignored by Git.

Documentation

About

Technical feasibility prototype exploring privacy-conscious participation analytics using Zoom active-speaker metadata

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages