Fix: Voice-Auto-Naming tot (TitaNet bricht bei langen Schnitten ab + vergiftete Promise-Kette)
identifySpeakers() embettete den laengsten Lauf ungekuerzt; TitaNet-ONNX bricht ab 180 s ab (broadcast 12288 by 17998) und riss den spk_embed-Helfer mit. Da spk.js die Aufrufe ueber eine Promise-Kette serialisiert, schlugen danach ALLE weiteren Sprecher mit 'spk beendet' fehl. - ID_CUT_SEC=25s in identifySpeakers - Kette in spk.js und tdChain in recorder.js failure-isoliert - pro Name gewinnt nur der beste Kosinus (Fabio war auf 2 Clustern)
This commit is contained in:
+18
-3
@@ -65,18 +65,33 @@ async function identifySpeakers(recData) {
|
||||
const len = cur.end - cur.start;
|
||||
if (!best[cur.speaker] || len > best[cur.speaker].len) best[cur.speaker] = { start: cur.start, end: cur.end, len };
|
||||
}
|
||||
const map = {};
|
||||
// Cut at most ID_CUT_SEC: onnxruntime ABORTS the embedding helper on very long
|
||||
// inputs (reproduced: 180 s -> "Non-zero status code returned while running
|
||||
// Where"; 20/60 s fine). On #74 the longest run of a moderator was minutes
|
||||
// long, which killed the helper on the first speaker and — through the then
|
||||
// poisoned promise chain in spk.js — every speaker after it ("spk beendet"),
|
||||
// i.e. voice auto-naming was dead for the whole recording.
|
||||
const ID_CUT_SEC = 25;
|
||||
const hits = [];
|
||||
for (const sp of speakers) {
|
||||
const r = best[sp]; if (!r) continue;
|
||||
const seg = `/tmp/idseg_${recData.id}_${sp}.wav`;
|
||||
const from = r.start / 1000;
|
||||
const to = Math.min(r.end / 1000, from + ID_CUT_SEC);
|
||||
try {
|
||||
await pexec('ffmpeg', ['-y', '-i', wavPath, '-ss', String(r.start / 1000), '-to', String(r.end / 1000), '-ar', '16000', '-ac', '1', seg]);
|
||||
await pexec('ffmpeg', ['-y', '-i', wavPath, '-ss', String(from), '-to', String(to), '-ar', '16000', '-ac', '1', seg]);
|
||||
const emb = await spk.embed(seg);
|
||||
const m = spk.bestMatch(emb, vps);
|
||||
if (m) map[sp] = m.name;
|
||||
if (m) hits.push({ speaker: sp, name: m.name, score: m.score });
|
||||
} catch (e) { console.error('identify', sp, e.message); }
|
||||
finally { try { fs.unlinkSync(seg); } catch {} }
|
||||
}
|
||||
// One enrolled person can only BE one cluster: keep the best-scoring match per
|
||||
// name (#74 handed "Fabio" to two clusters at once).
|
||||
const bestByName = {};
|
||||
for (const h of hits) if (!bestByName[h.name] || h.score > bestByName[h.name].score) bestByName[h.name] = h;
|
||||
const map = {};
|
||||
for (const h of Object.values(bestByName)) map[h.speaker] = h.name;
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user