add feature: read album picture from file/url

This commit is contained in:
Terry Geng 2020-02-04 18:00:11 +08:00
parent 30879db7b8
commit 98f096f08f
2 changed files with 90 additions and 35 deletions

View File

@ -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

View File

@ -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 = '<img src="data:image/PNG;base64,' + \
thumbnail_base64.decode() + '"/>'
logging.debug("Thumbail data " + thumbnail_html)
thumbnail_html = '<img width="80" src="data:image/jpge;base64,' + \
music['thumbnail'] + '"/>'
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 = '<img width="80" src="data:image/jpge;base64,' + \
music['thumbnail'] + '"/>'
#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)
var.botamusique = MumbleBot(args)
var.botamusique.loop()