Skip to content

Commit

Permalink
Merge pull request #80 from TheophileDiot/disnake
Browse files Browse the repository at this point in the history
Fix music in general and update
  • Loading branch information
TheophileDiot authored May 29, 2022
2 parents 2973e24 + 2740eed commit 97ef901
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 85 deletions.
6 changes: 3 additions & 3 deletions bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# email theophile.diot900@gmail.com
# linting: black
# -----------------------------------------------------------
from asyncio import get_event_loop
from asyncio import new_event_loop
from datetime import date
from itertools import chain
from logging import basicConfig, DEBUG, error, info, INFO
Expand Down Expand Up @@ -407,9 +407,9 @@ async def setup(self, **kwargs):
level=DEBUG if getenv("ENV") == "DEVELOPMENT" else INFO,
) # Configure the logging

system("cls" if name == "nt" else "clear")
# system("cls" if name == "nt" else "clear")
print("Omnitron is starting...")
loop = get_event_loop()
loop = new_event_loop()
try:
loop.run_until_complete(Omnitron.setup()) # Starts the bot
except KeyboardInterrupt:
Expand Down
181 changes: 136 additions & 45 deletions cogs/dj/play.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from cmath import atan
from functools import wraps
from inspect import Parameter
from os import getenv
from re import compile as re_compile
from typing import Union
from typing import List, Union
from youtube_dl import utils, YoutubeDL

