class SweepGui(xbmcgui.WindowXMLDialog): def __init__(self, *_args, **kwargs): self.sock = SocketCom("server") self.rec = SocketCom("sweep") self.channel = kwargs["channel"] self.count = kwargs["count"] result = self.sock.call_func("get", "eq_channel") if result is None: return self.eqid, self.name, _ = (result) self.rec.start_func_server(self) def onInit(self): self.prog1 = self.getControl(1900) self.prog2 = self.getControl(1901) self.prog1.setPercent(0.1) self.prog2.setPercent(0.1) #self.getControl(101).setLabel("%s - %s" % (self.name, tr(32410))) self.sock.call_func("play", "sweep", [self.count, self.channel]) @staticmethod def on_sound_play(nr): log("on_sound_play %s" % nr) def on_sound_stop(self): log("on_sound_stop") self.rec.stop_server() self.close() def on_chunk_play(self, c_nr, c_size, c_cnt, c_total): self.prog1.setPercent(c_cnt * 100 / (c_total - 1)) self.prog2.setPercent(c_nr * 100 / (c_size - 1)) def end_gui(self): self.sock.call_func("stop", "tone") self.sock.call_func("stop", "pulseplayer") self.rec.stop_server() self.close() def onAction(self, action): #OK pressed if action.getId() in [7, 100]: self.end_gui() #Cancel if action.getId() in [92, 10]: self.end_gui()
sys.path.append('./resources/lib/') sys.path.append('./fakekodi') from helper import SocketCom #sc = SocketCom("sound") sc = SocketCom("server") if not sc.is_server_running(): print("server is not running") sys.exit(0) try: func = sys.argv[1] if func == "exit": sc.stop_server() sys.exit(0) target = sys.argv[2] try: args = [] for arg in sys.argv[3:]: args.append(float(arg)) except Exception: args = [] except Exception: print('usage: control_sound.py "start" "tone" 1000 0.5') sys.exit(0) print(func, target, args)
class PulseInterfaceService(): def __init__(self, gid=0): self.service_owner = False self.running = False self.pulseloop = False self.gid = gid self.sock = SocketCom("server") self.q = Queue() self.mc = MessageCentral() #allow only one instance of the server if not self.sock.is_server_running(): self.start_event_loop() self.service_owner = True else: log("pase: server alreay running, don't start") #start all message loops def start_event_loop(self): self.running = True Thread(target=self.message_forward).start() Thread(target=self.start_pulse_loop).start() self.sock.start_server(self.on_socket_message) #stop all message loops def stop_event_loop(self): if self.running: self.running = False self.pulseloop = True self.q.put(('exit', '', '', None)) self.sock.stop_server() self.send_message_to_central('message', 'exit') self.pulse_event.close() # # support functions # def send_message_to_central(self, target, func, param='', conn=None): # create a new thread per message. So message_forward thread will not crash in case of message handling crash th = Thread(target=self.mc.on_message, args=(target, func, param, conn)) th.start() th.join() if conn: conn.close() # # message loops # def on_socket_message(self, conn, msg): try: func, target, args = json.loads(msg) log("pase: receive from socket: %s" % repr([func, target, args])) if target == "service" and func == "stop" and args[0] == self.gid: log("pase: stop_service received - stopping service") conn.close() self.stop_event_loop() self.q.put((target, func, args, conn)) except Exception as e: handle(e) #messages from pulse audio def pulse_event_receive(self, event): if event.facility._value in ["server", "source", "source_output"]: return self.q.put( (event.facility._value, event.t._value, [event.index], None)) #start message loop for pulse audio def start_pulse_loop(self): log("pase: start pulse loop") cnt = 1 while True: try: self.pulse_event = pulsectl.Pulse('Event Manager') log("pase: connected to pulse") cnt = 1 self.pulse_event.event_mask_set('all') self.pulse_event.event_callback_set(self.pulse_event_receive) self.send_message_to_central('pulse', 'connect') self.pulse_event.event_listen() except pulsectl.PulseDisconnected: log("pase: pulse disconnected") if not self.running: self.pulseloop = False log("pase: stop pulse loop") return except Exception as e: if cnt > 0: handle(e) logerror("pase: in event manager") cnt = cnt - 1 if not self.running: return time.sleep(0.5) # # message forward # # message from pulse may arrive to late/ quick for our message handling. # therefore collect them and process them 100ms after the last message. def message_forward(self): log("pase: start message_dispatch") timeout = None while True: try: try: target, func, param, conn = self.q.get(timeout=timeout) except Empty: # we did not receive any message since 100 ms. Send this info to # message collector. Message collector will then process the previouse # collected messages t = time.time() self.send_message_to_central('pa', 'update') timeout = None log("pase: pa_updated: time needed {:2f} ms".format( (time.time() - t) * 1000)) continue except Exception as e: handle(e) if target == "exit": break if conn is None: timeout = 0.1 self.send_message_to_central(target, func, param, conn) self.q.task_done() except Exception as e: handle(e) log("pase: stop message_dispatch")
class PaMonitor( xbmc.Monitor ): def __init__( self ): #strat process xbmc.Monitor.__init__( self ) xbmc.log("eq: start PulesEqualizer service",xbmc.LOGDEBUG) self.server_sock = SocketCom("kodi") if not self.server_sock.is_server_running(): self.server_sock.start_func_server(self) else: self.server_sock = None launcher = Launcher("menu") launcher.start() self.sock = SocketCom("server") ps = PulseService() ps.start() self.sock.call_func("set","device",[self.get_device()]) while not self.abortRequested(): if self.waitForAbort( 10 ): break launcher.stop() ps.stop() if self.server_sock: self.server_sock.stop_server() @staticmethod def get_device(): device = "" r_dict = json.loads(xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Settings.GetSettings", "params":{ "filter": {"section":"system", "category":"audio"}}, "id":1}')) for s in r_dict["result"]["settings"]: if s["id"] == "audiooutput.audiodevice": device = s["value"] break return device def on_device_get(self): result = self.get_device() xbmc.log("eq: kodi service: on_device_get %s" % result,xbmc.LOGDEBUG) return result @staticmethod def on_player_get(): r_dict = json.loads(xbmc.executeJSONRPC('{"jsonrpc":"2.0","method":"Player.GetActivePlayers","id":0}')) try: return r_dict["result"] except Exception: return None @staticmethod def on_log_write(message, level): xbmc.log(message, level) def on_service_up(self): self.sock.call_func("set","device",[self.get_device()]) def onNotification( self, _sender, method, _data ): target,func = method.lower().replace("on","").split(".") if target in ["system", "player"]: self.sock.call_func(func, target)