gyanmeet_flutter_sdk 1.6.0 copy "gyanmeet_flutter_sdk: ^1.6.0" to clipboard
gyanmeet_flutter_sdk: ^1.6.0 copied to clipboard

PlatformAndroid
unlisted

Gyanmeet meeting SDK for Flutter — a self-contained video meeting widget with host controls, chat, polls, batch exams, certificate verification, and optional on-device AI proctoring.

1.6.0 #

Fixed #

  • The app no longer terminates when a meeting ends. FaceDetectionMonitor disposed the ML Kit detector, the TFLite interpreter and the camera track synchronously, while a detection tick could still be parked on an await. The tick resumed onto freed native memory and took the process down with no Dart error — reliably on host-ended meetings, and during an exam whenever the room dropped. Teardown now waits for the in-flight tick, every await checks a disposed flag, and a tick is skipped once the room is disconnected, since LiveKit frees the native camera track at that point and captureFrame() on it crashes rather than throwing.

  • Identity comparisons no longer flag the right person as a mismatch. ML Kit extrapolates a bounding box past the image edge for a face that is only partly in shot; the crop clamped it and the model embedded a partial face, scoring it against a full-face baseline. Frames where less than 90% of the face is in shot are now skipped — such a frame is no evidence either way, so it can defer a check but never falsely clear one.

  • Face presence no longer flickers. A single dropped detection is treated as noise and only a second consecutive miss commits an absence, backdated to the first miss so debouncing never buys extra time before the grace period expires. Only detector output is debounced: a camera that is off, a missing track or a backgrounded app still report absence immediately.

  • Concurrent model loads no longer race. The identity gate and the monitor could each build an interpreter, and the loser's close() freed one the winner might already be running inference on. Loads are now deduplicated.

  • A truncated or half-flushed proctoring frame degrades to "no face this tick" instead of throwing, and the interpreter is re-checked after every await that can outlive it.

Changed #

  • Proctoring costs less per frame. The monitor and FaceComparator shared a single ML Kit detector instead of holding one each; landmarks, classification and tracking are switched off (nothing read them, and tracking was being fed unrelated stills rather than a video stream), and the budget goes to the accurate model instead, which drops fewer frames. Inference buffers are allocated once and rewritten in place rather than rebuilt per frame. Native resources are released when monitoring ends instead of living for the rest of the host app's life.

Added #

  • GyanmeetConfig.faceComparisonInterval throttles the on-device identity comparison. Face presence stays on its 2s tick; this bounds only the decode and embedding work. Null (the default) keeps comparing on every tick.

Also in this release #

  • AI violation warnings are now shown by the SDK when onAiViolationWarning / onAiViolationRemoved are left unset: a warning pill in the top-center stack under the connection banner, and a blocking removal notice. Previously the verdicts went only to the callbacks, so a consumer that had not implemented them showed the participant nothing.

  • Hosts and admins are never AI-monitored. The exemption used to cover hosts and co-hosts for enforcement only — monitoring still ran, so a host with the camera off collected violations. Monitoring is now skipped entirely for hosts, co-hosts and platform admin / super_admin users. The platform role arrives on the join response as user_role; the server enforces the same exemption.

  • The identity gate no longer needs a reference photo. With enableIdentityVerificationGate: true and no identityReferenceImage, the gate runs in enroll mode: the selfie only has to hold a usable face, and becomes the base for in-meeting monitoring (persisted as ENROLLED). Previously the gate was skipped silently whenever no reference was passed.

1.5.0 #

  • Batch exams as a phase of the class meeting. When the backend runs them and the hub is configured for one, the host gets a Start/End exam control and every attendee gets the paper as an overlay. The overlay is layered on top of the meeting rather than replacing it, so the camera, the identity check and proctoring all keep running while the exam is sat.
    • Questions, time limit, pass mark and attempts come from the hub's configuration. A host cannot change the rules of an exam while the class is sitting it.
    • The host may confine the exam to one or more sections of the question bank. Selecting none draws from the entire bank, which is how every exam behaved before sections existed.
    • The countdown runs against the server's expiry, not a client-side duration, and the paper auto-submits when it runs out.
    • New GyanmeetConfig.enableExam (default true) opts a consumer out of the feature entirely.
  • Public certificate verification. GyanmeetCertificateVerification takes a certificate ID — typed, or pasted from the URL a certificate's QR code encodes — and reports VALID, REVOKED, INVALID or NOT_FOUND. It needs no session, since whoever is checking a certificate has no account. Every fact shown is fetched from the backend by ID: nothing is read out of the QR payload or the PDF, and no signing key is ever involved on the client.
  • AI violation timings now come from the server. The face-absence grace period and the interval between repeat warnings are taken from GET /meetings/ai-violation-policy. The constants in the SDK are named kFallbackAi… and are used only until that call answers.
  • Fixed: warnings could never fire. Three causes, all addressed:
    • Turning the camera off stopped detection entirely, which made switching the camera off a way to escape monitoring. An absent camera is now clocked as the same absence as an absent face.
    • The absence clock was rebased by the metrics flush, which pushed the violation threshold permanently out of reach whenever the flush interval was shorter than the grace period. Absence is now timed on its own clock.
    • A continuous absence raised at most one violation. It now repeats at the server's configured interval, so warnings actually accumulate.
  • Fixed: hosts were subject to the violation policy. A host running the class could accumulate warnings and be removed from their own meeting. Hosts are now exempt from enforcement; proctoring callbacks still fire for them.
  • Backend support for both exams and certificates is detected, never assumed. A deployment without those routes behaves exactly as in 1.4.x.

