-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 141a34e
Showing
6 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
venv/ | ||
__pycache__/ | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
from discord.ext import commands | ||
from discord import FFmpegPCMAudio | ||
|
||
from manager import Manager | ||
from custom_queue import CustomQueue | ||
from settings import DISCORD_TOKEN, GUILD_NAME | ||
|
||
manager = Manager() | ||
queues = CustomQueue() | ||
bot = commands.Bot(command_prefix="!") | ||
|
||
|
||
@bot.event | ||
async def on_ready(): | ||
print(f"{bot.user.name} has connected to Discord!") | ||
|
||
|
||
def find_voice(ctx): | ||
voice = None | ||
for voice_client in bot.voice_clients: | ||
if voice_client.guild == ctx.guild: | ||
voice = voice_client | ||
return voice | ||
|
||
|
||
async def start_playing(ctx, audio_name): | ||
if audio_name == None: | ||
return | ||
|
||
def play(id, voice): | ||
if not queues.get_loop(id): | ||
queues.pop(id) | ||
if queues.get_len(id) == 0: | ||
return | ||
|
||
source = FFmpegPCMAudio(queues.front(id)) | ||
player = voice.play(source, after=lambda x=None: play(id, voice)) | ||
|
||
id = ctx.message.guild.id | ||
if ctx.author.voice: | ||
channel = ctx.message.author.voice.channel | ||
|
||
voice = find_voice(ctx) | ||
if not voice: | ||
voice = await channel.connect() | ||
|
||
if voice.is_playing(): | ||
stop(ctx) | ||
|
||
source = FFmpegPCMAudio(audio_name) | ||
player = voice.play(source, after=lambda x=None: play(id, voice)) | ||
else: | ||
await ctx.send("You are not on audio server") | ||
|
||
|
||
@bot.command(name="leave") | ||
async def leave(ctx): | ||
id = ctx.message.guild.id | ||
queues.set_loop(id, False) | ||
queues.clear(id) | ||
if ctx.voice_client: | ||
await ctx.guild.voice_client.disconnect() | ||
await ctx.send("I left the voice channel") | ||
else: | ||
await ctx.send("I am not in a voice channel") | ||
|
||
|
||
@bot.command(name="pause") | ||
async def pause(ctx): | ||
voice = find_voice(ctx) | ||
if not voice: | ||
return | ||
if voice.is_playing(): | ||
voice.pause() | ||
else: | ||
await ctx.send("Nothing is being played right now") | ||
|
||
|
||
@bot.command(name="resume") | ||
async def resume(ctx): | ||
voice = find_voice(ctx) | ||
if not voice: | ||
return | ||
if voice.is_playing(): | ||
await ctx.send("It's already playing") | ||
else: | ||
voice.resume() | ||
|
||
|
||
@bot.command(name="skip") | ||
async def skip(ctx): | ||
id = ctx.message.guild.id | ||
queues.set_loop(id, False) | ||
voice = find_voice(ctx) | ||
if not voice: | ||
return | ||
voice.stop() | ||
|
||
|
||
@bot.command(name="yt") | ||
async def youtube(ctx, url): | ||
id = ctx.message.guild.id | ||
result_name = manager.youtube_query(url) | ||
queues.add(id, result_name) | ||
|
||
if queues.get_len(id) == 1: | ||
await start_playing(ctx, result_name) | ||
|
||
|
||
@bot.command(name="tts") | ||
async def text_to_speech(ctx, text): | ||
id = ctx.message.guild.id | ||
result_name = manager.tts_query(text) | ||
queues.add(id, result_name) | ||
|
||
if queues.get_len(id) == 1: | ||
await start_playing(ctx, result_name) | ||
|
||
|
||
@bot.command(name="clear") | ||
async def clear_queue(ctx): | ||
id = ctx.message.guild.id | ||
queues.clear(id) | ||
|
||
|
||
@bot.command(name="loop") | ||
async def loop(ctx): | ||
id = ctx.message.guild.id | ||
queues.set_loop(id, True) | ||
|
||
|
||
bot.run(DISCORD_TOKEN) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
class CustomQueue: | ||
def __init__(self): | ||
self.loops = {} | ||
self.data = {} | ||
|
||
def set_loop(self, id, value): | ||
self.loops[id] = value | ||
|
||
def get_loop(self, id): | ||
if not id in self.loops: | ||
return False | ||
return self.loops[id] | ||
|
||
def add(self, id, audio_name): | ||
if id in self.data: | ||
self.data[id].append(audio_name) | ||
else: | ||
self.data[id] = [audio_name] | ||
|
||
def clear(self, id): | ||
self.data[id] = [] | ||
self.loops[id] = False | ||
|
||
def pop(self, id): | ||
if not id in self.data or self.data[id] == []: | ||
return None | ||
return self.data[id].pop(0) | ||
|
||
def front(self, id): | ||
if not id in self.data or self.data[id] == []: | ||
return None | ||
return self.data[id][0] | ||
|
||
def get_len(self, id): | ||
if not id in self.data: | ||
return 0 | ||
return len(self.data[id]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from os import remove | ||
from os.path import isfile | ||
|
||
from gtts import gTTS | ||
import youtube_dl | ||
|
||
from settings import DEFAULT_YOUTUBE_OPTIONS, MAX_YOUTUBE_VIDEOS, MAX_TTS_FILES | ||
|
||
|
||
class Manager: | ||
def __init__(self): | ||
self.current_youtube_options = DEFAULT_YOUTUBE_OPTIONS | ||
self.cnt_yt = 0 | ||
self.cnt_tts = 0 | ||
self.video_map = {} | ||
self.delete_youtube_files() | ||
|
||
def delete_youtube_files(self): | ||
for i in range(MAX_YOUTUBE_VIDEOS): | ||
if isfile("yt" + str(i) + ".wav"): | ||
remove("yt" + str(i) + ".wav") | ||
|
||
def tts_query(self, text): | ||
tts = gTTS(text) | ||
result_name = "tts" + str(self.cnt_tts) + ".wav" | ||
self.cnt_tts = (self.cnt_tts) % MAX_TTS_FILES | ||
tts.save(result_name) | ||
return result_name | ||
|
||
def youtube_query(self, url): | ||
if url in self.video_map: | ||
return self.video_map[url] | ||
|
||
file_name = "yt" + str(self.cnt_yt) + ".wav" | ||
self.video_map[url] = file_name | ||
self.cnt_yt = (self.cnt_yt + 1) % MAX_YOUTUBE_VIDEOS | ||
self.current_youtube_options["outtmpl"] = file_name | ||
with youtube_dl.YoutubeDL(self.current_youtube_options) as ydl: | ||
ydl.download([url]) | ||
return file_name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
aiohttp==3.7.4.post0 | ||
async-timeout==3.0.1 | ||
attrs==21.2.0 | ||
certifi==2021.5.30 | ||
cffi==1.14.6 | ||
chardet==4.0.0 | ||
charset-normalizer==2.0.3 | ||
click==8.0.1 | ||
discord.py==1.7.3 | ||
gTTS==2.2.3 | ||
idna==3.2 | ||
importlib-metadata==4.6.1 | ||
multidict==5.1.0 | ||
pycparser==2.20 | ||
PyNaCl==1.4.0 | ||
requests==2.26.0 | ||
six==1.16.0 | ||
typing-extensions==3.10.0.0 | ||
urllib3==1.26.6 | ||
yarl==1.6.3 | ||
youtube-dl==2021.6.6 | ||
zipp==3.5.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
DISCORD_TOKEN = "ODY2MDgyNTc2MzY2ODI5NTc4.YPNYQQ.56_lM-ccEh6EQcLIATaKBa-OURI" | ||
|
||
GUILD_NAME = "SummerProjectTestServer" | ||
|
||
DEFAULT_YOUTUBE_OPTIONS = { | ||
"outtmpl": "yt1.wav", | ||
"format": "bestaudio/best", | ||
"postprocessors": [ | ||
{ | ||
"key": "FFmpegExtractAudio", | ||
"preferredcodec": "wav", | ||
"preferredquality": "192", | ||
} | ||
], | ||
} | ||
|
||
MAX_YOUTUBE_VIDEOS = 10 | ||
MAX_TTS_FILES = 10 |