feat: add progress handler with cancellation to PyannoteDiarizationPipeline.diarize()#194
Merged
ivan-digital merged 4 commits intosoniqo:mainfrom Apr 7, 2026
Conversation
Add an overloaded diarize() method that accepts an optional progressHandler callback reporting (progress: Float, stage: String). Progress is calculated from actual completed work units: - Total units = windowCount * 2 (segmentation + embedding extraction) - Each window completion increments the counter - No estimated weights or magic numbers The original diarize(audio:sampleRate:config:) method is unchanged and delegates to the new overload with nil handler.
- Unit test: verify progressHandler overload compiles, DiarizationConfig defaults, DiarizationResult construction - E2E test: verify progress values are monotonically non-decreasing and within [0, 1] range, original API still works without handler - Docs: add progress reporting example to speaker-diarization.md
Change progressHandler return type from Void to Bool. Returning false stops diarization at the next window boundary and returns an empty DiarizationResult. This enables callers to cancel long-running diarization without waiting for the full pipeline to complete.
…arize() Same pattern as PyannoteDiarizationPipeline: progressHandler returns Bool (true=continue, false=cancel). Progress is reported per streaming chunk. The original no-handler overload delegates with nil.
ivan-digital
approved these changes
Apr 7, 2026
Collaborator
ivan-digital
left a comment
There was a problem hiding this comment.
Clean implementation — backward compatible API, good progress granularity per window, cancellation at window boundaries is the right tradeoff. Tests cover the key cases well. Thanks for adding this, progress reporting for long diarization jobs has been a gap.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
diarize()method that accepts an optionalprogressHandler: ((Float, String) -> Bool)?callbackcompletedUnits / totalUnits), no estimated weightswindowCount × 2(segmentation pass + embedding extraction pass)Bool:trueto continue,falseto cancel immediatelyDiarizationResultat the next window boundary (~50–200ms latency)diarize(audio:sampleRate:config:)API is unchanged and delegates to the new overload withnilhandlerMotivation
For long audio files (e.g. 40+ minutes),
diarize()can take many minutes. Without progress reporting, callers have no way to show meaningful progress to users. Additionally, users need the ability to cancel a long-running diarization — becausediarize()is synchronous, Swift Task cancellation alone cannot interrupt it.Changes
Sources/SpeechVAD/DiarizationPipeline.swift— newdiarize(audio:sampleRate:config:progressHandler:)overload with Bool return type; cancellation checks in VAD pre-filter, segmentation loop, and embedding loopTests/SpeechVADTests/DiarizationPipelineTests.swift— unit tests (API signature, config defaults) + E2E tests (monotonic progress, cancellation returns empty result, nil handler)docs/inference/speaker-diarization.md— progress reporting & cancellation usage examplesTest plan
swift test --filter DiarizationPipelineTests --skip E2E)diarize(audio:sampleRate:config:)API works identically (backward compatible)