voxygen.py 2.9 KB

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