# -*- coding: utf-8 -*- from __future__ import division from .__load__ import * from snowboy import snowboydecoder class Snowboy(object): def init(self, robot): self.bother = False self.robot = robot self.detector = None self.interrupted = False self.data = File.runtime('data') if self.detector is not None: self.detector.terminate() # snowboy配置,后续改成从数据库读取 snowboyConfig = Demeter.config['snowboy'] if snowboyConfig['hotword_switch'] == True: models = [ self.data + snowboyConfig['hotword'], self.data + snowboyConfig['on_hotword'], self.data + snowboyConfig['off_hotword'] ] else: models = self.data + snowboyConfig['hotword'] self.detector = snowboydecoder.HotwordDetector(models, sensitivity=snowboyConfig['sensitivity']) # main loop try: if snowboyConfig['hotword_switch'] == True: callbacks = [self.detectedCallback, self.onHotwordCallback, self.offHotwordCallback] else: callbacks = self.detectedCallback self.detector.start(detected_callback=callbacks, audio_recorder_callback=self.robot.converse, interrupt_check=self.interruptCallback, silent_count_threshold=int(snowboyConfig['silent_threshold']), recording_timeout=int(snowboyConfig['recording_timeout']) * 4, sleep_time=0.03) self.detector.terminate() except Exception as e: Demeter.logger.critical('离线唤醒机制初始化失败:{}'.format(e)) def stop(self): self.interrupted = True def detectedCallback(self): if not self.isProperTime(): Demeter.logger.warning('勿扰模式开启中') return if self.robot.isRecording: Demeter.logger.warning('正在录音中,跳过') return Player.play(self.data + 'beep_hi.wav') Demeter.logger.info('开始录音') self.robot.interrupt() self.robot.isRecording = True; def onHotwordCallback(self): if snowboyConfig['hotword_switch'] == True: self.bother = True Player.play(self.data + 'off.wav') Demeter.logger.info('勿扰模式打开') def offHotwordCallback(self): if snowboyConfig['hotword_switch'] == True: self.bother = False Player.play(self.data + 'on.wav') Demeter.logger.info('勿扰模式关闭') def interruptCallback(self): return self.interrupted def isProperTime(): if self.bother == True: return False if 'bother_enable' not in Demeter.config['snowboy']: return True if Demeter.config['snowboy']['bother_enable'] == False: return True if 'bother_since' not in Demeter.config['snowboy'] or 'bother_till' not in Demeter.config['snowboy']: return True since = Demeter.config['snowboy']['bother_since'] till = Demeter.config['snowboy']['bother_till'] current = time.localtime(time.time()).tm_hour if till > since: return current not in range(since, till) else: return not (current in range(since, 25) or current in range(-1, till))