diff --git a/.env.example b/.env.example deleted file mode 100644 index ef14edf..0000000 --- a/.env.example +++ /dev/null @@ -1,8 +0,0 @@ -# Discord Bot Token (dari Discord Developer Portal) -DISCORD_TOKEN="" - -# ID Channel Voice yang ingin di-join bot saat startup -VOICE_CHANNEL_ID= -GUILD_ID= -# Folder penyimpanan rekaman (opsional, default: ./recordings) -RECORDINGS_DIR=./recordings diff --git a/src/player.ts b/src/player.ts index e3c52c4..4c16269 100644 --- a/src/player.ts +++ b/src/player.ts @@ -8,6 +8,8 @@ import { } from "@discordjs/voice"; import { Readable } from "stream"; +import prism from "prism-media"; + export class DiscordPlayer { private player: AudioPlayer; private connection: VoiceConnection | null = null; @@ -30,12 +32,13 @@ export class DiscordPlayer { } public playStream(stream: Readable) { - // We assume the stream is Opus or PCM. - // For MediaRecorder (webm/opus), we might need to parse it. - // But let's start with a simple resource. - const resource = createAudioResource(stream, { - inputType: StreamType.WebmOpus, + // Use WebmDemuxer to extract Opus packets from browser stream + const demuxer = new prism.opus.WebmDemuxer(); + + const resource = createAudioResource(stream.pipe(demuxer), { + inputType: StreamType.Opus, }); + this.player.play(resource); } diff --git a/src/recorder.ts b/src/recorder.ts index 1b5f6e7..1fea65b 100644 --- a/src/recorder.ts +++ b/src/recorder.ts @@ -29,7 +29,7 @@ export async function startRecording(client: Client, channel: VoiceChannel): Pro guildId: channel.guild.id, adapterCreator: channel.guild.voiceAdapterCreator as any, selfDeaf: false, - selfMute: true, + selfMute: false, debug: true, }); diff --git a/src/webserver.ts b/src/webserver.ts index de016d6..c9fdf5b 100644 --- a/src/webserver.ts +++ b/src/webserver.ts @@ -11,12 +11,17 @@ export function startWebserver(port: number = 3000) { const wss = new WebSocketServer({ server }); const listeners = new Set(); + let headerChunks: Buffer[] = []; app.use(express.static(path.join(__dirname, "../public"))); // Endpoint for receiving (listening) audio from Discord app.get("/listen", (req, res) => { res.setHeader("Content-Type", "audio/ogg"); + + // Send cached headers so the browser can decode the stream + headerChunks.forEach(chunk => res.write(chunk)); + listeners.add(res); console.log(`[webserver] New listener connected. Total: ${listeners.size}`); @@ -28,6 +33,10 @@ export function startWebserver(port: number = 3000) { // Function to broadcast audio chunks to all listeners (global as any).broadcastToWeb = (chunk: Buffer) => { + // Store the first two chunks as headers (OpusHead and OpusTags) + if (headerChunks.length < 2) { + headerChunks.push(chunk); + } listeners.forEach(res => res.write(chunk)); };