fix: reconcile speakers automatically by default
The plain transcribe command still used chunk overlap speaker matching, so users had to discover a model flag or supply a known speaker count to get the improved voice comparison behavior. Enable OpenRouter voice comparison with automatic speaker counting for normal text and SRT invocations. Keep --speakers and --speaker-model as optional overrides, and let --no-diarization disable both provider labels and voice comparison. Make the basic command the documentation entry point and clarify the defaults in CLI help and repository guidance. Cover bare invocations across one and multiple uploads, default SRT, optional count constraints, opt-out ordering, and atomic output when the default comparison fails. Test Plan: - python3 -B -m unittest -v: all 85 tests passed. - bash -n transcribe: passed. - git diff --cached --check: passed. - Tests use real audio encoding with fake provider responses. Live voice accuracy remains unverified; no live API request was made for this change.
This commit is contained in:
1 parent
138c796399
commit
d7827d39f5
5 files changed
+107
-48
No files matched your search
@@ -35,6 +35,8 @@ def event(kind, **extra):
|
||||
event("start")
|
||||
if is_comparison:
|
||||
samples = json.loads((output.parent / "samples.json").read_text())
|
||||
manifest = json.loads((staging / "chunks.json").read_text())
|
||||
late_start = round(manifest[0]["end"]) if len(manifest) > 1 else 60
|
||||
content = request["messages"][-1]["content"]
|
||||
audio_parts = [part["input_audio"] for part in content if part["type"] == "input_audio"]
|
||||
assert len(content) == 2 * len(samples) == 2 * len(audio_parts)
|
||||
@@ -73,7 +75,7 @@ if is_comparison:
|
||||
if mode == "reconcile-bad-json":
|
||||
output.write_text("not json")
|
||||
sys.exit(0)
|
||||
assignments = [{"sample": sample["id"], "speaker": 0 if round(sample["start"]) in (1, 6, 60) else 1}
|
||||
assignments = [{"sample": sample["id"], "speaker": 0 if round(sample["start"]) in (1, 6, late_start) else 1}
|
||||
for sample in samples]
|
||||
if mode == "reconcile-missing":
|
||||
assignments.pop()
|
||||
@@ -182,12 +184,13 @@ else:
|
||||
if mode.startswith("reconcile"):
|
||||
# Two labels already describe voice A inside the first request; later
|
||||
# chunks reuse the same local numbers for different request identities.
|
||||
late_start = round(manifest[0]["end"]) if len(manifest) > 1 else 60
|
||||
words = [
|
||||
{"word": text, "start": start - chunk["start"], "end": start + 2 - chunk["start"],
|
||||
"speaker": speaker}
|
||||
for text, start, speaker in [
|
||||
("Alpha.", 1, 7), ("Again.", 6, 8), ("Beta.", 12, 9),
|
||||
("AlphaLate.", 60, 9), ("BetaLate.", 65, 7),
|
||||
("AlphaLate.", late_start, 9), ("BetaLate.", late_start + 5, 7),
|
||||
] if start >= chunk["start"] and start + 2 <= chunk["end"]
|
||||
]
|
||||
response = {"text": " ".join(w["word"] for w in words), "words": words}
|
||||
|
||||
Reference in new issue
Block a user