voxygen.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import os
  2. import requests
  3. import logging
  4. import sys
  5. from core import AudioPlayer
  6. from core import FileManager
  7. from tts import TTS
  8. logging.basicConfig()
  9. logger = logging.getLogger("jarvis")
  10. class Voxygen(TTS):
  11. VOXYGEN_LANGUAGES = dict(
  12. fr=dict(electra="Electra", emma="Emma", becool="Becool", agnes="Agnes", loic="Loic", fabienne="Fabienne", helene="Helene", marion="Marion",
  13. matteo="Matteo",
  14. melodine="Melodine", mendoo="Mendoo", michel="Michel", moussa="Moussa", philippe="Philippe", sorciere="Sorciere"),
  15. ar=dict(adel="Adel"),
  16. de=dict(matthias="Matthias", jylvia="Sylvia"),
  17. uk=dict(bronwen="Bronwen", elizabeth="elizabeth", judith="Judith", paul="Paul", witch="Witch"),
  18. us=dict(bruce="Bruce", jenny="Jenny"),
  19. es=dict(martha="Martha"),
  20. it=dict(sonia="Sonia"))
  21. VOXYGEN_VOICE_DEFAULT = "Michel"
  22. VOXYGEN_LANGUAGES_DEFAULT = "default"
  23. VOXYGEN_URL = "https://www.voxygen.fr/sites/all/modules/voxygen_voices/assets/proxy/index.php"
  24. VOXYGEN_CONTENT_TYPE = "audio/mpeg"
  25. VOXYGEN_TIMEOUT_SEC = 30
  26. def __init__(self):
  27. TTS.__init__(self, AudioPlayer.PLAYER_MP3, cache_extension="tts")
  28. def say(self, words=None, voice=None, language=VOXYGEN_LANGUAGES_DEFAULT, cache=True):
  29. voice = self.get_voice(voice, language)
  30. file_path = self.cache.get_audio_file_cache_path(words, voice, language)
  31. if self.get_audio(voice, words, file_path, cache):
  32. self.play_audio(file_path)
  33. self.cache.remove_audio_file(file_path, cache)
  34. def get_voice(self, voice, language):
  35. if language in self.VOXYGEN_LANGUAGES and voice in self.VOXYGEN_LANGUAGES[language]:
  36. return self.VOXYGEN_LANGUAGES[language][voice]
  37. logger.warn("Cannot find language matching language: %s voice: %s replace by default voice: %s", language, voice, self.VOXYGEN_VOICE_DEFAULT)
  38. return self.VOXYGEN_VOICE_DEFAULT
  39. def get_audio(self, voice, words, file_path, cache):
  40. if not cache or not os.path.exists(file_path) or FileManager.file_is_empty(file_path):
  41. payload = {
  42. "method": "redirect",
  43. "text": words.encode('utf8'),
  44. "voice": voice
  45. }
  46. r = requests.get(self.VOXYGEN_URL, params=payload, stream=True, timeout=self.VOXYGEN_TIMEOUT_SEC)
  47. content_type = r.headers['Content-Type']
  48. logger.debug("Trying to get url: %s response code: %s and content-type: %s", r.url, r.status_code, content_type)
  49. try:
  50. if r.status_code == requests.codes.ok and content_type == self.VOXYGEN_CONTENT_TYPE:
  51. return FileManager.write_in_file(file_path, r.content)
  52. else:
  53. return False
  54. except IOError as e:
  55. logger.error("I/O error(%s): %s", e.errno, e.strerror)
  56. except ValueError:
  57. logger.error("Could not convert data to an integer.")
  58. except:
  59. logger.error("Unexpected error: %s", sys.exc_info()[0])
  60. else:
  61. return True