Comment for the code and Fix for #46
This commit is contained in:
parent
db703f5e98
commit
7df7dff7ea
@ -31,7 +31,7 @@ You can enable the web interface into the configuration.ini file.
|
|||||||
|
|
||||||
Example installation commands for Debian and Ubuntu:
|
Example installation commands for Debian and Ubuntu:
|
||||||
```
|
```
|
||||||
apt install python3-venv ffmpeg libjpeg-dev
|
apt install python3-venv ffmpeg libjpeg-dev zlibc zlib1g zlib1g-dev
|
||||||
git clone --recurse-submodules https://github.com/azlux/botamusique.git
|
git clone --recurse-submodules https://github.com/azlux/botamusique.git
|
||||||
cd botamusique
|
cd botamusique
|
||||||
python3 -m venv venv
|
python3 -m venv venv
|
||||||
|
@ -12,9 +12,15 @@ def get_playlist_info(url, start_index=1, user=""):
|
|||||||
info = ydl.extract_info(url, download=False)
|
info = ydl.extract_info(url, download=False)
|
||||||
playlist_title = info['title']
|
playlist_title = info['title']
|
||||||
for j in range(start_index, min(len(info['entries']), start_index + var.config.getint('bot', 'max_track_playlist'))):
|
for j in range(start_index, min(len(info['entries']), start_index + var.config.getint('bot', 'max_track_playlist'))):
|
||||||
|
# Unknow String if No title into the json
|
||||||
|
title = info['entries'][j]['title'] if 'title' in info['entries'][j] else "Unknown Title"
|
||||||
|
# Add youtube url if the url in the json isn't a full url
|
||||||
|
url = info['entries'][j]['url'] if info['entries'][j]['url'][0:4] == 'http' else "https://www.youtube.com/watch?v=" + info['entries'][j]['url']
|
||||||
|
|
||||||
|
# append the music to a list of futur music to play
|
||||||
music = {'type': 'url',
|
music = {'type': 'url',
|
||||||
'title': info['entries'][j]['title'],
|
'title': title,
|
||||||
'url': "https://www.youtube.com/watch?v=" + info['entries'][j]['url'],
|
'url': url,
|
||||||
'user': user,
|
'user': user,
|
||||||
'from_playlist': True,
|
'from_playlist': True,
|
||||||
'playlist_title': playlist_title,
|
'playlist_title': playlist_title,
|
||||||
@ -36,9 +42,11 @@ def get_music_info(index=0):
|
|||||||
for i in range(2):
|
for i in range(2):
|
||||||
try:
|
try:
|
||||||
info = ydl.extract_info(var.playlist[0]['url'], download=False)
|
info = ydl.extract_info(var.playlist[0]['url'], download=False)
|
||||||
|
# Check if the Duration is longer than the config
|
||||||
if var.playlist[0]['current_index'] == index:
|
if var.playlist[0]['current_index'] == index:
|
||||||
var.playlist[0]['current_duration'] = info['entries'][0]['duration'] / 60
|
var.playlist[0]['current_duration'] = info['entries'][0]['duration'] / 60
|
||||||
var.playlist[0]['current_title'] = info['entries'][0]['title']
|
var.playlist[0]['current_title'] = info['entries'][0]['title']
|
||||||
|
# Check if the Duration of the next music is longer than the config (async download)
|
||||||
elif var.playlist[0]['current_index'] == index - 1:
|
elif var.playlist[0]['current_index'] == index - 1:
|
||||||
var.playlist[0]['next_duration'] = info['entries'][0]['duration'] / 60
|
var.playlist[0]['next_duration'] = info['entries'][0]['duration'] / 60
|
||||||
var.playlist[0]['next_title'] = info['entries'][0]['title']
|
var.playlist[0]['next_title'] = info['entries'][0]['title']
|
||||||
|
87
mumbleBot.py
87
mumbleBot.py
@ -28,6 +28,33 @@ import media.playlist
|
|||||||
import media.radio
|
import media.radio
|
||||||
import media.system
|
import media.system
|
||||||
|
|
||||||
|
"""
|
||||||
|
FORMAT OF A MUSIC INTO THE PLAYLIST
|
||||||
|
type : url
|
||||||
|
url
|
||||||
|
title
|
||||||
|
path
|
||||||
|
duration
|
||||||
|
thundnail
|
||||||
|
user
|
||||||
|
ready (validation, no, downloading, yes)
|
||||||
|
from_playlist (yes,no)
|
||||||
|
playlist_title
|
||||||
|
playlist_url
|
||||||
|
|
||||||
|
type : radio
|
||||||
|
url
|
||||||
|
name
|
||||||
|
current_title
|
||||||
|
user
|
||||||
|
|
||||||
|
type : file
|
||||||
|
path
|
||||||
|
title
|
||||||
|
duration
|
||||||
|
user
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class MumbleBot:
|
class MumbleBot:
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
@ -38,6 +65,7 @@ class MumbleBot:
|
|||||||
|
|
||||||
self.channel = args.channel
|
self.channel = args.channel
|
||||||
|
|
||||||
|
# Set specific format for the log
|
||||||
FORMAT = '%(asctime)s: %(message)s'
|
FORMAT = '%(asctime)s: %(message)s'
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
logging.basicConfig(format=FORMAT, level=logging.DEBUG, datefmt='%Y-%m-%d %H:%M:%S')
|
logging.basicConfig(format=FORMAT, level=logging.DEBUG, datefmt='%Y-%m-%d %H:%M:%S')
|
||||||
@ -49,6 +77,7 @@ class MumbleBot:
|
|||||||
logging.basicConfig(format=FORMAT, level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
|
logging.basicConfig(format=FORMAT, level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
|
||||||
logging.info("Starting in INFO loglevel")
|
logging.info("Starting in INFO loglevel")
|
||||||
|
|
||||||
|
# the playlist is... a list (Surprise !!)
|
||||||
var.playlist = []
|
var.playlist = []
|
||||||
|
|
||||||
var.user = args.user
|
var.user = args.user
|
||||||
@ -99,7 +128,7 @@ class MumbleBot:
|
|||||||
self.username = var.config.get("bot", "username")
|
self.username = var.config.get("bot", "username")
|
||||||
|
|
||||||
self.mumble = pymumble.Mumble(host, user=self.username, port=port, password=password, tokens=tokens,
|
self.mumble = pymumble.Mumble(host, user=self.username, port=port, password=password, tokens=tokens,
|
||||||
debug=var.config.getboolean('debug', 'mumbleConnection'), certfile=args.certificate)
|
debug=var.config.getboolean('debug', 'mumbleConnection'), certfile=certificate)
|
||||||
self.mumble.callbacks.set_callback("text_received", self.message_received)
|
self.mumble.callbacks.set_callback("text_received", self.message_received)
|
||||||
|
|
||||||
self.mumble.set_codec_profile("audio")
|
self.mumble.set_codec_profile("audio")
|
||||||
@ -113,6 +142,7 @@ class MumbleBot:
|
|||||||
|
|
||||||
self.loop()
|
self.loop()
|
||||||
|
|
||||||
|
# Set the CTRL+C shortcut
|
||||||
def ctrl_caught(self, signal, frame):
|
def ctrl_caught(self, signal, frame):
|
||||||
logging.info("\nSIGINT caught, quitting, {} more to kill".format(2 - self.nb_exit))
|
logging.info("\nSIGINT caught, quitting, {} more to kill".format(2 - self.nb_exit))
|
||||||
self.exit = True
|
self.exit = True
|
||||||
@ -122,13 +152,21 @@ class MumbleBot:
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
self.nb_exit += 1
|
self.nb_exit += 1
|
||||||
|
|
||||||
|
# All text send to the chat is analysed by this function
|
||||||
def message_received(self, text):
|
def message_received(self, text):
|
||||||
|
|
||||||
message = text.message.strip()
|
message = text.message.strip()
|
||||||
user = self.mumble.users[text.actor]['name']
|
user = self.mumble.users[text.actor]['name']
|
||||||
|
|
||||||
if var.config.getboolean('command', 'split_username_at_space'):
|
if var.config.getboolean('command', 'split_username_at_space'):
|
||||||
|
# in can you use https://github.com/Natenom/mumblemoderator-module-collection/tree/master/os-suffixes , you want to split the username
|
||||||
user = user.split()[0]
|
user = user.split()[0]
|
||||||
|
|
||||||
if message[0] == var.config.get('command', 'command_symbol'):
|
if message[0] == var.config.get('command', 'command_symbol'):
|
||||||
|
# remove the symbol from the message
|
||||||
message = message[1:].split(' ', 1)
|
message = message[1:].split(' ', 1)
|
||||||
|
|
||||||
|
# use the first word as a command, the others one as parameters
|
||||||
if len(message) > 0:
|
if len(message) > 0:
|
||||||
command = message[0]
|
command = message[0]
|
||||||
parameter = ''
|
parameter = ''
|
||||||
@ -144,6 +182,7 @@ class MumbleBot:
|
|||||||
self.mumble.users.myself.move_in(self.mumble.users[text.actor]['channel_id'], token=parameter)
|
self.mumble.users.myself.move_in(self.mumble.users[text.actor]['channel_id'], token=parameter)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Anti stupid guy function
|
||||||
if not self.is_admin(user) and not var.config.getboolean('bot', 'allow_other_channel_message') and self.mumble.users[text.actor]['channel_id'] != self.mumble.users.myself['channel_id']:
|
if not self.is_admin(user) and not var.config.getboolean('bot', 'allow_other_channel_message') and self.mumble.users[text.actor]['channel_id'] != self.mumble.users.myself['channel_id']:
|
||||||
self.mumble.users[text.actor].send_message(var.config.get('strings', 'not_in_my_channel'))
|
self.mumble.users[text.actor].send_message(var.config.get('strings', 'not_in_my_channel'))
|
||||||
return
|
return
|
||||||
@ -152,6 +191,9 @@ class MumbleBot:
|
|||||||
self.mumble.users[text.actor].send_message(var.config.get('strings', 'pm_not_allowed'))
|
self.mumble.users[text.actor].send_message(var.config.get('strings', 'pm_not_allowed'))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
###
|
||||||
|
# Admin command
|
||||||
|
###
|
||||||
for i in var.db.items("user_ban"):
|
for i in var.db.items("user_ban"):
|
||||||
if user.lower() == i[0]:
|
if user.lower() == i[0]:
|
||||||
self.mumble.users[text.actor].send_message(var.config.get('strings', 'user_ban'))
|
self.mumble.users[text.actor].send_message(var.config.get('strings', 'user_ban'))
|
||||||
@ -199,6 +241,9 @@ class MumbleBot:
|
|||||||
self.mumble.users[text.actor].send_message(var.config.get('strings', 'url_ban'))
|
self.mumble.users[text.actor].send_message(var.config.get('strings', 'url_ban'))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
###
|
||||||
|
# everyday commands
|
||||||
|
###
|
||||||
if command == var.config.get('command', 'play_file') and parameter:
|
if command == var.config.get('command', 'play_file') and parameter:
|
||||||
music_folder = var.config.get('bot', 'music_folder')
|
music_folder = var.config.get('bot', 'music_folder')
|
||||||
# sanitize "../" and so on
|
# sanitize "../" and so on
|
||||||
@ -230,7 +275,7 @@ class MumbleBot:
|
|||||||
|
|
||||||
elif command == var.config.get('command', 'play_url') and parameter:
|
elif command == var.config.get('command', 'play_url') and parameter:
|
||||||
music = {'type': 'url',
|
music = {'type': 'url',
|
||||||
'url': self.get_url_from_input(parameter),
|
'url': self.get_url_from_input(parameter), # grab the real URL
|
||||||
'user': user,
|
'user': user,
|
||||||
'ready': 'validation'}
|
'ready': 'validation'}
|
||||||
var.playlist.append(music)
|
var.playlist.append(music)
|
||||||
@ -241,7 +286,6 @@ class MumbleBot:
|
|||||||
self.send_msg(var.config.get('strings', 'too_long'), text)
|
self.send_msg(var.config.get('strings', 'too_long'), text)
|
||||||
else:
|
else:
|
||||||
for i in var.db.options("url_ban"):
|
for i in var.db.options("url_ban"):
|
||||||
print(i, ' -> ', {var.playlist[-1]["url"]})
|
|
||||||
if var.playlist[-1]['url'] == i:
|
if var.playlist[-1]['url'] == i:
|
||||||
self.mumble.users[text.actor].send_message(var.config.get('strings', 'url_ban'))
|
self.mumble.users[text.actor].send_message(var.config.get('strings', 'url_ban'))
|
||||||
var.playlist.pop()
|
var.playlist.pop()
|
||||||
@ -253,7 +297,7 @@ class MumbleBot:
|
|||||||
self.send_msg(var.config.get('strings', 'unable_download'), text)
|
self.send_msg(var.config.get('strings', 'unable_download'), text)
|
||||||
|
|
||||||
elif command == var.config.get('command', 'play_playlist') and parameter:
|
elif command == var.config.get('command', 'play_playlist') and parameter:
|
||||||
offset = 1
|
offset = 1 # if you want to start the playlist at a specific index
|
||||||
try:
|
try:
|
||||||
offset = int(parameter.split(" ")[-1])
|
offset = int(parameter.split(" ")[-1])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -286,6 +330,7 @@ class MumbleBot:
|
|||||||
elif command == var.config.get('command', 'update'):
|
elif command == var.config.get('command', 'update'):
|
||||||
if self.is_admin(user):
|
if self.is_admin(user):
|
||||||
self.mumble.users[text.actor].send_message("Starting the update")
|
self.mumble.users[text.actor].send_message("Starting the update")
|
||||||
|
# Need to be improved
|
||||||
tp = sp.check_output([var.config.get('bot', 'pip3_path'), 'install', '--upgrade', 'youtube-dl']).decode()
|
tp = sp.check_output([var.config.get('bot', 'pip3_path'), 'install', '--upgrade', 'youtube-dl']).decode()
|
||||||
msg = ""
|
msg = ""
|
||||||
if "Requirement already up-to-date" in tp:
|
if "Requirement already up-to-date" in tp:
|
||||||
@ -293,6 +338,7 @@ class MumbleBot:
|
|||||||
else:
|
else:
|
||||||
msg += "Update done : " + tp.split('Successfully installed')[1]
|
msg += "Update done : " + tp.split('Successfully installed')[1]
|
||||||
if 'up-to-date' not in sp.check_output(['/usr/bin/env', 'git', 'pull']).decode():
|
if 'up-to-date' not in sp.check_output(['/usr/bin/env', 'git', 'pull']).decode():
|
||||||
|
# Need to change it with release tag
|
||||||
msg += "<br /> I'm up-to-date"
|
msg += "<br /> I'm up-to-date"
|
||||||
else:
|
else:
|
||||||
msg += "<br /> I have available updates, need to do it manually"
|
msg += "<br /> I have available updates, need to do it manually"
|
||||||
@ -306,6 +352,7 @@ class MumbleBot:
|
|||||||
self.mumble.channels.find_by_name(self.channel).move_in()
|
self.mumble.channels.find_by_name(self.channel).move_in()
|
||||||
|
|
||||||
elif command == var.config.get('command', 'volume'):
|
elif command == var.config.get('command', 'volume'):
|
||||||
|
# The volume is a percentage
|
||||||
if parameter is not None and parameter.isdigit() and 0 <= int(parameter) <= 100:
|
if parameter is not None and parameter.isdigit() and 0 <= int(parameter) <= 100:
|
||||||
self.volume = float(float(parameter) / 100)
|
self.volume = float(float(parameter) / 100)
|
||||||
self.send_msg(var.config.get('strings', 'change_volume') % (
|
self.send_msg(var.config.get('strings', 'change_volume') % (
|
||||||
@ -349,13 +396,15 @@ class MumbleBot:
|
|||||||
self.send_msg(reply, text)
|
self.send_msg(reply, text)
|
||||||
|
|
||||||
elif command == var.config.get('command', 'skip'):
|
elif command == var.config.get('command', 'skip'):
|
||||||
if parameter is not None and parameter.isdigit() and int(parameter) > 0:
|
if parameter is not None and parameter.isdigit() and int(parameter) > 0: # Allow to remove specific music into the queue with a number
|
||||||
if int(parameter) < len(var.playlist):
|
if int(parameter) < len(var.playlist):
|
||||||
removed = var.playlist.pop(int(parameter))
|
removed = var.playlist.pop(int(parameter))
|
||||||
|
|
||||||
|
# the Title isn't here if the music wasn't downloaded
|
||||||
self.send_msg(var.config.get('strings', 'removing_item') % (removed['title'] if 'title' in removed else removed['url']), text)
|
self.send_msg(var.config.get('strings', 'removing_item') % (removed['title'] if 'title' in removed else removed['url']), text)
|
||||||
else:
|
else:
|
||||||
self.send_msg(var.config.get('strings', 'no_possible'), text)
|
self.send_msg(var.config.get('strings', 'no_possible'), text)
|
||||||
elif self.next():
|
elif self.next(): # Is no number send, just skip the current music
|
||||||
self.launch_music()
|
self.launch_music()
|
||||||
self.async_download_next()
|
self.async_download_next()
|
||||||
else:
|
else:
|
||||||
@ -413,24 +462,28 @@ class MumbleBot:
|
|||||||
uri = ""
|
uri = ""
|
||||||
logging.debug("launch_music asked" + str(var.playlist[0]))
|
logging.debug("launch_music asked" + str(var.playlist[0]))
|
||||||
if var.playlist[0]["type"] == "url":
|
if var.playlist[0]["type"] == "url":
|
||||||
|
# Delete older music is the tmp folder is too big
|
||||||
media.system.clear_tmp_folder(var.config.get('bot', 'tmp_folder'), var.config.getint('bot', 'tmp_folder_max_size'))
|
media.system.clear_tmp_folder(var.config.get('bot', 'tmp_folder'), var.config.getint('bot', 'tmp_folder_max_size'))
|
||||||
|
|
||||||
|
# Check if the music is ready to be played
|
||||||
if var.playlist[0]["ready"] == "downloading":
|
if var.playlist[0]["ready"] == "downloading":
|
||||||
return
|
return
|
||||||
elif var.playlist[0]["ready"] != "yes":
|
elif var.playlist[0]["ready"] != "yes":
|
||||||
logging.info("Current music wasn't ready, Downloading...")
|
logging.info("Current music wasn't ready, Downloading...")
|
||||||
self.download_music(index=0)
|
self.download_music(index=0)
|
||||||
|
|
||||||
|
# get the Path
|
||||||
uri = var.playlist[0]['path']
|
uri = var.playlist[0]['path']
|
||||||
if os.path.isfile(uri):
|
if os.path.isfile(uri):
|
||||||
audio = EasyID3(uri)
|
audio = EasyID3(uri)
|
||||||
title = ""
|
title = ""
|
||||||
if audio["title"]:
|
if audio["title"]:
|
||||||
title = audio["title"][0]
|
title = audio["title"][0] # take the title from the file tag
|
||||||
|
|
||||||
path_thumbnail = var.playlist[0]['path'][:-4] + '.jpg' # Remove .mp3 and add .jpg
|
path_thumbnail = var.playlist[0]['path'][:-4] + '.jpg' # Remove .mp3 and add .jpg
|
||||||
thumbnail_html = ""
|
thumbnail_html = ""
|
||||||
if os.path.isfile(path_thumbnail):
|
if os.path.isfile(path_thumbnail):
|
||||||
|
# Create the image message
|
||||||
im = Image.open(path_thumbnail)
|
im = Image.open(path_thumbnail)
|
||||||
im.thumbnail((100, 100), Image.ANTIALIAS)
|
im.thumbnail((100, 100), Image.ANTIALIAS)
|
||||||
buffer = BytesIO()
|
buffer = BytesIO()
|
||||||
@ -460,13 +513,14 @@ class MumbleBot:
|
|||||||
|
|
||||||
command = ["ffmpeg", '-v', ffmpeg_debug, '-nostdin', '-i', uri, '-ac', '1', '-f', 's16le', '-ar', '48000', '-']
|
command = ["ffmpeg", '-v', ffmpeg_debug, '-nostdin', '-i', uri, '-ac', '1', '-f', 's16le', '-ar', '48000', '-']
|
||||||
logging.info("FFmpeg command : " + " ".join(command))
|
logging.info("FFmpeg command : " + " ".join(command))
|
||||||
self.thread = sp.Popen(command, stdout=sp.PIPE, bufsize=480)
|
self.thread = sp.Popen(command, stdout=sp.PIPE, bufsize=480) # The ffmpeg process is a thread
|
||||||
self.is_playing = True
|
self.is_playing = True
|
||||||
|
|
||||||
def download_music(self, index):
|
def download_music(self, index):
|
||||||
if var.playlist[index]['type'] == 'url' and var.playlist[index]['ready'] == "validation":
|
if var.playlist[index]['type'] == 'url' and var.playlist[index]['ready'] == "validation":
|
||||||
if media.url.get_url_info(index=index):
|
if media.url.get_url_info(index=index):
|
||||||
if var.playlist[index]['duration'] > var.config.getint('bot', 'max_track_duration'):
|
if var.playlist[index]['duration'] > var.config.getint('bot', 'max_track_duration'):
|
||||||
|
# Check the length, useful in case of playlist, it wasn't checked before)
|
||||||
var.playlist.pop()
|
var.playlist.pop()
|
||||||
logging.info("the music " + var.playlist[index]["url"] + " has a duration of " + var.playlist[index]['duration'] + "s -- too long")
|
logging.info("the music " + var.playlist[index]["url"] + " has a duration of " + var.playlist[index]['duration'] + "s -- too long")
|
||||||
self.send_msg(var.config.get('strings', 'too_long'))
|
self.send_msg(var.config.get('strings', 'too_long'))
|
||||||
@ -479,6 +533,7 @@ class MumbleBot:
|
|||||||
self.send_msg(var.config.get('strings', 'unable_download'))
|
self.send_msg(var.config.get('strings', 'unable_download'))
|
||||||
|
|
||||||
if var.playlist[index]['type'] == 'url' and var.playlist[index]['ready'] == "no":
|
if var.playlist[index]['type'] == 'url' and var.playlist[index]['ready'] == "no":
|
||||||
|
# download the music
|
||||||
var.playlist[index]['ready'] = "downloading"
|
var.playlist[index]['ready'] = "downloading"
|
||||||
|
|
||||||
logging.debug("Download index:" + str(index))
|
logging.debug("Download index:" + str(index))
|
||||||
@ -512,7 +567,7 @@ class MumbleBot:
|
|||||||
|
|
||||||
logging.info("Information before start downloading :" + str(var.playlist[index]))
|
logging.info("Information before start downloading :" + str(var.playlist[index]))
|
||||||
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
|
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
|
||||||
for i in range(2):
|
for i in range(2): # Always try 2 times
|
||||||
try:
|
try:
|
||||||
ydl.extract_info(url)
|
ydl.extract_info(url)
|
||||||
if 'ready' in var.playlist[index] and var.playlist[index]['ready'] == "downloading":
|
if 'ready' in var.playlist[index] and var.playlist[index]['ready'] == "downloading":
|
||||||
@ -524,6 +579,8 @@ class MumbleBot:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def async_download_next(self):
|
def async_download_next(self):
|
||||||
|
# Function start if the next music isn't ready
|
||||||
|
# Do nothing in case the next music is already downloaded
|
||||||
logging.info("Async download next asked")
|
logging.info("Async download next asked")
|
||||||
if len(var.playlist) > 1 and var.playlist[1]['type'] == 'url' and var.playlist[1]['ready'] in ["no", "validation"]:
|
if len(var.playlist) > 1 and var.playlist[1]['type'] == 'url' and var.playlist[1]['ready'] in ["no", "validation"]:
|
||||||
th = threading.Thread(target=self.download_music, kwargs={'index': 1})
|
th = threading.Thread(target=self.download_music, kwargs={'index': 1})
|
||||||
@ -534,6 +591,7 @@ class MumbleBot:
|
|||||||
th.start()
|
th.start()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
# Parse the html from the message to get the URL
|
||||||
def get_url_from_input(string):
|
def get_url_from_input(string):
|
||||||
if string.startswith('http'):
|
if string.startswith('http'):
|
||||||
return string
|
return string
|
||||||
@ -544,15 +602,19 @@ class MumbleBot:
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Main loop of the Bot
|
||||||
def loop(self):
|
def loop(self):
|
||||||
raw_music = ""
|
raw_music = ""
|
||||||
while not self.exit and self.mumble.isAlive():
|
while not self.exit and self.mumble.isAlive():
|
||||||
|
|
||||||
while self.mumble.sound_output.get_buffer_size() > 0.5 and not self.exit:
|
while self.mumble.sound_output.get_buffer_size() > 0.5 and not self.exit:
|
||||||
|
# If the buffer isn't empty, I cannot send new music part, so I wait
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
if self.thread:
|
if self.thread:
|
||||||
|
# I get raw from ffmpeg thread
|
||||||
raw_music = self.thread.stdout.read(480)
|
raw_music = self.thread.stdout.read(480)
|
||||||
if raw_music:
|
if raw_music:
|
||||||
|
# Adjust the volume and send it to mumble
|
||||||
self.mumble.sound_output.add_sound(audioop.mul(raw_music, 2, self.volume))
|
self.mumble.sound_output.add_sound(audioop.mul(raw_music, 2, self.volume))
|
||||||
else:
|
else:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
@ -560,23 +622,29 @@ class MumbleBot:
|
|||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
if self.thread is None or not raw_music:
|
if self.thread is None or not raw_music:
|
||||||
|
# Not music into the buffet
|
||||||
if self.is_playing:
|
if self.is_playing:
|
||||||
|
# get next music
|
||||||
self.is_playing = False
|
self.is_playing = False
|
||||||
self.next()
|
self.next()
|
||||||
if len(var.playlist) > 0:
|
if len(var.playlist) > 0:
|
||||||
if var.playlist[0]['type'] in ['radio', 'file'] \
|
if var.playlist[0]['type'] in ['radio', 'file'] \
|
||||||
or (var.playlist[0]['type'] == 'url' and var.playlist[0]['ready'] not in ['validation', 'downloading']):
|
or (var.playlist[0]['type'] == 'url' and var.playlist[0]['ready'] not in ['validation', 'downloading']):
|
||||||
|
# Check if the music can be start before launch the music
|
||||||
self.launch_music()
|
self.launch_music()
|
||||||
self.async_download_next()
|
self.async_download_next()
|
||||||
|
|
||||||
while self.mumble.sound_output.get_buffer_size() > 0:
|
while self.mumble.sound_output.get_buffer_size() > 0:
|
||||||
|
# Empty the buffer before exit
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
if self.exit:
|
if self.exit:
|
||||||
|
# The db is not fixed config like url/user ban and volume
|
||||||
util.write_db()
|
util.write_db()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
# Kill the ffmpeg thread and empty the playlist
|
||||||
if self.thread:
|
if self.thread:
|
||||||
self.thread.kill()
|
self.thread.kill()
|
||||||
self.thread = None
|
self.thread = None
|
||||||
@ -587,6 +655,7 @@ class MumbleBot:
|
|||||||
self.mumble.users.myself.comment(var.config.get('bot', 'comment'))
|
self.mumble.users.myself.comment(var.config.get('bot', 'comment'))
|
||||||
|
|
||||||
def send_msg(self, msg, text=None):
|
def send_msg(self, msg, text=None):
|
||||||
|
# text if the object message, contain information if direct message or channel message
|
||||||
if not text or not text.session:
|
if not text or not text.session:
|
||||||
own_channel = self.mumble.channels[self.mumble.users.myself['channel_id']]
|
own_channel = self.mumble.channels[self.mumble.users.myself['channel_id']]
|
||||||
own_channel.send_text_message(msg)
|
own_channel.send_text_message(msg)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user