Use IoC, impliment queue

This commit is contained in:
Max Isom 2020-03-12 22:41:26 -05:00
parent 8eb4c8a6c0
commit 17ba78f7b7
17 changed files with 1081 additions and 131 deletions

View file

@ -4,5 +4,8 @@ dotenv.config();
export const DISCORD_TOKEN: string = process.env.DISCORD_TOKEN ? process.env.DISCORD_TOKEN : '';
export const DISCORD_CLIENT_ID: string = process.env.DISCORD_CLIENT_ID ? process.env.DISCORD_CLIENT_ID : '';
export const YOUTUBE_API_KEY: string = process.env.YOUTUBE_API_KEY ? process.env.YOUTUBE_API_KEY : '';
export const SPOTIFY_CLIENT_ID: string = process.env.SPOTIFY_CLIENT_ID ? process.env.SPOTIFY_CLIENT_ID : '';
export const SPOTIFY_CLIENT_SECRET: string = process.env.SPOTIFY_CLIENT_SECRET ? process.env.SPOTIFY_CLIENT_SECRET : '';
export const DATA_DIR = path.resolve(process.env.DATA_DIR ? process.env.DATA_DIR : './data');
export const CACHE_DIR = path.join(DATA_DIR, 'cache');

View file

@ -3,6 +3,7 @@ import {Readable, PassThrough} from 'stream';
import path from 'path';
import hasha from 'hasha';
import ytdl from 'ytdl-core';
import prism from 'prism-media';
import {CACHE_DIR} from './config';
const nextBestFormat = (formats: ytdl.videoFormat[]): ytdl.videoFormat => {
@ -24,9 +25,11 @@ export default async (url: string): Promise<Readable> => {
const filter = (format: ytdl.videoFormat): boolean => format.codecs === 'opus' && format.container === 'webm' && format.audioSampleRate !== undefined && parseInt(format.audioSampleRate, 10) === 48000;
let format = formats.find(filter);
let canDirectPlay = true;
if (!format) {
format = nextBestFormat(info.formats);
canDirectPlay = false;
}
try {
@ -46,6 +49,30 @@ export default async (url: string): Promise<Readable> => {
await fs.rename(cacheTempPath, cachedPath);
});
return ytdl.downloadFromInfo(info, {format}).pipe(pass);
if (canDirectPlay) {
return ytdl.downloadFromInfo(info, {format}).pipe(pass);
}
const transcoder = new prism.FFmpeg({
args: [
'-reconnect',
'1',
'-reconnect_streamed',
'1',
'-reconnect_delay_max',
'5',
'-i',
format.url,
'-loglevel',
'verbose',
'-vn',
'-acodec',
'libopus',
'-f',
'webm'
]
});
return transcoder.pipe(pass);
}
};

View file

@ -0,0 +1,67 @@
import {TextChannel, Message} from 'discord.js';
import delay from 'delay';
export default class {
private readonly channel: TextChannel;
private readonly text: string;
private msg!: Message;
private isStopped: boolean = false;
constructor(channel: TextChannel, text: string) {
this.channel = channel;
this.text = text;
}
async start(): Promise<void> {
this.msg = await this.channel.send(this.text);
const period = 500;
const icons = ['⚪', '🔵', '⚫'];
const reactions = [];
let i = 0;
let isRemoving = false;
(async () => {
while (!this.isStopped) {
if (reactions.length === icons.length) {
isRemoving = true;
}
// eslint-disable-next-line no-await-in-loop
await delay(period);
if (isRemoving) {
const reactionToRemove = reactions.shift();
if (reactionToRemove) {
// eslint-disable-next-line no-await-in-loop
await reactionToRemove.remove();
} else {
isRemoving = false;
}
} else {
if (!this.isStopped) {
// eslint-disable-next-line no-await-in-loop
reactions.push(await this.msg.react(icons[i % icons.length]));
}
i++;
}
}
})();
}
async stop(str?: string): Promise<Message> {
this.isStopped = true;
if (str) {
await Promise.all([this.msg.reactions.removeAll(), this.msg.edit(str)]);
} else {
await this.msg.reactions.removeAll();
}
return this.msg;
}
}