From 98f096f08fae0d2b98fbbe339c47f59a25335307 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Tue, 4 Feb 2020 18:00:11 +0800 Subject: [PATCH] add feature: read album picture from file/url --- media/playlist.py | 4 ++ mumbleBot.py | 121 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 90 insertions(+), 35 deletions(-) diff --git a/media/playlist.py b/media/playlist.py index 5b3e657..049999e 100644 --- a/media/playlist.py +++ b/media/playlist.py @@ -56,6 +56,10 @@ class PlayList: return self.playlist[self.next_index()] + def jump(self, index): + self.current_index = index + return self.playlist[index] + def clear(self): self.playlist = [] self.current_index = 0 diff --git a/mumbleBot.py b/mumbleBot.py index 17f37be..f3e0fe4 100644 --- a/mumbleBot.py +++ b/mumbleBot.py @@ -20,6 +20,7 @@ import util import base64 from PIL import Image from io import BytesIO +import mutagen from mutagen.easyid3 import EasyID3 import re import media.url @@ -37,7 +38,8 @@ type : url title path duration - thundnail + artist + thumbnail user ready (validation, no, downloading, yes) from_playlist (yes,no) @@ -53,7 +55,9 @@ type : radio type : file path title + artist duration + thumbnail user """ @@ -101,6 +105,7 @@ class MumbleBot: self.nb_exit = 0 self.thread = None self.is_playing = False + self.is_pause = False if var.config.getboolean("webinterface", "enabled"): wi_addr = var.config.get("webinterface", "listening_addr") @@ -155,8 +160,6 @@ class MumbleBot: self.mumble.channels.find_by_name(self.channel).move_in() self.mumble.set_bandwidth(200000) - self.loop() - # Set the CTRL+C shortcut def ctrl_caught(self, signal, frame): logging.info( @@ -602,10 +605,15 @@ class MumbleBot: logging.debug("Next into the queue") return var.playlist.next() - def launch_music(self): + def launch_music(self, index=-1): uri = "" - music = var.playlist.next() - logging.debug("launch_music asked" + str(music)) + music = None + if index == -1: + music = var.playlist.next() + else: + music = var.playlist.jump(index) + + logging.debug("launch_music asked" + str(music['path'])) if music["type"] == "url": # Delete older music is the tmp folder is too big media.system.clear_tmp_folder(var.config.get( @@ -619,42 +627,31 @@ class MumbleBot: self.download_music(music) if music == False: var.playlist.remove() + return - # get the Path - uri = music['path'] - if os.path.isfile(uri): - audio = EasyID3(uri) - print(audio["title"]) - title = "" - if audio["title"]: - # take the title from the file tag - title = audio["title"][0] + if self.update_music_tag_info(): + music = var.playlist.current_item() - # Remove .mp3 and add .jpg - path_thumbnail = music['path'][:-4] + '.jpg' - thumbnail_html = "" - if os.path.isfile(path_thumbnail): - # Create the image message - im = Image.open(path_thumbnail) - im.thumbnail((100, 100), Image.ANTIALIAS) - buffer = BytesIO() - im.save(buffer, format="JPEG") - thumbnail_base64 = base64.b64encode(buffer.getvalue()) - thumbnail_html = '' - - logging.debug("Thumbail data " + thumbnail_html) + thumbnail_html = '' if var.config.getboolean('bot', 'announce_current_music'): self.send_msg(var.config.get( - 'strings', 'now_playing') % (title, thumbnail_html)) - else: - logging.error("Error with the path during launch_music") - pass + 'strings', 'now_playing') % (music['title'], thumbnail_html)) elif music["type"] == "file": uri = var.config.get('bot', 'music_folder') + \ var.playlist.current_item()["path"] + if self.update_music_tag_info(uri): + music = var.playlist.current_item() + + thumbnail_html = '' + #logging.debug("Thumbnail data " + thumbnail_html) + if var.config.getboolean('bot', 'announce_current_music'): + self.send_msg(var.config.get( + 'strings', 'now_playing') % (music['title'], thumbnail_html)) + elif music["type"] == "radio": uri = music["url"] title = media.radio.get_radio_server_description(uri) @@ -744,6 +741,51 @@ class MumbleBot: break var.playlist.playlist[index] = music + def update_music_tag_info(self, uri=""): + music = var.playlist.current_item() + if not music['type'] == 'file' and not music['type'] == 'url': + return False + + # get the Path + if uri == "": + uri = music['path'] + + if os.path.isfile(uri): + music = self.get_music_tag_info(music, uri) + var.playlist.update(music) + return True + else: + logging.error("Error with the path during launch_music") + return False + + def get_music_tag_info(self, music, uri=""): + if not uri: + uri = music['path'] + + if os.path.isfile(uri): + audio = EasyID3(uri) + if audio["title"]: + # take the title from the file tag + music['title'] = audio["title"][0] + music['artist'] = ', '.join(audio["artist"]) + + path_thumbnail = uri[:-3] + "jpg" + if os.path.isfile(path_thumbnail): + im = Image.open(path_thumbnail) + im.thumbnail((100, 100), Image.ANTIALIAS) + buffer = BytesIO() + im.save(buffer, format="JPEG") + music['thumbnail'] = base64.b64encode(buffer.getvalue()).decode('utf-8') + + # try to extract artwork from mp3 ID3 tag + elif uri[-3:] == "mp3": + tags = mutagen.File(uri) + if "APIC:" in tags: + music['thumbnail'] = base64.b64encode(tags["APIC:"].data).decode('utf-8') + + return music + + def async_download_next(self): # Function start if the next music isn't ready # Do nothing in case the next music is already downloaded @@ -795,7 +837,7 @@ class MumbleBot: # get next music self.is_playing = False self.next() - if len(var.playlist.playlist) > 0: + if not self.is_pause and len(var.playlist.playlist) > 0: if var.playlist.current_item()['type'] in ['radio', 'file'] \ or (var.playlist.current_item()['type'] == 'url' and var.playlist.current_item()['ready'] not in ['validation', 'downloading']): # Check if the music can be start before launch the music @@ -819,6 +861,14 @@ class MumbleBot: var.playlist.clear() self.is_playing = False + def pause(self): + # Kill the ffmpeg thread + if self.thread: + self.thread.kill() + self.thread = None + self.is_playing = False + self.is_pause = True + def set_comment(self): self.mumble.users.myself.comment(var.config.get('bot', 'comment')) @@ -892,4 +942,5 @@ if __name__ == '__main__': var.config = config var.db = db - botamusique = MumbleBot(args) \ No newline at end of file + var.botamusique = MumbleBot(args) + var.botamusique.loop() \ No newline at end of file