質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

1回答

5812閲覧

【discord.js】ボイスチャンネルごとの音声を録音するbotの作成

takumi_pro

総合スコア2

Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

2グッド

3クリップ

投稿2021/10/27 10:41

編集2021/10/31 05:17

前提・実現したいこと

discord.js(v13)を使用して音声録音botを作成しています。
具体的には以下のようなものです。

  1. ボイスチャンネルにメンバーが参加(1人以上)
  2. botがボイスチャンネルの人数を検知し参加
  3. ボイスチャンネルにメンバーが参加(2人以上)
  4. botが自動で録音を開始
  5. ボイスチャンネルのメンバーが退出(1人)
  6. botが自動退出

以下のコード
https://github.com/discordjs/voice/tree/main/examples/recorder
を参考にして1~6のように動作するbotを作成できました。

発生している問題

4の録音の動作で問題が発生しています。

現状、録音された音声が特定のユーザのもので一つのファイルとして保存されてしまうのですが、
私としては、ユーザごとではなくボイスチャンネルごとの音声(複数人の発言)を一つのファイルとして保存したいと考えています。

音声の受け取りでuseridを指定しているためそのuseridに該当するユーザのみの音声を拾って保存しているのだと思います。

以下が、該当箇所のソースコードとなります。

createListeningStream関数の引数の説明
receiver : getVoiceConnection('ボイスチャンネルid').receiver
userId : ユーザID
recordable : new Set
user : ユーザ名

import { EndBehaviorType, VoiceConnection, VoiceReceiver } from '@discordjs/voice' import { User, Client, Intents } from 'discord.js' import { createWriteStream } from 'fs' import { opus } from 'prism-media' import { pipeline } from 'stream' function getDisplayName (userId: string, user?: User) { return user ? `${user.username}_${user.discriminator}` : userId } export async function createListeningStream (receiver: VoiceReceiver, userId: string, recordable: Set<string>, user?: User) { if (!recordable.has('recorded')) { // =======================ここから========================== receiver.subscribe(userId) const opusStream = receiver.subscribe(userId, { end: { behavior: EndBehaviorType.Manual } }) // =======================ここまで========================== const oggStream = new opus.OggLogicalBitstream({ opusHead: new opus.OpusHead({ channelCount: 2, sampleRate: 48000 }), pageSizeControl: { maxPackets: 10 } }) const filename = `./recordings/${Date.now()}-${getDisplayName(userId, user)}.ogg` const out = createWriteStream(filename) console.log(`???? Started recording ${filename}`) await pipeline(opusStream, oggStream, out, (err) => { if (err) { console.warn(`❌ Error recording file ${filename} - ${err.message}`) } else { console.log(`✅ Recorded ${filename}`) } }) } recordable?.add('recorded') }

discord.jsのdocumentやdiscordjs/voiceのdocument、Qiitaなどを確認して見たのですが、
録音は特定のユーザに対してのみのものがほとんどでした。

どのようにボイスチャンネル全体の録音をするのか実装のヒントを教えていただけないでしょうか。

ソースコード

https://github.com/takumi-pro/discord_recorder

補足情報(FW/ツールのバージョンなど)

@discordjs/voice : 0.6.0
discord.js : 13.1.0
typescript : 4.4.4

Waki285, r_key👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

※私はDiscord開発者ではないので、間違った事を書いている可能性があるという前提でお読み下さい

音声ストリーミングデータもテキストと同様に【ユーザーからの】メッセージの一種としてDidcord Voiceサーバでハンドリングされ、メッセージの中身は改造WebRTCによってVoIP(IP電話)同様にユーザーとサーバー間のIP通話になっていて、複数ユーザーの会話の場合はそれをDiscord Voiceサーバ側でミキシングしてサーバから各ユーザーにIP通話として配信している仕組みのようです。

https://blog.discord.com/how-discord-handles-two-and-half-million-concurrent-voice-users-using-webrtc-ce01c3187429

この音声データをプログラムで扱うためにDiscord側からSDKで提供されているNetworkingモジュールなどがありますが、現時点では音声関連のAPIはユーザーIDやユーザーのpeerID(VoIPのIPアドレス情報)と紐付ける形で提供されているようです。

https://discord.com/developers/docs/resources/voice
https://discord.com/developers/docs/game-sdk/networking#sendmessage

(Dicord Voiceサーバからすれば、ユーザーとは違うチャンネルというただの管理上の入れ物自身から発せられる音声メッセージはないという考えなのかな?)

このため、discord.js及びその拡張のdiscord.js/voiceもDiscord Voiceサーバー上では、あたかもチャンネルという部屋に居るようにミキシングされ配信された音声データは扱えないと思われます。
実際、discord.js/voiceのリファレンスには該当するメソッドがありませんね。

なので、チャンネル全体としての音をまとめようと思ったら、チャンネルにいる全てのユーザーID分の音声データを取得して、自前でミックスする必要があるってことですね(;´Д`)

(DiscordにAPIの機能追加要望出したら取得できるようになるかもしれませんが・・・)

投稿2021/11/02 21:44

AnMoreNight

総合スコア109

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takumi_pro

2021/11/05 10:18

丁寧な回答ありがとうございます。 なるほど、やはりメソッドはありませんよね、、 チャンネルに参加しているユーザのユーザIDは取得できるため、 複数の音声データ取得やミックスが可能か実装して見たいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問