1.4.0 #

  • Server-enforced AI violation policy. When the backend implements it, the SDK reports face-absence and identity-mismatch violations to POST /meetings/ai-violation; the server owns a consolidated warning counter (both kinds share it, and it survives an app restart) and removes the participant once the warnings are exhausted. Two new callbacks report the outcome:
    • onAiViolationWarning(AiViolationVerdict) — counted, warnings remain. verdict.isFinalWarning is true on the last one before removal.
    • onAiViolationRemoved(AiViolationVerdict) — terminal. The participant is removed and cannot rejoin this meeting, or any other meeting in the same batch, without re-registering. Show a blocking notice and leave. Both carry the server's own message, which contains the configured thresholds — prefer it over composing copy locally.
  • Backend support is detected, never assumed. The SDK probes GET /meetings/ai-violation-policy once per meeting; a deployment that does not implement it is left completely untouched — no reporting, no removal, and existing proctoring callbacks behave exactly as in 1.3.x. The same applies if the endpoint disappears mid-meeting.
  • Gaze and reference-unavailable violations are still surfaced to the consumer app but are never reported to the policy, because the server does not count them. Looking away cannot cost a warning.
  • Reports are suppressed while a host break is active, so nobody accumulates violations for stepping away during a break.
  • Two new GyanmeetJoinDenialReason values for backends that gate joins on proctoring and attendance: aiViolationRemoved and insufficientAttendance. Note: consumers with an exhaustive switch over the enum will need to handle the new values.

1.3.7 #

  • Config parity with the iOS SDK:
    • allowPoll — let attendees create polls (hosts always can when polls are shown). Poll button visibility is now gated purely by showPolls; poll creation is gated separately by allowPoll in the polls panel.
    • showHeader — show/hide the top meeting header (title + count + timer).
    • waitingOverlayText — optional message shown under the join spinner.
  • Camera switch control: a front/back toggle appears next to the camera button while the camera is on. Capture now explicitly defaults to the front camera.
  • Brand watermark: a subtle, non-interactive "Gyanmeet" mark pinned in the video area (and fullscreen), tinted by the configured primaryColor.
  • Chat persistence: sent chat messages are now side-written to /meetings/{id}/chat (fire-and-forget) so history survives; realtime delivery still flows over the LiveKit text stream.

1.3.6 #

  • Host "Enable Audio" (granted after a participant raises their hand) now auto-unmutes that participant's microphone. LiveKit does not allow the server to force-publish audio, so the granted participant's own client unmutes on the audioGrantedByHost false→true edge. Edge-triggered: a user who mutes again afterward is not overridden until the host revokes and re-grants.
  • Hosts-only video mode now shows a "Waiting for the host to join…" placeholder when no host is present, instead of an indefinite loading spinner that was indistinguishable from a stalled connection.

1.3.5 #

  • Typed join errors: a refused join now surfaces as GyanmeetJoinError (with a GyanmeetJoinDenialReason) instead of a raw DioException, carrying the backend reason code + human message so the consumer app can render its own UI. Covers missed Day 1, rejoin-limit exceeded, left-too-early, join window not open / closed, and meeting ended.

1.3.4 #

  • In-meeting identity monitoring now confirms a suspected mismatch against the external face-compare service before flagging. An on-device mismatch must persist for 3 consecutive checks; on the 3rd, the live frame is compared remotely (POST /compare) against the enrollment image. A violation fires only if the service also reports a mismatch — a remote match is treated as a false alarm and resets. Active when GyanmeetConfig.faceCompareUrl is set; otherwise the 3-strike on-device verdict stands. Far fewer false positives, with only a handful of remote calls per session (on escalation, not a timer).

