mouth.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. from .__load__ import *
  4. # 口 说话
  5. class Mouth(object):
  6. tool = {}
  7. def init(self, robot):
  8. self.robot = robot
  9. # 播放器
  10. self.speaker = None
  11. # 对话
  12. self.onSay = None
  13. return self
  14. def say(self, msg, cache=False, plugin='', completed=None):
  15. if self.onSay:
  16. self.robot.logger.info(self.log('onSay: {}'.format(msg)))
  17. if plugin != '':
  18. self.onSay("[{}] {}".format(plugin, msg))
  19. else:
  20. self.onSay(msg)
  21. self.onSay = None
  22. if plugin != '':
  23. self.robot.brain.addMemory(1, "[{}] {}".format(plugin, msg))
  24. else:
  25. self.robot.brain.addMemory(1, msg)
  26. pattern = r'^https?://.+'
  27. if re.match(pattern, msg):
  28. self.robot.logger.info(self.log('内容包含URL,无法读取'))
  29. return
  30. voice = ''
  31. self.robot.logger.info(self.log('获取文字 - ' + msg))
  32. if getCache(msg):
  33. self.robot.logger.info(self.log('命中缓存,播放缓存语音'))
  34. voice = getCache(msg)
  35. else:
  36. try:
  37. voice = self.robot.tool['tts'].tts(msg)
  38. if cache:
  39. saveCache(voice, msg)
  40. except Exception as e:
  41. self.robot.logger.error(self.log('保存缓存失败:{}'.format(e)))
  42. if completed is None:
  43. completed = lambda: self.robot.brain.doubt(msg)
  44. self.speek(voice, not cache, completed=completed)
  45. def speek(self, voice, delete=False, completed=None, volume=1):
  46. if self.speaker == None:
  47. self.speaker = Demeter.service('sox', 'player')
  48. self.speaker.init(self)
  49. self.speaker.play(voice, delete=delete, onCompleted=completed, volume=volume)
  50. def checkSpeeker(self):
  51. return self.speaker is not None and self.speaker.is_playing()
  52. # 中断、停止
  53. def close(self):
  54. if self.checkSpeeker():
  55. self.speaker.stop()
  56. #self.speaker = None
  57. def talk(self, fp, callback=None):
  58. self.speek(self.robot.data + 'beep_lo.wav')
  59. self.robot.logger.info(self.log('结束录音'))
  60. self.robot.isRecording = False
  61. if self.robot.profiling:
  62. self.robot.logger.info(self.log('性能调试已打开'))
  63. pr = cProfile.Profile()
  64. pr.enable()
  65. self.onTalk(fp, callback)
  66. pr.disable()
  67. s = io.StringIO()
  68. sortby = 'cumulative'
  69. ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
  70. ps.print_stats()
  71. print(s.getvalue())
  72. else:
  73. self.onTalk(fp, callback)
  74. def onTalk(self, fp, callback=None, onSay=None):
  75. try:
  76. self.robot.stop()
  77. query = self.robot.tool['asr'].asr(fp)
  78. File.remove(fp)
  79. self.robot.brain.think(query, callback, onSay)
  80. except Exception as e:
  81. self.robot.logger.critical(self.log(e))
  82. clean()
  83. def log(self, text):
  84. return 'Mouth:' + text