fixes stt paras

This commit is contained in:
ValueOn AG 2026-05-12 23:33:50 +02:00
parent a098445521
commit c59d119c77
2 changed files with 40 additions and 13 deletions

View file

@ -25,12 +25,12 @@ class AudioCaptureProcessor extends AudioWorkletProcessor {
this.minRmsThreshold = 0.0003;
this.preRollSamples = Math.ceil(this.nativeRate * 1.0);
this.minFlushSamples = Math.ceil(this.nativeRate * 0.5);
this.silenceFlushCallbacks = 6;
this.silenceFlushSamples = Math.ceil(this.nativeRate * 1.0);
this.ratio = this.nativeRate / this.targetRate;
this.chunkBuffer = [];
this.samplesCollected = 0;
this.hasVoicedContent = false;
this.consecutiveSilentCallbacks = 0;
this.consecutiveSilentSamples = 0;
}
process(inputs, outputs, parameters) {
@ -45,9 +45,9 @@ class AudioCaptureProcessor extends AudioWorkletProcessor {
if (cbRms >= this.minRmsThreshold) {
this.hasVoicedContent = true;
this.consecutiveSilentCallbacks = 0;
this.consecutiveSilentSamples = 0;
} else {
this.consecutiveSilentCallbacks++;
this.consecutiveSilentSamples += input.length;
}
this.chunkBuffer.push(new Float32Array(input));
@ -56,7 +56,7 @@ class AudioCaptureProcessor extends AudioWorkletProcessor {
const shouldFlush = (
this.samplesCollected >= this.maxSamplesPerChunk
|| (this.hasVoicedContent
&& this.consecutiveSilentCallbacks >= this.silenceFlushCallbacks
&& this.consecutiveSilentSamples >= this.silenceFlushSamples
&& this.samplesCollected > this.minFlushSamples)
);
@ -75,7 +75,7 @@ class AudioCaptureProcessor extends AudioWorkletProcessor {
const rms = Math.sqrt(powerSum / Math.max(merged.length, 1));
this.hasVoicedContent = false;
this.consecutiveSilentCallbacks = 0;
this.consecutiveSilentSamples = 0;
if (rms >= this.minRmsThreshold) {
const outLen = Math.floor(merged.length / this.ratio);
@ -264,14 +264,14 @@ export class AudioCaptureProcedure {
const maxSamplesPerChunk = nativeRate * 8;
const preRollSamples = Math.ceil(nativeRate * 1.0);
const minFlushSamples = Math.ceil(nativeRate * 0.5);
const silenceFlushCallbacks = 6;
const silenceFlushSamples = Math.ceil(nativeRate * 1.0);
const ratio = nativeRate / targetRate;
scriptProcessor = ctx.createScriptProcessor(8192, 1, 1);
let chunkBuffer: Float32Array[] = [];
let samplesCollected = 0;
let hasVoicedContent = false;
let consecutiveSilentCallbacks = 0;
let consecutiveSilentSamples = 0;
scriptProcessor.onaudioprocess = (e: AudioProcessingEvent) => {
const input = e.inputBuffer.getChannelData(0);
@ -283,9 +283,9 @@ export class AudioCaptureProcedure {
if (cbRms >= minRmsThreshold) {
hasVoicedContent = true;
consecutiveSilentCallbacks = 0;
consecutiveSilentSamples = 0;
} else {
consecutiveSilentCallbacks++;
consecutiveSilentSamples += input.length;
}
chunkBuffer.push(new Float32Array(input));
@ -294,7 +294,7 @@ export class AudioCaptureProcedure {
const shouldFlush = (
samplesCollected >= maxSamplesPerChunk
|| (hasVoicedContent
&& consecutiveSilentCallbacks >= silenceFlushCallbacks
&& consecutiveSilentSamples >= silenceFlushSamples
&& samplesCollected > minFlushSamples)
);
@ -313,7 +313,7 @@ export class AudioCaptureProcedure {
const rms = Math.sqrt(powerSum / Math.max(merged.length, 1));
hasVoicedContent = false;
consecutiveSilentCallbacks = 0;
consecutiveSilentSamples = 0;
if (rms >= minRmsThreshold) {
const outLen = Math.floor(merged.length / ratio);

View file

@ -27,6 +27,7 @@ export class ChatProcedure {
private _consecutiveOpenFailures: number = 0;
private static readonly _MAX_OPEN_FAILURES = 5;
private _isAuthMode: boolean;
private _recentlySentTexts: Set<string> = new Set();
constructor(
page: Page,
@ -465,10 +466,14 @@ export class ChatProcedure {
'meeting ended', 'meeting started', 'was invited', 'left the chat',
'joined the meeting', 'left the meeting', 'doesn\'t have a teams account',
'verify their identity', 'new notification', 'last read',
'sending...', 'sending…', 'gesendet', 'sent',
];
function _isNoise(text: string): boolean {
const lower = text.toLowerCase();
return noisePatterns.some(p => lower.includes(p));
if (noisePatterns.some(p => lower.includes(p))) return true;
if (/^\d{1,2}:\d{2}(:\d{2})?\s*$/.test(text.trim())) return true;
if (/^8:/.test(text.trim())) return true;
return false;
}
function _extractTeamsTimestamp(el: HTMLElement): string | undefined {
@ -970,6 +975,22 @@ export class ChatProcedure {
}): void {
if (!this._isSubscribed || !msg.text) return;
// Strip leading timestamp prefixes like "22:51 " or "22:51:03 "
let cleanText = msg.text.replace(/^\d{1,2}:\d{2}(:\d{2})?\s+/, '').trim();
// Strip "Sending..." prefix
cleanText = cleanText.replace(/^Sending\.\.\.\s*/i, '').trim();
if (!cleanText) return;
msg.text = cleanText;
// Filter bot's own sent messages (echoed back from the chat panel)
const normalisedIncoming = cleanText.replace(/\s+/g, ' ').trim().substring(0, 200);
if (this._recentlySentTexts.has(normalisedIncoming)) return;
// Sanitize raw Teams MRI IDs as speaker (e.g. "8:teamsvisitor:cbb83be0...")
if (/^8:(orgid|teamsvisitor|live|guest):/.test(msg.speaker)) {
msg.speaker = 'Unknown';
}
const nowMs = Date.now();
// Dedup
@ -1243,6 +1264,12 @@ export class ChatProcedure {
await this._page.keyboard.press('Enter');
}
this._logger.info(`Chat message sent (stage=${stageUsed}, via=${sent ? 'sendBtn' : 'enter'})`);
const normalised = text.replace(/\s+/g, ' ').trim().substring(0, 200);
this._recentlySentTexts.add(normalised);
if (this._recentlySentTexts.size > 50) {
const first = this._recentlySentTexts.values().next().value;
if (first) this._recentlySentTexts.delete(first);
}
return true;
}