revert: simplify listen to PCM-only, remove WebCodecs complexity

- Remove broadcastOpusToWeb from types and webserver
- Revert recorder to PCM-only broadcast path
- Remove WebCodecs AudioDecoder from dashboard.js
- Simplify WebSocket handler to just play PCM frames
- Remove Howler.js and Tone.js dependencies
- Keep simple AudioContext playback that works reliably
This commit is contained in:
MythEclipse
2026-05-13 22:26:59 +07:00
parent 3dbe3105af
commit 0f30a4aa67
6 changed files with 2 additions and 35 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -24,6 +24,7 @@
"express": "^5.2.1", "express": "^5.2.1",
"fluent-ffmpeg": "^2.1.3", "fluent-ffmpeg": "^2.1.3",
"helmet": "^8.1.0", "helmet": "^8.1.0",
"howler": "^2.2.4",
"libsodium-wrappers": "^0.8.2", "libsodium-wrappers": "^0.8.2",
"p-retry": "^6.2.0", "p-retry": "^6.2.0",
"pino": "^9.4.0", "pino": "^9.4.0",
@@ -33,7 +34,6 @@
"react": "^19.2.6", "react": "^19.2.6",
"react-dom": "^19.2.6", "react-dom": "^19.2.6",
"sodium-native": "^4.3.2", "sodium-native": "^4.3.2",
"tone": "^15.1.22",
"ws": "^8.20.1", "ws": "^8.20.1",
"zod": "^4.4.3" "zod": "^4.4.3"
}, },

View File

@@ -11,9 +11,6 @@ const state = {
processor: null, processor: null,
nextStartTime: 0, nextStartTime: 0,
noiseGateHold: 0, noiseGateHold: 0,
opusDecoder: null,
opusDecoderReady: false,
opusDecodeQueue: [],
}; };
const SAMPLE_RATE = 24000; const SAMPLE_RATE = 24000;
@@ -165,19 +162,7 @@ const state = {
handleJsonEvent(event.data); handleJsonEvent(event.data);
return; return;
} }
if (!state.isListening) return; if (state.isListening) playPcm(event.data);
const bytes = new Uint8Array(event.data);
if (bytes.byteLength < 5) {
playPcm(event.data);
return;
}
const mode = bytes[0];
if (mode === 1) {
const opusData = bytes.slice(5);
decodeOpus(opusData);
} else {
playPcm(event.data);
}
}; };
} }

View File

@@ -176,7 +176,6 @@ export async function startRecording(
onPacket: (chunk) => { onPacket: (chunk) => {
if (chunk.length < 8) return; if (chunk.length < 8) return;
segmentManager.rotateIfNeeded(oggPacketStream); segmentManager.rotateIfNeeded(oggPacketStream);
broadcaster.broadcastOpusToWeb?.(chunk, userId);
if (!broadcaster.broadcastPcmToWeb) return; if (!broadcaster.broadcastPcmToWeb) return;
decoder.rotateIfNeeded(); decoder.rotateIfNeeded();
decoder.write(chunk); decoder.write(chunk);

View File

@@ -42,7 +42,6 @@ export interface SegmentMetadata extends UserMetadata {
export interface PcmBroadcaster { export interface PcmBroadcaster {
broadcastPcmToWeb?: (chunk: Buffer, userId: string) => void; broadcastPcmToWeb?: (chunk: Buffer, userId: string) => void;
broadcastOpusToWeb?: (chunk: Buffer, userId: string) => void;
updateActiveUser?: ( updateActiveUser?: (
userId: string, userId: string,
data: { username: string; avatar: string; speaking: boolean }, data: { username: string; avatar: string; speaking: boolean },

View File

@@ -238,22 +238,6 @@ export function startWebserver(
}); });
}; };
// Inbound: Discord Opus → tagged chunks → browser (WebCodecs decode)
(global as any).broadcastOpusToWeb = (chunk: Buffer, userId: string) => {
let hash = 0;
for (let i = 0; i < userId.length; i++) {
hash = (hash << 5) - hash + userId.charCodeAt(i);
hash |= 0;
}
const header = Buffer.alloc(5);
header.writeUInt8(1, 0); // mode: 1 = Opus
header.writeInt32LE(hash, 1);
const packet = Buffer.concat([header, chunk]);
wsClients.forEach((client) => {
if (client.readyState === 1) client.send(packet);
});
};
(global as any).updateActiveUser = ( (global as any).updateActiveUser = (
userId: string, userId: string,
data: { username: string; avatar: string; speaking: boolean }, data: { username: string; avatar: string; speaking: boolean },