TypeError: connection.play is not a function

TypeError: connection.play is not a function

我有这个音乐机器人项目,我是从 YouTube 上得到的,我在其中添加了一些我自己的东西。

问题是每次我发送 ?play (songname) 命令时,它都会发送一个错误 connection.play is not a function。我该怎么办?

我得到的错误:

connection.play(stream, {seek: 0, volume: 1})
           ^

TypeError: connection.play is not a function
    at Object.execute (C:\Users\Pauli.Salminen\Desktop\DiscordBotPRojects\reactionroles\commands\play.js:41:24)       
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

这是我的 play.js:

const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const { joinVoiceChannel } = require('@discordjs/voice');

module.exports = {
  name: 'play',
  description: 'joins aadn plays muusic',
  async execute(kaoru, message, args) {
    const voiceChannel = message.member.voice.channel;

    if (!voiceChannel)
      return message.channel.send('> **You need to join voicechannel first!**');
    const permissions = voiceChannel.permissionsFor(message.client.user);
    if (!permissions.has('CONNECT'))
      return message.channel.send('> **You dont have right permissions!**');
    if (!permissions.has('SPEAK'))
      return message.channel.send('> **You dont have right permissions!**');
    if (!args.length)
      return message.channel.send('> **You need to insert name of the song!**');

    const connection = joinVoiceChannel({
      channelId: message.member.voice.channel,
      guildId: message.guild.id,
      adapterCreator: message.guild.voiceAdapterCreator,
    });

    const videoFinder = async (query) => {
      const videoResult = await ytSearch(query);

      return videoResult.videos.length > 1 ? videoResult.videos[0] : null;
    };

    const video = await videoFinder(args.join(' '));

    if (video) {
      const stream = ytdl(video.url, { filter: 'audioonly' });
      connection.play(stream, { seek: 0, volume: 1 }).on('finish', () => {
        voiceChannel.leave();
      });

      await message.reply(`:thumbsup: Now playing ***${video.title}***`);
    } else {
      message.channel.send('No video results found');
    }
  }
};

discord.js v13 中有一些变化,您必须使用 @discordjs/voice 模块。

您的第一个错误是没有在 channelId: message.member.voice.channel 提供 ID。频道 ID 应为 message.member.voice.channel.id.

其次,play()connection 上不再可用。在 v13 中,您必须先创建一个音频播放器,使用 createAudioPlayer() method; then create an audio resource. Audio resources contain audio that can be played by an audio player to voice connections. To create one, you can use the createAudioResource() 方法并将您的 stream 作为参数传递。

创建资源后,您可以使用 player.play(). You also need to subscribe your connection to the player so the connection will broadcast whatever your player is playing. To do this, call the subscribe() 方法在语音 connection 上使用播放器作为参数在音频播放器上播放它们。

此外,没有 connection.on 侦听器。您可以使用 player.on though. To check if a song is finished, you can subscribe to the AudioPlayerStatus.Idle 事件。

最后,要离开频道,您应该使用 connection.disconnect() or connection.destroy().

而不是 voiceChannel.leave()

您可以在下面找到工作代码:

const {
  AudioPlayerStatus,
  createAudioPlayer,
  createAudioResource,
  joinVoiceChannel,
} = require('@discordjs/voice');
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');

module.exports = {
  name: 'play',
  description: 'joins aadn plays muusic',
  async execute(kaoru, message, args) {
    const voiceChannel = message.member.voice.channel;

    if (!voiceChannel)
      return message.channel.send('> **You need to join voicechannel first!**');
    const permissions = voiceChannel.permissionsFor(message.client.user);
    if (!permissions.has('CONNECT'))
      return message.channel.send('> **You dont have right permissions!**');
    if (!permissions.has('SPEAK'))
      return message.channel.send('> **You dont have right permissions!**');
    if (!args.length)
      return message.channel.send('> **You need to insert name of the song!**');

    const connection = joinVoiceChannel({
      channelId: message.member.voice.channel.id,
      guildId: message.guild.id,
      adapterCreator: message.guild.voiceAdapterCreator,
    });

    const videoFinder = async (query) => {
      const videoResult = await ytSearch(query);
      return videoResult.videos.length > 1 ? videoResult.videos[0] : null;
    };

    const video = await videoFinder(args.join(' '));

    if (video) {
      const stream = ytdl(video.url, { filter: 'audioonly' });
      const player = createAudioPlayer();
      const resource = createAudioResource(stream);

      await player.play(resource);
      connection.subscribe(player);

      player.on('error', (error) => console.error(error));
      player.on(AudioPlayerStatus.Idle, () => {
        console.log(`song's finished`);
        connection.disconnect();
      });

      await message.reply(`:thumbsup: Now playing ***${video.title}***`);
    } else {
      message.channel.send('No video results found');
    }
  },
};

PS:确保 GUILD_VOICE_STATES 意图已启用。否则,您的机器人将无法连接到语音通道。