discord.jsでYouTube動画を流す

5 min read読了の目安(約4700字

こんにちはー

この記事では、discord.jsでYouTube動画を流す(音声のみですが)方法をご紹介します。

Step1 パッケージのインストール

discord.jsとは別に、音源を取得するのにytdl-coreを、音声を再生するのに@discordjs/opusffmpeg-staticが必要なので、インストールしておきます。

npm i ytdl-core @discordjs/opus ffmpeg-static

Step2 ベースを作る

+ const ytdl = require('ytdl-core')
+ 
+ client.on('message', async message => {
+ });

Step3 コマンドの指定

この記事では!playにしました。

const ytdl = require('ytdl-core')

client.on('message', async message => {
+   if (message.content.startsWith('!play') && message.guild) {
+ 
+   }
});

Step4 動画URLを切り出す

.split()です。

const ytdl = require('ytdl-core')

client.on('message', async message => {
  if (message.content.startsWith('!play') && message.guild) {
+     const playurl = message.content.split(' ')[1];
  }
});

Step5 動画が見つからなかったとき

returnしてやりましょう。

const ytdl = require('ytdl-core')

client.on('message', async message => {
  if (message.content.startsWith('!play') && message.guild) {
    const playurl = message.content.split(' ')[1];
+     if (!ytdl.validateURL(playurl)) return message.reply('YouTubeにその動画が存在しません。URLをご確認ください。');
  }
});

Step6 そのメンバーが参加しているVCの取得

discord.jsドキュメント↓

https://discord.js.org/#/docs/main/stable/class/VoiceState?scrollTo=channel
const ytdl = require('ytdl-core')

client.on('message', async message => {
  if (message.content.startsWith('!play') && message.guild) {
    const playurl = message.content.split(' ')[1];
    if (!ytdl.validateURL(playurl)) return message.reply('YouTubeにその動画が存在しません。URLをご確認ください。');
+     const userch = message.member.voice.channel;
  }
});

Step7 ユーザーがVCに入っていなかったら

returnしてやりましょう。

const ytdl = require('ytdl-core')

client.on('message', async message => {
  if (message.content.startsWith('!play') && message.guild) {
    const playurl = message.content.split(' ')[1];
    if (!ytdl.validateURL(playurl)) return message.reply('YouTubeにその動画が存在しません。URLをご確認ください。');
    const userch = message.member.voice.channel;
+     if (!userch) return message.reply('コマンドを実行する前にボイスチャンネルに参加してください。');
  }
});

Step8 ボイスチャンネルに参加

discord.jsドキュメント↓

https://discord.js.org/#/docs/main/stable/class/VoiceChannel?scrollTo=join
const ytdl = require('ytdl-core')

client.on('message', async message => {
  if (message.content.startsWith('!play') && message.guild) {
    const playurl = message.content.split(' ')[1];
    if (!ytdl.validateURL(playurl)) return message.reply('YouTubeにその動画が存在しません。URLをご確認ください。');
    const userch = message.member.voice.channel;
    if (!userch) return message.reply('コマンドを実行する前にボイスチャンネルに参加してください。');
+     const connection = await channel.join();
  }
});

Step9 音源取得&再生

const ytdl = require('ytdl-core')

client.on('message', async message => {
  if (message.content.startsWith('!play') && message.guild) {
    const playurl = message.content.split(' ')[1];
    if (!ytdl.validateURL(playurl)) return message.reply('YouTubeにその動画が存在しません。URLをご確認ください。');
    const userch = message.member.voice.channel;
    if (!userch) return message.reply('コマンドを実行する前にボイスチャンネルに参加してください。');
    const connection = await channel.join();
+     const stream = ytdl(ytdl.getURLVideoID(playurl), { filter: 'audioonly' })
+     const dispatcher = connection.play(stream)
  }
});

Step10 再生終了時にボイスチャンネルから退出

const ytdl = require('ytdl-core')

client.on('message', async message => {
  if (message.content.startsWith('!play') && message.guild) {
    const playurl = message.content.split(' ')[1];
    if (!ytdl.validateURL(playurl)) return message.reply('YouTubeにその動画が存在しません。URLをご確認ください。');
    const userch = message.member.voice.channel;
    if (!userch) return message.reply('コマンドを実行する前にボイスチャンネルに参加してください。');
    const connection = await channel.join();
    const stream = ytdl(ytdl.getURLVideoID(playurl), { filter: 'audioonly' });
    const dispatcher = connection.play(stream);
+     dispatcher.once('finish', () => { channel.leave() });
  }
});

コード全文

const ytdl = require('ytdl-core')

client.on('message', async message => {
  if (message.content.startsWith('!play') && message.guild) {
    const playurl = message.content.split(' ')[1];
    if (!ytdl.validateURL(playurl)) return message.reply('YouTubeにその動画が存在しません。URLをご確認ください。');
    const userch = message.member.voice.channel;
    if (!userch) return message.reply('コマンドを実行する前にボイスチャンネルに参加してください。');
    const connection = await channel.join();
    const stream = ytdl(ytdl.getURLVideoID(playurl), { filter: 'audioonly' });
    const dispatcher = connection.play(stream);
    dispatcher.once('finish', () => { channel.leave() });
  }
});

おわり

お読みいただきありがとうございました!