fixes stt paras
This commit is contained in:
parent
a098445521
commit
c59d119c77
2 changed files with 40 additions and 13 deletions
|
|
@ -25,12 +25,12 @@ class AudioCaptureProcessor extends AudioWorkletProcessor {
|
||||||
this.minRmsThreshold = 0.0003;
|
this.minRmsThreshold = 0.0003;
|
||||||
this.preRollSamples = Math.ceil(this.nativeRate * 1.0);
|
this.preRollSamples = Math.ceil(this.nativeRate * 1.0);
|
||||||
this.minFlushSamples = Math.ceil(this.nativeRate * 0.5);
|
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.ratio = this.nativeRate / this.targetRate;
|
||||||
this.chunkBuffer = [];
|
this.chunkBuffer = [];
|
||||||
this.samplesCollected = 0;
|
this.samplesCollected = 0;
|
||||||
this.hasVoicedContent = false;
|
this.hasVoicedContent = false;
|
||||||
this.consecutiveSilentCallbacks = 0;
|
this.consecutiveSilentSamples = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
process(inputs, outputs, parameters) {
|
process(inputs, outputs, parameters) {
|
||||||
|
|
@ -45,9 +45,9 @@ class AudioCaptureProcessor extends AudioWorkletProcessor {
|
||||||
|
|
||||||
if (cbRms >= this.minRmsThreshold) {
|
if (cbRms >= this.minRmsThreshold) {
|
||||||
this.hasVoicedContent = true;
|
this.hasVoicedContent = true;
|
||||||
this.consecutiveSilentCallbacks = 0;
|
this.consecutiveSilentSamples = 0;
|
||||||
} else {
|
} else {
|
||||||
this.consecutiveSilentCallbacks++;
|
this.consecutiveSilentSamples += input.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chunkBuffer.push(new Float32Array(input));
|
this.chunkBuffer.push(new Float32Array(input));
|
||||||
|
|
@ -56,7 +56,7 @@ class AudioCaptureProcessor extends AudioWorkletProcessor {
|
||||||
const shouldFlush = (
|
const shouldFlush = (
|
||||||
this.samplesCollected >= this.maxSamplesPerChunk
|
this.samplesCollected >= this.maxSamplesPerChunk
|
||||||
|| (this.hasVoicedContent
|
|| (this.hasVoicedContent
|
||||||
&& this.consecutiveSilentCallbacks >= this.silenceFlushCallbacks
|
&& this.consecutiveSilentSamples >= this.silenceFlushSamples
|
||||||
&& this.samplesCollected > this.minFlushSamples)
|
&& this.samplesCollected > this.minFlushSamples)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ class AudioCaptureProcessor extends AudioWorkletProcessor {
|
||||||
const rms = Math.sqrt(powerSum / Math.max(merged.length, 1));
|
const rms = Math.sqrt(powerSum / Math.max(merged.length, 1));
|
||||||
|
|
||||||
this.hasVoicedContent = false;
|
this.hasVoicedContent = false;
|
||||||
this.consecutiveSilentCallbacks = 0;
|
this.consecutiveSilentSamples = 0;
|
||||||
|
|
||||||
if (rms >= this.minRmsThreshold) {
|
if (rms >= this.minRmsThreshold) {
|
||||||
const outLen = Math.floor(merged.length / this.ratio);
|
const outLen = Math.floor(merged.length / this.ratio);
|
||||||
|
|
@ -264,14 +264,14 @@ export class AudioCaptureProcedure {
|
||||||
const maxSamplesPerChunk = nativeRate * 8;
|
const maxSamplesPerChunk = nativeRate * 8;
|
||||||
const preRollSamples = Math.ceil(nativeRate * 1.0);
|
const preRollSamples = Math.ceil(nativeRate * 1.0);
|
||||||
const minFlushSamples = Math.ceil(nativeRate * 0.5);
|
const minFlushSamples = Math.ceil(nativeRate * 0.5);
|
||||||
const silenceFlushCallbacks = 6;
|
const silenceFlushSamples = Math.ceil(nativeRate * 1.0);
|
||||||
const ratio = nativeRate / targetRate;
|
const ratio = nativeRate / targetRate;
|
||||||
|
|
||||||
scriptProcessor = ctx.createScriptProcessor(8192, 1, 1);
|
scriptProcessor = ctx.createScriptProcessor(8192, 1, 1);
|
||||||
let chunkBuffer: Float32Array[] = [];
|
let chunkBuffer: Float32Array[] = [];
|
||||||
let samplesCollected = 0;
|
let samplesCollected = 0;
|
||||||
let hasVoicedContent = false;
|
let hasVoicedContent = false;
|
||||||
let consecutiveSilentCallbacks = 0;
|
let consecutiveSilentSamples = 0;
|
||||||
|
|
||||||
scriptProcessor.onaudioprocess = (e: AudioProcessingEvent) => {
|
scriptProcessor.onaudioprocess = (e: AudioProcessingEvent) => {
|
||||||
const input = e.inputBuffer.getChannelData(0);
|
const input = e.inputBuffer.getChannelData(0);
|
||||||
|
|
@ -283,9 +283,9 @@ export class AudioCaptureProcedure {
|
||||||
|
|
||||||
if (cbRms >= minRmsThreshold) {
|
if (cbRms >= minRmsThreshold) {
|
||||||
hasVoicedContent = true;
|
hasVoicedContent = true;
|
||||||
consecutiveSilentCallbacks = 0;
|
consecutiveSilentSamples = 0;
|
||||||
} else {
|
} else {
|
||||||
consecutiveSilentCallbacks++;
|
consecutiveSilentSamples += input.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkBuffer.push(new Float32Array(input));
|
chunkBuffer.push(new Float32Array(input));
|
||||||
|
|
@ -294,7 +294,7 @@ export class AudioCaptureProcedure {
|
||||||
const shouldFlush = (
|
const shouldFlush = (
|
||||||
samplesCollected >= maxSamplesPerChunk
|
samplesCollected >= maxSamplesPerChunk
|
||||||
|| (hasVoicedContent
|
|| (hasVoicedContent
|
||||||
&& consecutiveSilentCallbacks >= silenceFlushCallbacks
|
&& consecutiveSilentSamples >= silenceFlushSamples
|
||||||
&& samplesCollected > minFlushSamples)
|
&& samplesCollected > minFlushSamples)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -313,7 +313,7 @@ export class AudioCaptureProcedure {
|
||||||
const rms = Math.sqrt(powerSum / Math.max(merged.length, 1));
|
const rms = Math.sqrt(powerSum / Math.max(merged.length, 1));
|
||||||
|
|
||||||
hasVoicedContent = false;
|
hasVoicedContent = false;
|
||||||
consecutiveSilentCallbacks = 0;
|
consecutiveSilentSamples = 0;
|
||||||
|
|
||||||
if (rms >= minRmsThreshold) {
|
if (rms >= minRmsThreshold) {
|
||||||
const outLen = Math.floor(merged.length / ratio);
|
const outLen = Math.floor(merged.length / ratio);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export class ChatProcedure {
|
||||||
private _consecutiveOpenFailures: number = 0;
|
private _consecutiveOpenFailures: number = 0;
|
||||||
private static readonly _MAX_OPEN_FAILURES = 5;
|
private static readonly _MAX_OPEN_FAILURES = 5;
|
||||||
private _isAuthMode: boolean;
|
private _isAuthMode: boolean;
|
||||||
|
private _recentlySentTexts: Set<string> = new Set();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
page: Page,
|
page: Page,
|
||||||
|
|
@ -465,10 +466,14 @@ export class ChatProcedure {
|
||||||
'meeting ended', 'meeting started', 'was invited', 'left the chat',
|
'meeting ended', 'meeting started', 'was invited', 'left the chat',
|
||||||
'joined the meeting', 'left the meeting', 'doesn\'t have a teams account',
|
'joined the meeting', 'left the meeting', 'doesn\'t have a teams account',
|
||||||
'verify their identity', 'new notification', 'last read',
|
'verify their identity', 'new notification', 'last read',
|
||||||
|
'sending...', 'sending…', 'gesendet', 'sent',
|
||||||
];
|
];
|
||||||
function _isNoise(text: string): boolean {
|
function _isNoise(text: string): boolean {
|
||||||
const lower = text.toLowerCase();
|
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 {
|
function _extractTeamsTimestamp(el: HTMLElement): string | undefined {
|
||||||
|
|
@ -970,6 +975,22 @@ export class ChatProcedure {
|
||||||
}): void {
|
}): void {
|
||||||
if (!this._isSubscribed || !msg.text) return;
|
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();
|
const nowMs = Date.now();
|
||||||
|
|
||||||
// Dedup
|
// Dedup
|
||||||
|
|
@ -1243,6 +1264,12 @@ export class ChatProcedure {
|
||||||
await this._page.keyboard.press('Enter');
|
await this._page.keyboard.press('Enter');
|
||||||
}
|
}
|
||||||
this._logger.info(`Chat message sent (stage=${stageUsed}, via=${sent ? 'sendBtn' : '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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue