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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
import {TextChannel, Message} from 'discord.js';
import {URL} from 'url';
import {TYPES} from '../types';
import {inject, injectable} from 'inversify';
import {QueuedSong, STATUS} from '../services/player';
import PlayerManager from '../managers/player';
import {getMostPopularVoiceChannel} from '../utils/channels';
import LoadingMessage from '../utils/loading-message';
import errorMsg from '../utils/error-msg';
import Command from '.';
import GetSongs from '../services/get-songs';
@injectable()
export default class implements Command {
public name = 'play';
public aliases = ['p'];
public examples = [
['play', 'resume paused playback'],
['play https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'plays a YouTube video'],
['play cool music', 'plays the first search result for "cool music" from YouTube'],
['play https://www.youtube.com/watch?list=PLi9drqWffJ9FWBo7ZVOiaVy0UQQEm4IbP', 'adds the playlist to the queue'],
['play https://open.spotify.com/track/3ebXMykcMXOcLeJ9xZ17XH?si=tioqSuyMRBWxhThhAW51Ig', 'plays a song from Spotify'],
['play https://open.spotify.com/album/5dv1oLETxdsYOkS2Sic00z?si=bDa7PaloRx6bMIfKdnvYQw', 'adds all songs from album to the queue'],
['play https://open.spotify.com/playlist/37i9dQZF1DX94qaYRnkufr?si=r2fOVL_QQjGxFM5MWb84Xw', 'adds all songs from playlist to the queue']
];
public requiresVC = true;
private readonly playerManager: PlayerManager;
private readonly getSongs: GetSongs;
constructor(@inject(TYPES.Managers.Player) playerManager: PlayerManager, @inject(TYPES.Services.GetSongs) getSongs: GetSongs) {
this.playerManager = playerManager;
this.getSongs = getSongs;
}
public async execute(msg: Message, args: string []): Promise<void> {
const [targetVoiceChannel] = getMostPopularVoiceChannel(msg.guild!);
const res = new LoadingMessage(msg.channel as TextChannel);
await res.start();
const player = this.playerManager.get(msg.guild!.id);
const queueOldSize = player.queueSize();
const wasPlayingSong = player.getCurrent() !== null;
if (args.length === 0) {
if (player.status === STATUS.PLAYING) {
await res.stop(errorMsg('already playing, give me a song name'));
return;
}
// Must be resuming play
if (!wasPlayingSong) {
await res.stop(errorMsg('nothing to play'));
return;
}
await player.connect(targetVoiceChannel);
await player.play();
await res.stop('the stop-and-go light is now green');
return;
}
const newSongs: QueuedSong[] = [];
let extraMsg = '';
// Test if it's a complete URL
try {
const url = new URL(args[0]);
const YOUTUBE_HOSTS = ['www.youtube.com', 'youtu.be', 'youtube.com'];
if (YOUTUBE_HOSTS.includes(url.host)) {
// YouTube source
if (url.searchParams.get('list')) {
// YouTube playlist
newSongs.push(...await this.getSongs.youtubePlaylist(url.searchParams.get('list') as string));
} else {
// Single video
const song = await this.getSongs.youtubeVideo(url.href);
if (song) {
newSongs.push(song);
} else {
await res.stop(errorMsg('that doesn\'t exist'));
return;
}
}
} else if (url.protocol === 'spotify:' || url.host === 'open.spotify.com') {
const [convertedSongs, nSongsNotFound, totalSongs] = await this.getSongs.spotifySource(args[0]);
if (totalSongs > 50) {
extraMsg = 'a random sample of 50 songs was taken';
}
if (totalSongs > 50 && nSongsNotFound !== 0) {
extraMsg += ' and ';
}
if (nSongsNotFound !== 0) {
if (nSongsNotFound === 1) {
extraMsg += '1 song was not found';
} else {
extraMsg += `${nSongsNotFound.toString()} songs were not found`;
}
}
newSongs.push(...convertedSongs);
}
} catch (_: unknown) {
// Not a URL, must search YouTube
const query = args.join(' ');
const song = await this.getSongs.youtubeVideoSearch(query);
if (song) {
newSongs.push(song);
} else {
await res.stop(errorMsg('that doesn\'t exist'));
return;
}
}
if (newSongs.length === 0) {
await res.stop(errorMsg('no songs found'));
return;
}
newSongs.forEach(song => player.add(song));
const firstSong = newSongs[0];
if (extraMsg !== '') {
extraMsg = ` (${extraMsg})`;
}
if (newSongs.length === 1) {
await res.stop(`u betcha, **${firstSong.title}** added to the queue${extraMsg}`);
} else {
await res.stop(`u betcha, **${firstSong.title}** and ${newSongs.length - 1} other songs were added to the queue${extraMsg}`);
}
if (queueOldSize === 0 && !wasPlayingSong) {
// Only auto-play if queue was empty before and nothing was playing
if (player.voiceConnection === null) {
await player.connect(targetVoiceChannel);
}
await player.play();
}
}
}
|