1.3.3 #

  • Optional remote identity gate: set GyanmeetConfig.faceCompareUrl (+ faceCompareApiKey) to verify the pre-meeting selfie against the reference via a standalone face-compare service (POST /compare, face-api.js) instead of on-device. More accurate; no model needed for the gate. Falls back to on-device when unset. In-meeting monitoring always stays on-device.
  • Enrollment refresh: the verified gate selfie becomes the on-device enrollment base for in-meeting identity monitoring (fresh, same-domain capture → far more reliable than matching against a stale reference photo).
  • Exposes FaceCompareClient / FaceCompareResult for standalone use.
  • Participant video now uses contain fit instead of cover, so the full camera frame is shown without zoom/crop (letterboxed when aspect ratios differ). Applies to grid tiles and tile fullscreen.
  • Break overlay now syncs on join: BreakController publishes a state-request on connect and replies to others' requests, matching the web client. An SDK participant joining after a break has already started now sees the overlay (previously only live break broadcasts were picked up).

1.3.1 #

  • VideoMode.hostsOnly now excludes non-host tiles from the grid entirely instead of rendering them as avatars. Attendees (including the local user's own tile) no longer appear; only host/co-host tiles show — their video when the camera is on, their avatar when off. Active-speaker pinning is likewise limited to hosts.
  • GyanmeetConfig.darkMode (default off) renders the SDK chrome in dark mode: chat, participants, polls, create-poll, meeting header, bottom controls, and loading/error surfaces now resolve panel/text colors from a theme-aware palette (GyanPalette) instead of hardcoded light colors. Video surfaces and camera screens stay dark in both modes by design.
  • Identity gate no longer silently admits everyone when the reference image can't be used (model disabled/failed, or no face found in the reference). It now fires onProctoringViolation with the new ProctoringViolationType.referenceUnavailable (reason: face_model_disabled, face_model_load_failed, reference_no_face, or reference_embed_error) and shows an on-screen "verification unavailable" notice. The user is still let through (non-bricking), but the consumer is now informed and can flag/review.

1.2.1 #

  • Lower default faceMatchThreshold to 0.45 (was 0.5). Verified separation: impostor pairs ~0.35, genuine pairs ~0.60, so 0.45 keeps impostors out while giving genuine matches more headroom against lighting/pose variation — reduces false rejects, especially on the single-shot identity gate.

1.2.0 #

  • Manual identity enrollment: pass GyanmeetMeeting.identityReferenceImage (encoded bytes) to use a known reference face as the baseline instead of auto-enrolling the first detected face.
  • Optional pre-meeting identity gate: GyanmeetConfig.enableIdentityVerificationGate (default off) requires a selfie matched against the reference image before the meeting is shown; a mismatch fires onIdentityMismatch.
  • Identity matching hardened: head-pose quality gate, median-of-5 smoothing, and a startup grace period to eliminate false mismatches from transient bad frames.

1.1.0 #

  • Host break: GyanmeetConfig.enableBreak (default off) adds a host break control + fullscreen countdown overlay, synced peer-to-peer over the LiveKit data channel. AI monitoring pauses during a break.
  • AI monitoring now honors the meeting camera setting (participant_video): when AI is on but the meeting camera is off, a hidden unpublished camera feeds face monitoring; when both are off, monitoring stays fully inactive.

1.0.0 #

  • First stable release. Meeting mode complete: join flow, video grid, host controls, chat, polls, adaptive bandwidth, and AI monitoring.
  • On-device identity verification (face match) during AI monitoring. The first detected face is enrolled as a baseline; later frames are compared and onIdentityMismatch(similarity) fires after sustained mismatch.
  • Bundles a MobileFaceNet model — works out of the box, no consumer setup. Override via GyanmeetConfig.faceModelAssetPath / faceMatchThreshold, or set the path to null to disable.
  • Unified onProctoringViolation(ProctoringViolation) handler covering gaze, identity, and face-absence in one place; type-specific callbacks still fire.
  • Exposes FaceComparator for standalone two-photo comparison.

0.0.2 #

  • Documentation cleanup: README and package description now describe the SDK on its own terms (no internal implementation references).

0.0.1 #

  • Initial release of the Gyanmeet meeting SDK for Flutter.
  • GyanmeetMeeting widget: join flow, optional PreJoin, full room lifecycle.
  • Video grid + pagination, active-speaker pin, fullscreen, mic/cam/screen toggles.
  • Host controls, chat (open + host-moderated), participants panel, polls.
  • Adaptive bandwidth: selective subscription, screen-share auto-subscribe, publish control.
1
likes
130
points
178
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Gyanmeet meeting SDK for Flutter — a self-contained video meeting widget with host controls, chat, polls, batch exams, certificate verification, and optional on-device AI proctoring.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

dio, flutter, google_mlkit_face_detection, image, livekit_client, livekit_components, path_provider, provider, tflite_flutter

More

Packages that depend on gyanmeet_flutter_sdk