from disnake import (
ApplicationCommandInteraction,
Attachment,
Client as botClient,
Colour,
Embed,
NotFound,
VoiceClient,
Expand Down Expand Up @@ -103,6 +106,25 @@ def __init__(self, bot: Omnitron):
self.yt_rx = re_compile(
r"http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?‌​[\w\?‌​=]*)?"
)
utils.bug_reports_message = lambda: ""
self.ytdl = YoutubeDL(
{
"format": "worstaudio/worst",
"outtmpl": "temp/musics/%(title)s.%(ext)s",
"download_archive": "temp/musics.txt",
"restrictfilenames": True,
"noplaylist": True,
"nocheckcertificate": True,
"ignoreerrors": False,
"logtostderr": False,
"quiet": True,
"no_warnings": True,
"verbose": False,
"default_search": "auto",
# bind to ipv4 since ipv6 addresses cause issues sometimes
"source_address": "0.0.0.0",
}
)

""" EVENTS """

Expand Down Expand Up @@ -159,24 +181,9 @@ async def check(
self,
source,
query: str = None,
audio_file: Attachment = None,
):
"""This check ensures that the bot and command author are in the same voicechannel."""
try:
player = self.bot.lavalink.player_manager.create(
source.guild.id, endpoint=str(source.guild.region)
)
except NodeException:
if isinstance(source, Context):
return await source.reply(
f"⚠️ - {source.author.mention} - The player is not ready yet, please try again in a few seconds!",
delete_after=20,
)
else:
return await source.response.send_message(
f"⚠️ - {source.author.mention} - The player is not ready yet, please try again in a few seconds!",
ephemeral=True,
)

# Create returns a player if one exists, otherwise creates.
# This line is important because it ensures that a player always exists for a guild.

Expand All @@ -202,6 +209,22 @@ async def check(
ephemeral=True,
)

try:
player = self.bot.lavalink.player_manager.create(
source.guild.id, endpoint=source.author.voice.channel.rtc_region
)
except NodeException:
if isinstance(source, Context):
return await source.reply(
f"⚠️ - {source.author.mention} - The player is not ready yet, please try again in a few seconds!",
delete_after=20,
)
else:
return await source.response.send_message(
f"⚠️ - {source.author.mention} - The player is not ready yet, please try again in a few seconds!",
ephemeral=True,
)

if not player.is_connected:
if source.author.voice.channel == source.guild.afk_channel:
if isinstance(source, Context):
Expand Down Expand Up @@ -249,7 +272,7 @@ async def check(
ephemeral=True,
)

return await function(self, source, query)
return await function(self, source, query, audio_file=audio_file)

return check

Expand All @@ -259,30 +282,30 @@ async def check(
name="play",
aliases=["sc_p"],
usage="<link>|<Title>",
description="Plays a link or title from a SoundCloud/YouTube song! It can also play attachments! (supports playlists!)",
description="Plays a link or title from a YouTube/SoundCloud song or an audio file! (supports playlists!)",
)
@Utils.check_bot_starting()
@Utils.check_dj()
@bot_has_guild_permissions(connect=True, speak=True)
@bot_has_permissions(send_messages=True, embed_links=True)
@__ensure_voice
@max_concurrency(1, per=BucketType.guild)
async def play_command(self, source: Context, query: str = None):
async def play_command(self, source: Context, query: str = None, **kwargs):
"""
This command plays a link or title from a SoundCloud/YouTube song! (supports playlists!)
This command plays a link or title from a YouTube/SoundCloud song or an audio file! (supports playlists!)
Parameters
----------
source: :class:`disnake.ext.commands.Context`
The command context
query: :class:`str` optional
The SoundCloud/YouTube link or title
The link or YouTube/SoundCloud title
"""
await self.handle_play(source, query)

@slash_command(
name="play",
description="Plays a link or title from a SoundCloud/YouTube song! (supports playlists!)",
description="Plays a link or title from a YouTube/SoundCloud song or an audio file! (supports playlists!)",
)
@guild_only()
@Utils.check_bot_starting()
Expand All @@ -295,25 +318,30 @@ async def play_slash_command(
self,
source: ApplicationCommandInteraction,
query: str = None,
audio_file: Attachment = None,
):
"""
This slash command plays a link or title from a SoundCloud/YouTube song! (supports playlists!)
This slash command plays a link or title from a YouTube/SoundCloud song or an audio file! (supports playlists!)
Parameters
----------
source: :class:`disnake.ext.commands.ApplicationCommandInteraction`
The application command interaction
query: :class:`str` optional
The link or title
The link or YouTube/SoundCloud title
audio_file: :class:`disnake.ext.commands.Attachment` optional
The audio file to play
"""
await self.handle_play(source, query)
await self.handle_play(source, query, attachment=audio_file)

""" METHOD(S) """

async def handle_play(
self,
source: Union[Context, ApplicationCommandInteraction],
query: str = None,
*,
attachment: Attachment = None,
):
"""Searches and plays a song from a given query."""
# Get the player for this guild from cache.
Expand Down Expand Up @@ -366,14 +394,28 @@ async def handle_play(

try:
results = await player.node.get_tracks(
query if query else source.message.attachments[0].url
query if query else await source.message.attachments[0].read()
)
except TimeoutError:
return await source.reply(
f"⚠️ - {source.author.mention} - Your query timed out!",
delete_after=20,
)

if (
(not results or results and "exception" in results or not results["tracks"])
and query
and query.startswith("ytsearch:")
):
query = query.replace("ytsearch:", "scsearch:")
try:
results = await player.node.get_tracks(query)
except TimeoutError:
return await source.reply(
f"⚠️ - {source.author.mention} - Your query timed out!",
delete_after=20,
)

# Results could be None if Lavalink returns an invalid response (non-JSON/non-200 (OK)).
# ALternatively, results['tracks'] could be an empty array if the query yielded no tracks.
if results and "exception" in results:
Expand Down Expand Up @@ -402,7 +444,7 @@ async def handle_play(
# Valid loadTypes are:
# TRACK_LOADED - single video/direct URL)
# PLAYLIST_LOADED - direct URL to playlist)
# SEARCH_RESULT - query prefixed with either ytsearch: or scsearch:.
# SEARCH_RESULT - query prefixed with either ytsearch:.
# NO_MATCHES - query yielded no results
# LOAD_FAILED - most likely, the video encountered an exception during loading.
if results["loadType"] == "PLAYLIST_LOADED":
Expand All @@ -422,32 +464,80 @@ async def handle_play(
else:
content = "🎶 - **Playing:** - 🎶"

yt_infos = None
try:
if self.yt_rx.match(track["info"]["uri"]):
yt_infos = self.ytdl.extract_info(
track["info"]["uri"], download=False
)
except Exception as e:
if not f"{e}".endswith(
"This video may be inappropriate for some users."
):
if isinstance(source, Context):
return await source.reply(
f"⚠️ - {source.author.mention} - An error occurred while retrieving the video information, please try again in a few moments!",
delete_after=20,
)
else:
return await source.followup.send(
f"⚠️ - {source.author.mention} - An error occurred while retrieving the video information, please try again in a few moments!",
ephemeral=True,
)
else:
if isinstance(source, Context):
return await source.reply(
f"⚠️ - {source.author.mention} - This video is not suitable for some users! (I can't play some age restricted videos)",
delete_after=20,
)
else:
return await source.followup.send(
f"⚠️ - {source.author.mention} - This video is not suitable for some users! (I can't play some age restricted videos)",
ephemeral=True,
)

# You can attach additional information to audiotracks through kwargs, however this involves
# constructing the AudioTrack class yourself.
audio_track = AudioTrack(track, source.author.id, recommended=True)
player.add(requester=source.author.id, track=audio_track)

title = (
track["info"]["title"]
if track["info"]["title"] != "Unknown title"
or not isinstance(source, Context)
or not source.message.attachments
else source.message.attachments[0].filename
)
url = (
query
if query and not query.startswith("ytsearch")
else track["info"]["uri"]
)
duration = self.bot.utils_class.duration(track["info"]["length"] / 1000)
if yt_infos:
colour = Colour(0xFF0000)
title = yt_infos["title"]
url = (
yt_infos["webpage_url"]
if "webpage_url" in yt_infos
else yt_infos["video_url"]
)
duration = self.bot.utils_class.duration(yt_infos["duration"])
author = f"Channel: {yt_infos['channel']}"
else:
colour = self.bot.color
title = (
track["info"]["title"]
if track["info"]["title"] != "Unknown title"
or not isinstance(source, Context)
or not source.message.attachments
else source.message.attachments[0].filename
)
url = (
query
if query and not query.startswith("ytsearch")
else track["info"]["uri"]
)
duration = self.bot.utils_class.duration(track["info"]["length"] / 1000)
author = track["info"]["author"]

em = Embed(
colour=self.bot.color,
colour=colour,
title=title,
url=url,
)

em.set_author(name=track["info"]["author"])
if yt_infos is not None:
em.set_thumbnail(url=yt_infos["thumbnail"])

em.set_author(name=author)
em.set_footer(text=f"duration: {duration}")

self.bot.playlists[source.guild.id].append(
Expand All @@ -461,8 +551,9 @@ async def handle_play(
),
"title": title,
"url": url,
"author": track["info"]["author"],
"author": author,
"duration": duration,
"thumbnail": yt_infos["thumbnail"] if yt_infos is not None else None,
}
)

Expand Down
5 changes: 5 additions & 0 deletions cogs/dj/playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ async def handle_playlist(
em.title = self.bot.playlists[source.guild.id][position]["title"]
em.url = self.bot.playlists[source.guild.id][position]["url"]

if self.bot.playlists[source.guild.id][position].get("thumbnail"):
em.set_thumbnail(
url=self.bot.playlists[source.guild.id][position]["thumbnail"]
)

em.set_author(
name=f"Author: {self.bot.playlists[source.guild.id][position]['author']}"
)
Expand Down
2 changes: 1 addition & 1 deletion cogs/events/on_voice_state_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ async def on_voice_state_update(
if _id in self.voice_intervals:
self.voice_intervals.pop(_id).cancel()

if not member.bot and after.channel is None:
if after.channel != before.channel:
if not [m for m in before.channel.members if not m.bot]:
if member.guild.voice_client:
await member.guild.voice_client.disconnect(force=True)
Expand Down
Binary file added lavalink/2277cf-Lavalink.jar
Binary file not shown.
8 changes: 5 additions & 3 deletions lavalink/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
FROM arm64v8/openjdk:17.0-slim-buster
# FROM openjdk:17-alpine # for amd64 CPU
# FROM arm64v8/openjdk:17.0-slim-buster
FROM openjdk:17-alpine

WORKDIR /opt/Lavalink

COPY Lavalink.jar Lavalink.jar
# temporary workaround for youtube search
# COPY Lavalink.jar Lavalink.jar
COPY 2277cf-Lavalink.jar Lavalink.jar
COPY application.yml application.yml

EXPOSE 2333
Expand Down
Loading

0 comments on commit 97ef901

Please sign in to comment.