2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【@discord.js/voice】VCにmp3音声を流す【TypeScript】

Last updated at Posted at 2023-02-13

イントロダクション

本記事では、DiscordのBotをVoice Channel(VC)に参加させ、VC内でローカルに用意したmp3ファイルを再生するプログラムについて記述しています。なお、Discord.jsのバージョンはv14です。

本記事の対象者

  • DiscordBotを動作させたことがある。
  • DiscordBotを利用してVC上に音声を再生したい。

筆者環境

環境 Version 備考
Node.js v16.18.0
TypeScript v4.9.5
discord.js v14.7.1 基本パッケージ
dotenv v16.0.3 Botトークン保存用
@discordjs/voice v0.14.0 VCを扱うパッケージ
ffmpeg-static v5.1.0 @discordjs/voiceの依存
tweetnacl v1.0.3 @discordjs/voiceの依存
Visual Studio Code v1.75.1

本記事のBotは以下のようなファイル構造を保持しているとします。

.
├─ build
|  ├─ sounds
| |  └─ melody.mp3
|  └─ main.js
|
├─ node_modules
|  └─ etc.
├─ src
|  └─ main.ts
├─ .env
└─ etc.

モジュールのインストール

以下の記事でdiscord.js+TypeScriptの導入方法について丁寧に説明して下さっています。

なお本記事のファイル/フォルダの構成や、コマンド等については上述の記事を参考にしています。

初めに基本となるdiscord.jsと、dotenvを導入します。

cmd
npm install discord.js dotenv

次にVCで音声を再生するために必要なパッケージを導入します。

cmd
npm install @discordjs/voice ffmpeg-static tweetnacl

プログラムの説明

VCのあるサーバーにおいて、任意のテキストチャンネルで

discord
!play

と送信するとBotがVCに参加し、mp3音源を再生します。再生が終了するとBotはVCから退出します。
mp3ファイルは./build/soundsフォルダに格納します。

!playを送信する前にVCには最低一人が参加している状態としてください。
本プログラムでは誰もいないVCにBotは参加できません。

プログラム本体

main.ts
import fs from 'node:fs'
import path from 'node:path'
import { Client, Message, Events, GatewayIntentBits } from 'discord.js'
import { entersState, AudioPlayerStatus, createAudioPlayer, createAudioResource, joinVoiceChannel, StreamType, NoSubscriberBehavior } from '@discordjs/voice'
import dotenv from 'dotenv'

dotenv.config()

const soundPath: string = path.join(__dirname, 'sounds');
const soundFiles: string[] = fs.readdirSync(soundPath).filter(file => file.endsWith('.mp3'));
let soundFilePath: { [key: string]: string } = {};

for (const file of soundFiles) {
    const extractExtension: string = file.split('.')[0];
    const filePath: string = path.join(soundPath, file);
    soundFilePath[extractExtension] = filePath;
}

const client = new Client({
    intents: [  GatewayIntentBits.Guilds,
                GatewayIntentBits.GuildMessages,
                GatewayIntentBits.MessageContent,
                GatewayIntentBits.GuildVoiceStates
            ]
});

client.once(Events.ClientReady, (c: Client) => {
    console.log(`Ready! Logged in as ${c.user?.tag}`);
});

client.on(Events.MessageCreate, async (message: Message) => {
    if (message.author.bot) {
        return;
    }

    if (!message.content.startsWith('!play')) {
        return;
    }

    const channel = message.member?.voice.channel;
    if (!channel) {
        await message.reply('[ERR] Someone needs to be on the voice channel.');
        return;
    }

     const connection = joinVoiceChannel({
      adapterCreator: channel.guild.voiceAdapterCreator,
      channelId: channel.id,
      guildId: channel.guild.id,
      selfDeaf: true,
      selfMute: false,
     });
    
    const player = createAudioPlayer({
        behaviors: {
            noSubscriber: NoSubscriberBehavior.Pause,
        },
    });

    connection.subscribe(player);

    const resource = createAudioResource(soundFilePath['melody'],
        {
        inputType: StreamType.Arbitrary,
        }
    );

    player.play(resource);

    await entersState(player,AudioPlayerStatus.Playing, 10 * 1000);
    await entersState(player, AudioPlayerStatus.Idle, 24 * 60 * 60 * 1000);
    
    connection.destroy();
});

client.login(process.env.TOKEN);
.env
TOKEN='YOUR_BOT_TOKEN'

Botの実行

先述の参考記事の通りであれば、次に示すnpm runコマンドを利用してコンパイルします。

ファイル名やフォルダの名前は適宜読み替えてください。

cmd
npm run compile

または、

cmd
tsc -p .

コンパイルが完了したら以下のコマンドでBotを実行します。

cmd
npm run start

または

cmd
node ./build/main.js

Botを起動できたら、VCに参加して、任意のテキストチャンネルで!playと入力し送信してください。正しく動作していれば、Botがあなたが参加しているVCに参加し、指定した音声を再生します。再生が終わると退出します。

音声が再生されている途中に!playを送信すると再生状態が上書きされます。すなわち再生される音声は同じものがまた最初から再生される動作となります。

Botが正しく動作しない場合、BotがVCから退出しないことがあります。その場合はdiscordから手動にて退出を行ってください。PC版であれば、VCチャンネルのBotを右クリックすると退出させる操作が可能です。ただしサーバーの管理者権限が必要なことに注意してください。

BotがVCに参加して、一瞬で退出する場合は、再生したいmp3ファイルのパス指定がうまくいっていない可能性があります。console.log()等を利用してcreateAudioResource()の第一引数に正しくパスが指定されているか確認してみてください。

まとめ

本記事ではDiscordBotでmp3ファイルを再生するプログラムを紹介しました。今回はローカルに用意したmp3ファイルを使用しましたが、インターネット上のファイルや、Youtubeといった動画共有サービスの動画音声を再生することも可能です。こちらについては読者に検索いただきたい。

参考になるリンク等

@discordjs/voice Documentation

Youtubeの音源を再生する方法

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?