実現したいこと
とりあえずDiscordのボイスチャットの音声を録音してWavにして文字にしたい
前提
とりあえずDiscordのボイスチャットの音声を録音してWavにしたい
問題
エラーは特になかった
wavファイルは生成されるがノイズがありそれも0~1秒程度のものが生成される
該当のソースコード
js
1const { Client, GatewayIntentBits, Partials, } = require('discord.js'); 2const { joinVoiceChannel, EndBehaviorType} = require('@discordjs/voice'); 3const { OpusEncoder } = require('@discordjs/opus') 4const fs = require('node:fs'); 5let { encode } = require('node-wav'); 6const client = new Client({ 7 intents: Object.values(GatewayIntentBits), 8 partials: [Partials.Message, Partials.Channel, Partials.Reaction], rest: 60000 9}); 10 11client.once('ready', () => { 12 console.log(`Logged in as ${client.user.tag}`); 13}); 14 15client.on('messageCreate', async (message) => { 16 if (message.content === 'BOT起動') { 17 // メッセージを送信したユーザーが接続しているボイスチャンネルに参加する 18 const voiceChannel = message.member.voice.channel; 19 if (!voiceChannel) return message.reply('ボイスチャンネルに接続してください'); 20 const connection = joinVoiceChannel({ 21 channelId: voiceChannel.id, 22 guildId: voiceChannel.guild.id, 23 adapterCreator: voiceChannel.guild.voiceAdapterCreator, 24 selfDeaf: false 25 }); 26 console.log(`Connected to ${voiceChannel.name}`); 27 // 音声入力のストリームを作成する 28 const { createAudioPlayer } = require('@discordjs/voice'); 29 30 const player = createAudioPlayer(); 31 // プレイヤーを音声接続オブジェクトに接続する 32 connection.subscribe(player); 33 34 // `connection` は接続された `VoiceConnection` オブジェクトです。 35 connection.receiver.speaking.on('start', (userId) => { 36 37 const audio = connection.receiver.subscribe(userId, { 38 end: { 39 behavior: EndBehaviorType.AfterSilence, 40 duration: 1000, 41 }, 42 }); 43 44 const leftOpusStream = []; 45 const rightOpusStream = []; 46 47 let isLeftChannel = true; // 初めは左チャンネル 48 49 audio.on('data', (chunk) => { 50 const decodedChunk = decodeOpus(chunk); 51 52 if (isLeftChannel) { 53 leftOpusStream.push(decodedChunk); 54 } else { 55 rightOpusStream.push(decodedChunk); 56 } 57 58 isLeftChannel = !isLeftChannel; // チャンネルを切り替える 59 }); 60 61 audio.on('end', async () => { 62 console.log(`Stream from user ${userId} has ended`); 63 const leftPcmDataArray = await Promise.all(leftOpusStream); 64 const leftConcatenatedBuffer = Buffer.concat(leftPcmDataArray); 65 const rightPcmDataArray = await Promise.all(rightOpusStream); 66 const rightConcatenatedBuffer = Buffer.concat(rightPcmDataArray); 67 //const concatenatedBuffer = Buffer.concat(pcmDataArray); 68 const wavDataPromise = encodeWav(leftConcatenatedBuffer, rightConcatenatedBuffer); 69 audio.destroy(); 70 wavDataPromise.then((wavData) => { 71 console.log(wavData) 72 // whisper(player, wavData); 73 }).catch((error) => { 74 console.error(error); 75 }).finally(() => { 76 audio.destroy(); 77 }); 78 }); 79 }); 80 81 async function decodeOpus(opusStream) { 82 return new Promise((resolve, reject) => { 83 const opusDecoder = new OpusEncoder(48000, 2); 84 const pcmData = opusDecoder.decode(opusStream); 85 resolve(pcmData); 86 }); 87 } 88 89 async function encodeWav(leftPcmDataArray, rightPcmDataArray) { 90 const arr1 = new Float32Array(leftPcmDataArray.buffer); 91 const arr2 = new Float32Array(rightPcmDataArray.buffer); 92 93 const wavData = encode([arr1, arr2], { 94 sampleRate: 48000 95 }); 96 const now = new Date(); 97 const fileName = `${now.getHours()}h${now.getMinutes()}m${now.getSeconds()}s.wav`; 98 const filePath = `/tmp/${fileName}`; 99 100 fs.writeFileSync(filePath, Buffer.from(wavData), { encoding: 'binary' }); 101 102 return filePath; 103 } 104 105 } 106 107 } 108 109}); 110 111client.login('token'); 112
試したこと
https://zenn.dev/ss_2013/articles/ab3dfd73513afb
この記事を参考にやったがだめだった
補足情報(FW/ツールのバージョンなど)
json
1{ 2 "dependencies": { 3 "@discordjs/opus": "^0.9.0", 4 "@discordjs/voice": "^0.16.0", 5 "@google-cloud/speech": "^5.6.0", 6 "@kirdock/discordjs-voice-recorder": "^1.0.4", 7 "dartjs": "^1.2.0", 8 "discord.js": "^14.11.0", 9 "dotenv": "^16.3.1", 10 "ffmpeg-static": "^5.1.0", 11 "libsodium-wrappers": "^0.7.11", 12 "node-opus": "^0.3.3", 13 "node-wav": "^0.0.2", 14 "prism-media": "^1.3.5", 15 "wav-encoder": "^1.3.0" 16 } 17}
あなたの回答
tips
プレビュー