File size: 2,896 Bytes
67bf4ee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { Message, EmbedBuilder } from 'discord.js';
import {
  joinVoiceChannel,
  createAudioResource,
  AudioPlayerStatus,
} from '@discordjs/voice';
import { get } from 'https';
import { MusicQueue } from '../utils/MusicQueue';
import { queues } from '../index';
import type { Command } from '../types';

async function playSong(queue: MusicQueue, guildId: string) {
  if (queue.songs.length === 0) {
    queue.playing = false;
    return;
  }

  queue.playing = true;
  queue.currentSong = queue.songs.shift()!;

  try {
    const stream = await new Promise<Readable>((resolve, reject) => {
      get(queue.currentSong.url, (res) => {
        if (res.statusCode !== 200) return reject(new Error('Failed to fetch MP3'));
        resolve(res);
      }).on('error', reject);
    });

    const resource = createAudioResource(stream);
    queue.player.play(resource);

    queue.player.once(AudioPlayerStatus.Idle, () => playSong(queue, guildId));
  } catch (error) {
    console.error('Error playing mp3:', error);
    queue.playing = false;
  }
}

export default <Command>{
  data: {
    name: 'play',
    description: 'Phát nhạc từ link .mp3',
    toJSON() {
      return { name: 'play', description: 'Phát nhạc từ link .mp3' };
    },
  },
  ownersOnly: false,
  async execute(message: Message, args: string[]) {
    const guildId = message.guild?.id;
    if (!guildId) return message.reply('❌ Lệnh này chỉ hoạt động trong server.');

    const voiceChannel = message.member?.voice.channel;
    if (!voiceChannel) {
      return message.reply('❌ Bạn cần tham gia voice channel để phát nhạc.');
    }

    const query = args.join(' ').trim();
    if (!query || !query.endsWith('.mp3')) {
      return message.reply('❌ Vui lòng cung cấp một link `.mp3` hợp lệ.');
    }

    if (!queues.has(guildId)) {
      queues.set(guildId, new MusicQueue());
    }
    const queue = queues.get(guildId)!;

    const song = {
      title: query.split('/').pop() || 'MP3 File',
      url: query,
      duration: 0,
      thumbnail: '',
      requestedBy: message.author.id,
    };

    queue.songs.push(song);

    if (!queue.playing) {
      if (!queue.connection) {
        queue.connection = joinVoiceChannel({
          channelId: voiceChannel.id,
          guildId: guildId,
          adapterCreator: message.guild!.voiceAdapterCreator,
        });
        queue.connection.subscribe(queue.player);
      }
      playSong(queue, guildId);
    }

    const embed = new EmbedBuilder()
      .setColor('#00ff00')
      .setTitle('🎵 Đã thêm vào hàng đợi')
      .setDescription(`**${song.title}**`)
      .addFields(
        { name: 'Vị trí', value: queue.songs.length.toString(), inline: true },
        { name: 'Người yêu cầu', value: `<@${song.requestedBy}>`, inline: true }
      );

    await message.reply({ embeds: [embed] });
  },
};