81 lines
2.4 KiB
TypeScript
81 lines
2.4 KiB
TypeScript
import { AudioPlayerStatus, AudioResource, createAudioPlayer, createAudioResource, VoiceConnection } from "@discordjs/voice";
|
|
import { stream as createStream } from "play-dl";
|
|
import { Guild } from "discord.js";
|
|
import { getOrCreateVoiceConnection } from "./util";
|
|
import { OutputHandler } from "../utils/outputHandler";
|
|
import play from "play-dl";
|
|
|
|
namespace InitPlayDl {
|
|
let initialized = false;
|
|
export async function init() {
|
|
if (initialized)
|
|
return;
|
|
|
|
await play.getFreeClientID();
|
|
initialized = true;
|
|
}
|
|
}
|
|
|
|
class MusicQueue {
|
|
private connection: VoiceConnection;
|
|
private list: AudioResource[];
|
|
constructor(connection: VoiceConnection) {
|
|
this.connection = connection;
|
|
this.list = [];
|
|
}
|
|
public static fromConnection(connection: VoiceConnection): MusicQueue {
|
|
return (connection as any).queue ??= new MusicQueue(connection);
|
|
}
|
|
private play() {
|
|
if (!this.list[0]) return;
|
|
const player = createAudioPlayer();
|
|
this.connection.subscribe(player);
|
|
player.once(AudioPlayerStatus.Idle, this.next.bind(this));
|
|
player.play(this.list[0]);
|
|
}
|
|
public enqueue(resource: AudioResource) {
|
|
this.list.push(resource);
|
|
if (this.list.length == 1) {
|
|
this.play();
|
|
return;
|
|
}
|
|
}
|
|
public next() {
|
|
this.list.shift();
|
|
this.play();
|
|
}
|
|
}
|
|
|
|
// TODO: 토큰 설정하고 플레이돼게 만들기
|
|
export async function playMusic(guild: Guild, url: string) {
|
|
try {
|
|
const connection = await getOrCreateVoiceConnection(guild);
|
|
if (!connection)
|
|
throw new Error("Yaeju is not joined VoiceChat");
|
|
|
|
await InitPlayDl.init();
|
|
|
|
const validation = play.yt_validate(url);
|
|
|
|
if (validation !== "video" && validation !== "playlist")
|
|
throw new Error("Invalid YouTube URL: " + validation);
|
|
|
|
const stream = await play.stream(url);
|
|
MusicQueue.fromConnection(connection).enqueue(
|
|
createAudioResource(stream.stream, {
|
|
inputType: stream.type
|
|
})
|
|
);
|
|
} catch(err) {
|
|
OutputHandler.errorLog("[PlayMusic Error]", err);
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
export async function skipMusic(guild: Guild) {
|
|
const connection = await getOrCreateVoiceConnection(guild);
|
|
if (!connection)
|
|
throw new Error("Yaeju is not joined VoiceChat");
|
|
|
|
MusicQueue.fromConnection(connection).next();
|
|
}
|