class MusicServer: client_list = {} root_dir = './musics' search_tool = Search() download_queue = [] def __init__(self): self.music_list = [] self.music_player = MusicPlayer() self.api_map = self.init_router() self.start_flag = False self.playing_flag = False self.play_mode = 'loop' self.current_index = -1 self.current_music = {} websocket_server = websockets.serve(self.service, '192.168.1.209', 8888) asyncio.get_event_loop().run_until_complete(websocket_server) asyncio.ensure_future(self.auto_next()) asyncio.ensure_future(self.download_task()) asyncio.get_event_loop().run_forever() async def service(self, websocket, path): client_name = self.handle_client(websocket, path) async for message in websocket: await self.router(client_name, json.loads(message)) async def router(self, client_name, request): print(f'{client_name}:{request}') await self.api_map[request['path']](request=request, client_name=client_name) async def send_response(self, path, data, client_name=None): response = json.dumps({'api': path, 'data': data}) if client_name is not None: await self.client_list[client_name].send(response) else: offline = [] for client, ws in self.client_list.items(): try: await ws.send(response) except Exception as e: print(f'{client} offline') offline.append(client) for client in offline: self.client_list.pop(client) async def get_player_info(self, **kwargs): request = kwargs['request'] data = { 'mode': self.play_mode, 'music': self.current_music, 'play_status': self.playing_flag, 'volume': self.music_player.get_music_volume() } await self.send_response(request['path'], data) async def get_local_music_list(self, **kwargs): request = kwargs['request'] self.music_list = get_local_music_list(self.root_dir) data = {'player_status': self.start_flag, 'music_list': self.music_list} send_mode = kwargs['send_mode'] if kwargs.get('send_mode') else 1 if send_mode == 1: await self.send_response(request['path'], data, kwargs['client_name']) else: await self.send_response(request['path'], data) async def search_music_list(self, **kwargs): request = kwargs['request'] search_value = request['query']['search_value'] music_list = await self.search_tool.search_song(search_value) data = {'player_status': self.start_flag, 'music_list': music_list} await self.send_response(request['path'], data, kwargs['client_name']) async def download_music(self, **kwargs): request = kwargs['request'] music = request['query']['music'] self.download_queue.append(music) await self.send_response(request['path'], self.download_queue) async def set_mode(self, **kwargs): request = kwargs['request'] self.play_mode = request['query']['mode'] await self.send_response(request['path'], {'play_mode': self.play_mode}) async def play_music(self, **kwargs): request = kwargs['request'] index = request['query']['index'] music = self.music_list[index] music_file = parse_file_path(self.root_dir, music) self.music_player.play_click(music_file) self.start_flag = True self.playing_flag = True self.current_index = index self.current_music = music await self.send_response(request['path'], music) async def pause_music(self, **kwargs): request = kwargs['request'] self.music_player.pause_click() self.playing_flag = False await self.send_response(request['path'], {'play_status': 'play'}) async def unpause_music(self, **kwargs): if not self.start_flag: await self.next_music(request={'path': 'music/next'}) else: request = kwargs['request'] self.music_player.unpause_click() self.playing_flag = True await self.send_response(request['path'], {'play_status': 'pause'}) async def pre_music(self, **kwargs): request = kwargs['request'] index = self.get_index('pre') await self.play_music(request={'path': request['path'], 'query': {'index': index}}) async def next_music(self, **kwargs): request = kwargs['request'] index = self.get_index('next') await self.play_music(request={'path': request['path'], 'query': {'index': index}}) async def set_volume(self, **kwargs): request = kwargs['request'] volume = request['query']['volume_value'] self.music_player.set_volume(round(volume/100, 2)) await self.send_response(request['path'], volume) def get_index(self, click_type): if not self.start_flag: return 0 if self.play_mode == 'loop': if click_type == 'pre': index = -1 if self.current_index == 0 else self.current_index-1 if click_type == 'next': index = 0 if self.current_index == len(self.music_list) - 1 else self.current_index + 1 elif self.play_mode == 'random': index = random.randrange(0, len(self.music_list)) return index async def auto_next(self): while True: if self.start_flag: if self.music_player.get_music_pos() == -1: await self.next_music(request={'path': 'music/next'}) await asyncio.sleep(1) async def download_task(self): while True: if len(self.download_queue) >= 1: task_wait = self.download_queue[0] ret = await download_mp3(task_wait) self.download_queue.remove(task_wait) await self.send_response('music/download', self.download_queue) if ret['code'] == 1: await self.get_local_music_list(request={'path': 'music/local'}, send_mode='2') await self.send_response('music/msg', ret['msg']) else: await asyncio.sleep(1) def init_router(self): return { 'music/playerInfo': self.get_player_info, 'music/local': self.get_local_music_list, 'music/search': self.search_music_list, 'music/download': self.download_music, 'music/playMode': self.set_mode, 'music/play': self.play_music, 'music/pause': self.pause_music, 'music/unpause': self.unpause_music, 'music/pre': self.pre_music, 'music/next': self.next_music, 'music/volume': self.set_volume } def handle_client(self, ws, path): client_name = path.replace('/', '') self.client_list[client_name] = ws return client_name
class MusicScreen(Screen): ''' Shows the popup to choose the file to play ''' '''def show_load(self): content = LoadDialog(load=self.load, cancel=self.dismiss_popup) self._popup = Popup(title="Load file", content=content, size_hint=(0.9, 0.9)) self._popup.open() def dismiss_popup(self): self._popup.dismiss()''' def __init__(self, **kwargs): super(MusicScreen, self).__init__(**kwargs) #self.library_manager = LibraryManager() self.player = MusicPlayer() # # Getting the layout to dinamically add the buttons #ml_list_view = self.ids.ml_list_view # adding files to library #songs = self.library_manager.parse_library() # for song in songs: # btn = Button(text=os.path.basename(song), font_size=14)# , on_press=self.play_station(radio) # #btn.bind(on_press=self.pressed) # #btn.bind(on_press=self.play_station) # ml_layout.add_widget(btn) # list_adapter = ListAdapter(data=songs, cls=ListItemButton, selection_mode='single') # list_adapter.bind(on_selection_change=self.selection_change) # ml_list_view.adapter = list_adapter # songs_text = '' # for song in songs: # songs_text = songs_text + song # library_text.text = songs_text#''.join('aaaa ').join('bbbb')#, 'and something else') #library_text.text = library_text.text.join('bbbb') def selection_change(self, adapter, *args): print "selection changed" def load(self, path, filename): pass #self.player.stop_audio() self.player.load_audio(filename[0]) #self.dismiss_popup() '''Playing or pausing a song. 1) If stopped play it again from the 'elapsed' value. If it's 0 play it from the beginning. 2) If it's playing store the elapsed time and stop the song. ''' def play_pause_audio(self): pass self.player.play_pause_audio() def pause_audio(self): pass self.player.pause_audio() def play_audio(self): pass self.player.play_audio() ''' Stopping the song. 1) self.elapsed set to 0 so the next song (or the same) will be played from the beginning 2) actually stop the song ''' def stop_audio(self): pass self.player.stop_audio() ''' Reloading the song if it's currently playing. Just call self.stop_song and then self.play_pause_song ''' def reload_audio(self): pass self.player.reload_audio() ''' Setting the volume. When the value of the slider is changed, this will affect the volume of the played song. ''' def set_volume(self, value): pass self.player.set_volume(value)
class MusicServer: client_list = {} root_dir = './musics' search_tool = Search() download_queue = [] def __init__(self): # 0是全部列表 self.current_menu_id = 0 self.music_list = [] self.music_player = MusicPlayer() self.album_manager = InstanceAsyncAlbumManager self.api_map = self.init_router() self.start_flag = False self.playing_flag = False self.play_mode = 'loop' self.current_index = -1 self.current_music = {} websocket_server = websockets.serve(self.service, '0.0.0.0', 8888) asyncio.get_event_loop().run_until_complete(websocket_server) asyncio.ensure_future(self.auto_next()) asyncio.ensure_future(self.download_task()) asyncio.get_event_loop().run_forever() async def service(self, websocket, path): client_name = self.handle_client(websocket, path) async for message in websocket: await self.router(client_name, json.loads(message)) async def router(self, client_name, request): print(f'{client_name}:{request}') await self.api_map[request['path']](request=request, client_name=client_name) async def send_response(self, path, data, client_name=None): response = json.dumps({'api': path, 'data': data}) if client_name: await self.client_list[client_name].send(response) else: offline = [] for client, ws in self.client_list.items(): try: await ws.send(response) except: print(f'{client} offline') offline.append(client) for client in offline: self.client_list.pop(client) async def get_player_info(self, **kwargs): request = kwargs['request'] data = { 'mode': self.play_mode, 'music': self.current_music, 'play_status': self.playing_flag, 'volume': self.music_player.get_music_volume(), 'menu_list': await self.album_manager.get_album_list(), 'current_menu': self.album_manager.current_album_id } await self.send_response(request['path'], data) async def get_all_songs(self, **kwargs): self.current_menu_id = 0 request = kwargs['request'] self.music_list = await self.album_manager.all_songs() data = { 'player_status': self.start_flag, 'music_list': self.music_list } # send_mode = kwargs['send_mode'] if kwargs.get('send_mode') else 1 await self.send_response(request['path'], data, kwargs['client_name']) async def get_menu_songs(self, **kwargs): request = kwargs['request'] album_id = request['query']['menu_id'] # self.current_menu_id = menu_id music_list = await self.album_manager.get_album_songs(album_id) data = {'menu_id': album_id, 'music_list': music_list} await self.send_response(request['path'], data, kwargs['client_name']) async def search_music_list(self, **kwargs): request = kwargs['request'] search_value = request['query']['search_value'] music_list = await self.search_tool.search_song(search_value) data = {'player_status': self.start_flag, 'music_list': music_list} await self.send_response(request['path'], data, kwargs['client_name']) async def download_music(self, **kwargs): request = kwargs['request'] music = request['query']['music'] self.download_queue.append(music) await self.send_response(request['path'], self.download_queue) async def set_mode(self, **kwargs): request = kwargs['request'] self.play_mode = request['query']['mode'] await self.send_response(request['path'], {'play_mode': self.play_mode}) # 前端回传song_id 和 album_id async def play_music(self, **kwargs): if not self.start_flag: await self.send_response( 'music/volume', self.music_player.get_music_volume() * 100) request = kwargs['request'] index = request['query']['index'] song_id = request['query']['song_id'] album_id = request['query'].get('album_id', 0) song = await self.album_manager.set_current_song(song_id) print(song) # 设置歌单 await self.album_manager.set_current_play_list(album_id) self.album_manager.set_current_album_id(album_id) self.album_manager.set_next_song() music_file = parse_file_path(self.root_dir, song) # music = await self.album_manager.get_song_info(self.current_menu_id, song_id) self.music_player.play_click(music_file) self.start_flag = True self.playing_flag = True self.current_index = index self.current_music = song # self.album_manager.set_current_album_id(album_id) song["album_id"] = album_id await self.send_response(request['path'], song) async def pause_music(self, **kwargs): request = kwargs['request'] self.music_player.pause_click() self.playing_flag = False await self.send_response(request['path'], {'play_status': 'play'}) async def unpause_music(self, **kwargs): if not self.start_flag: await self.next_music(request={'path': 'music/next'}) else: request = kwargs['request'] self.music_player.unpause_click() self.playing_flag = True await self.send_response(request['path'], {'play_status': 'pause'}) async def pre_music(self, **kwargs): request = kwargs['request'] index = self.get_index('pre') await self.play_music(request={ 'path': request['path'], 'query': { 'index': index } }) async def next_music(self, **kwargs): request = kwargs['request'] # index = self.get_index('next') song = self.album_manager.next_song if self.play_mode == "loop" else self.album_manager.get_random_song( ) print(song) # index的逻辑没有动 await self.play_music( request={ 'path': request['path'], 'query': { 'index': 0, 'song_id': song['song_id'], 'album_id': self.album_manager.current_album_id } }) async def set_volume(self, **kwargs): request = kwargs['request'] volume = request['query']['volume_value'] self.music_player.set_volume(volume / 100) await self.send_response(request['path'], volume) async def add_menu(self, **kwargs): request = kwargs['request'] menu_name = request['query']['menu_name'] await self.album_manager.add_album(menu_name, '') await self.send_response(request['path'], await self.album_manager.get_album_list()) async def add_song_to_menu(self, **kwargs): request = kwargs['request'] menu_id = request['query']['menu_id'] song = request['query']['song'] await self.album_manager.add_album_song(menu_id, song) async def del_song_from_menu(self, **kwargs): request = kwargs['request'] song = request['query']['song'] await self.album_manager.del_album_song(song['album_id'], song['song_id']) self.music_list = await self.album_manager.get_album_songs( song['album_id']) await self.get_menu_songs(request={ 'path': 'music/menu', 'query': { 'menu_id': song['album_id'] } }) def get_index(self, click_type): index = 0 if not self.start_flag: return index if self.play_mode == 'loop': if click_type == 'pre': index = -1 if self.current_index == 0 else self.current_index - 1 if click_type == 'next': index = 0 if self.current_index == len( self.music_list) - 1 else self.current_index + 1 elif self.play_mode == 'random': index = random.randrange(0, len(self.music_list)) return index async def auto_next(self): while True: if self.start_flag: if self.music_player.get_music_pos() == -1: await self.next_music(request={'path': 'music/next'}) await asyncio.sleep(1) async def download_task(self): while True: if len(self.download_queue) >= 1: task_wait = self.download_queue[0] ret = await download_mp3(task_wait) self.download_queue.remove(task_wait) await self.send_response('music/download', self.download_queue) if ret['code'] == 1: await self.album_manager.add_song(ret['song']) await self.send_response('music/msg', ret['msg']) else: await asyncio.sleep(1) def init_router(self): return { 'music/playerInfo': self.get_player_info, 'music/local': self.get_all_songs, 'music/menu': self.get_menu_songs, 'music/search': self.search_music_list, 'music/download': self.download_music, 'music/playMode': self.set_mode, 'music/play': self.play_music, 'music/pause': self.pause_music, 'music/unpause': self.unpause_music, 'music/pre': self.pre_music, 'music/next': self.next_music, 'music/volume': self.set_volume, 'music/menu/add': self.add_menu, 'music/menu/add/song': self.add_song_to_menu, 'music/menu/del/song': self.del_song_from_menu, } def handle_client(self, ws, path): client_name = path.replace('/', '') self.client_list[client_name] = ws return client_name
async def on_message(message: Message): if message.author.id == bot.user.id: return control_channel = get_bot_control_channel(message.server.channels) if not control_channel: return if control_channel.id != message.channel.id: return if not message.content: await bot.delete_message(message) return content = message.content.split(' ') command = content[0].lower() if len(content) > 1: args = content[1:] else: args = None if message.channel.is_private: if command != 'help': await bot.send_message( message.author, "I didn't get that. But there are available commands:") await bot.send_message(message.author, help_message) return m_player = bot.music_players.get(message.server.id, None) user_voice_channel = message.author.voice.voice_channel bot_voice_channel = bot.voice_channels.get(message.server.id, None) if command == 'summon' or command == 'summoning jutsu': if user_voice_channel: if m_player: await m_player.voice_client.disconnect() m_player.voice_client = await bot.join_voice_channel( user_voice_channel) else: voice_client = await bot.join_voice_channel(user_voice_channel) m_player = MusicPlayer( voice_client, next_song_event_generator(control_channel), settings.MUSIC_DIRECTORY, settings.DEFAULT_VOLUME) bot.music_players.update({message.server.id: m_player}) bot.voice_channels.update( {message.server.id: user_voice_channel}) username = message.author.nick if message.author.nick else message.author.name await bot.send_message(control_channel, 'At your service, sir {}.'.format(username)) else: await bot.send_message(control_channel, 'Unable to join: unknown voice channel!') elif command == 'help': await bot.send_message(message.author, help_message) elif command == 'clear_messages': if not message.author.permissions_in(control_channel).manage_messages: return await bot.purge_from(control_channel, limit=50) elif command == 'update_songs': if not message.author.permissions_in(control_channel).manage_messages: return m_player.update_songs() elif m_player and user_voice_channel == bot_voice_channel: if command == 'bye': await bot.disconnect_from_server(message.server.id) elif command == 'play': success = await m_player.play() if not success: await incorrect_message(message) elif command == 'seek' and args: await m_player.seek(args[0]) elif command == 'volume': if args: success = m_player.set_volume(args[0]) if not success: await incorrect_message(message) else: await bot.send_message( control_channel, 'New volume is {}%'.format(m_player.get_volume())) else: await bot.send_message( control_channel, 'Current volume is {}%'.format(m_player.get_volume())) elif command == 'pause': m_player.pause() elif command == 'stop': await bot.change_presence(game=discord.Game( name='v. {}'.format(settings.BOT_VERSION))) m_player.reset_player() elif command == 'next': await m_player.play_next_song() elif command == 'prev': await m_player.play_previous_song() elif command == 'add' and args: success = m_player.add_to_playlist(args[0]) if not success: await incorrect_message(message) elif command == 'delete': if args: song = await m_player.delete_from_playlist(args[0]) else: song = await m_player.delete_from_playlist() if not song: await incorrect_message(message) else: # todo: execute playlist command here await bot.send_message( control_channel, '***{}.** {} was deleted from playlist!*'.format( args[0], song.title)) elif command == 'playlist': plist_msg = '' i = 1 for song_title in m_player.get_playlist_titles(): if m_player.current_song_id == i - 1: song_title = '**' + song_title + '**' else: song_title = '*' + song_title + '*' plist_msg += '**{}**. {}\n'.format(i, song_title) i += 1 if plist_msg: await bot.send_message(control_channel, plist_msg) else: await bot.send_message(control_channel, '*The playlist is empty!*') elif command == 'select' and args: try: await m_player.select_song(args[0]) except Exception: await incorrect_message(message) else: await incorrect_message(message) else: await incorrect_message(message)
class Bot(commands.Bot): def __init__( self, spam_time=600, spam_messages=[], custom_rewards=[], tts_engine=None, greeting_message='' ): super().__init__( irc_token=os.environ.get('TMI_TOKEN'), client_id=os.environ.get('CLIENT_ID'), nick=os.environ.get('BOT_NICK'), prefix=os.environ.get('BOT_PREFIX'), initial_channels=[os.environ.get('CHANNEL')], client_secret=os.environ.get('CLIENT_SECRET')) self.user_id = os.environ.get('TWITCH_USER_ID') self.ignore_users = [self.nick] self.only_owner_commands = ['dtts', 'atts'] self.only_mod_commands = ['vol', 'next', 'stop'] self.owner_nick = os.environ.get('CHANNEL').replace('#', '').lower() self.spam_time = spam_time self.spam_messages = spam_messages self.chatters_list = [] self.custom_rewards = custom_rewards self.greeting_message = greeting_message self.riot_api = RiotAPI() self.cats_api = CatsAPI() self.tts_engine = tts_engine self.music_player = MusicPlayer(os.environ.get('DOWNLOADS_PATH')) self.music_dl = MusicDL(download_path=os.environ.get('DOWNLOADS_PATH')) async def event_ready(self): print(f'{self.nick} is ready') if len(self.spam_messages) > 0: await self.spam() async def event_command_error(self, message, ex): if ex.__class__ is CommandNotFound: await send_exception(message, 'No se reconoce el comando. Usa !c para ver todos los comandos.') return await send_exception(message, ex) async def event_raw_usernotice(self, channel, tags): print(tags) async def event_message(self, message): try: if message.author.name.lower() in self.ignore_users: return if message.author.name.lower() not in self.chatters_list: await message.channel.send(self.greeting_message.format(message.author.name)) self.chatters_list.append(message.author.name) await self.handle_commands(message) await self.handle_custom_rewards(message) except Exception as ex: print(ex) async def handle_custom_rewards(self, message): try: reward_id = message.tags.get("custom-reward-id", None) if not reward_id: return if reward_id not in self.custom_rewards: return reward_action = self.custom_rewards[reward_id] if type(reward_action) == str: return reward_action(message) except Exception as ex: print(ex) async def spam(self): channel = self.get_channel(self.owner_nick) while True: await asyncio.sleep(self.spam_time) selected_message = random.choice(self.spam_messages) await channel.send(selected_message) @commands.command(name='michi') async def cat(self, message): try: cat_url = self.cats_api.get_random_cat() await message.channel.send(f'{message.author.name}, disfruta tu michi {cat_url}') except RandomCatException as ex: await self.send_exception(message, ex) except Exception as ex: print(ex) @commands.command(name='redes') async def social_media(self, message): try: social_media = [ 'https://twitter.com/Luis_LiraC', 'https://www.youtube.com/c/luislira', 'https://www.instagram.com/luislirac/', ] response = 'Me puedes seguir en:\n' + '\n'.join(social_media) await message.channel.send(response) except Exception as ex: print(ex) @commands.command(name='mt') async def mastery(self, message): try: result = self.riot_api.get_mastery_info(message.message.content) await message.channel.send(f"""{message.author.name}. Tengo {result['points']} puntos de maestrÃa con {result['name']}. La última vez que lo jugué fue en {result['date']} """) except ChampionException as ex: await send_exception(message, ex) except NotPlayedException as ex: await send_exception(message, ex) except Exception as ex: print(ex) @commands.command(name='c') async def cmd(self, message): try: keys = list(map(lambda c: f'!{c}' if c not in self.only_owner_commands and c not in self.only_mod_commands else '', [ *self.commands.keys()])) if message.author.is_mod: for c in self.only_mod_commands: keys.append(f'{c}') response = f'{message.author.name} Puedes usar estos comandos:\n' + \ '\n'.join(keys) await message.channel.send(response) except Exception as ex: print(ex) @commands.command(name='followage') async def follow_age(self, message): try: follower_name = message.author.name.lower() followers_list = await self.get_followers(self.user_id) follow_date = None for follower in followers_list: if follower['from_name'].lower() == follower_name: follow_date = follower['followed_at'] break if follow_date is None: await message.channel.send(f'{follower_name}, no me sigues :(') return utc_date = datetime.strptime(follow_date, '%Y-%m-%dT%H:%M:%SZ') date = utc_date.replace(tzinfo=timezone.utc).astimezone(tz=None) now = datetime.utcnow().replace(tzinfo=timezone.utc).astimezone(tz=None) following_days = (now - date).days if following_days == 1 or following_days == 0: await message.channel.send(f'{follower_name}, tienes 1 dÃa siguiéndome. Muchas gracias 🥳') elif following_days > 1: await message.channel.send(f'{follower_name}, tienes {following_days} dÃas siguiéndome. Muchas gracias 🥳') except Exception as ex: print(ex) @commands.command(name='atts') async def activate_tts(self, message): if self.tts_engine is None: return if message.author.name.lower() == self.owner_nick: self.tts_engine.activate() @commands.command(name='dtts') async def deactivate_tts(self, message): if self.tts_engine is None: return if message.author.name.lower() == self.owner_nick: self.tts_engine.deactivate() @commands.command(name='bonk') async def bonk(self, message): playsound('./sounds/bonk.mp3') @commands.command(name='sr') async def song_request(self, message): try: user_input = message.content.replace('!sr', '').strip() if user_input == '': raise NotResultsException song_reference = self.music_dl.download(user_input) if song_reference is None: raise NotResultsException song_name = self.music_dl.get_song_name(song_reference) await self.music_player.add_to_playlist(song_reference, message, song_name) except MaxDurationException as ex: await send_exception(message, ex) except NotResultsException as ex: await send_exception(message, ex) except Exception as ex: print('----------') print(ex) print('----------') # I needed to do this because only this "fix" a weird bug # When the player stop and then play music again the volume change to -1 and it ignore every # validation that I do to change it again to the initial volume self.music_player = MusicPlayer(os.environ.get('DOWNLOADS_PATH')) print(f'[Music Player Restarted at {datetime.now()}]') print('----------') @commands.command(name='next') async def next_song(self, message): try: if message.author.is_mod: await self.music_player.next() except Exception as ex: print(ex) @commands.command(name='vol') async def volume(self, message): try: if message.author.is_mod: volume = message.content.replace('!vol ', '').strip() self.music_player.set_volume(volume) except Exception as ex: print(ex) @commands.command(name='currentsong') async def currentsong(self, message): try: reference = self.music_player.get_song_reference() song_name = self.music_dl.get_song_name(reference) if song_name is not None: await message.channel.send(f'{message.author.name}. La canción es: {song_name}') except Exception as ex: print(ex) @commands.command(name='stop') async def stop(self, message): try: if message.author.is_mod: self.music_player.stop() except Exception as ex: print(ex)
class MusicWorker(Worker): def __init__(self, holder): super().__init__(holder) random.seed() self._config = Config() self._player = MusicPlayer() self._load_config() def on_connect(self, client, userdata, flags): super().on_connect(client, userdata, flags) client.subscribe(MUSIC_TOPIC_SUBSCRIBE) def on_message(self, client, userdata, msg): super().on_message(client, userdata, msg) payload = msg.payload.decode('UTF-8') if msg.topic.startswith(MUSIC_TOPIC_ROOT): command = msg.topic.rsplit("/", 1)[-1] if command == 'play': mp3_file = payload result = self._play_music(mp3_file) client.publish(msg.topic + '/reply', payload=result, qos=1) elif command == 'stop': self._stop_music() elif command == 'play_random_one': self._play_random_one() elif command == 'list_music': mp3_list = self._get_mp3_list() file_list = [mp3.rsplit('/', 1)[-1] for mp3 in mp3_list] client.publish(msg.topic + '/reply', payload='{}:{}'.format(payload, ','.join(file_list)), qos=1, retain=True) elif command == 'get_volume': volume = self._get_volume() client.publish(msg.topic + '/reply', payload='{}'.format(volume), qos=1, retain=True) elif command == 'set_volume': result = self._set_volume(payload) client.publish(msg.topic + '/reply', payload=result, qos=1) if result == 'ok': client.publish(MUSIC_TOPIC_ROOT + 'get_volume/reply', payload='{}'.format(payload), qos=1, retain=True) def _play_music(self, mp3_file=None, remote_command=True): self._stop_music() result = 'ok' if mp3_file is None or len(mp3_file) == 0: self._player.play(SAFE_MP3) result = 'ok' elif remote_command: if mp3_file.find('..') != -1 or mp3_file.find( '/') != -1 or mp3_file.find('\\') != -1: # bad guy self._player.play(SAFE_MP3) result = 'File not exist!' else: full_path = '{}/{}'.format(self._config.mp3_folder, mp3_file) if os.path.isfile(full_path): self._player.play(full_path) result = 'ok' else: self._player.play(SAFE_MP3) result = 'File not exist!' else: self._player.play(mp3_file) result = 'ok' return result def _stop_music(self): self._player.stop() def _get_mp3_list(self): mp3_list = glob.glob('{}/*.[mM][pP]3'.format(self._config.mp3_folder)) return mp3_list def _play_random_one(self): mp3_list = self._get_mp3_list() mp3_file = random.choice(mp3_list) print('Playing: {}'.format(mp3_file)) self._play_music(mp3_file, remote_command=False) def _get_volume(self): return self._player.get_volume() def _set_volume(self, volume): v = -1 try: v = int(volume) except: pass if v >= 0 and v <= 100: self._player.set_volume(v) self._music_config.volume = v self._save_config() return 'ok' else: return 'volume is valid!' def _save_config(self): with open(MUSIC_SAVE_FILE, 'wb') as f: pickle.dump(self._music_config, f) def _load_config(self): self._music_config = None if os.path.isfile(MUSIC_SAVE_FILE): try: with open(MUSIC_SAVE_FILE, 'rb') as f: self._music_config = pickle.load(f) except: pass if self._music_config is None: self._music_config = MusicConfig() print('Volume:', self._music_config.volume) self._player.set_volume(self._music_config.volume) def pause(self): self._player.pause() # 为了解决 alarm 设置不了音量的问题 # 也不彻底,先这样了! self._player.set_volume(100) def resume(self): self._player.resume() # 为了解决 alarm 设置不了音量的问题 # 也不彻底,先这样了! self._player.set_volume(self._music_config.volume)