voxygen.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import hashlib
  2. import os
  3. import shutil
  4. import pygame
  5. import requests
  6. import logging
  7. VOXYGEN_LANGUAGES = dict(
  8. fr=dict(electra="Electra", emma="Emma", becool="Becool", agnes="Agnes", loic="Loic", fabienne="Fabienne", helene="Helene", marion="Marion", matteo="Matteo",
  9. melodine="Melodine", mendoo="Mendoo", michel="Michel", moussa="Moussa", philippe="Philippe", sorciere="Sorciere"),
  10. ar=dict(adel="Adel"),
  11. de=dict(matthias="Matthias", jylvia="Sylvia"),
  12. uk=dict(bronwen="Bronwen", elizabeth="elizabeth", judith="Judith", paul="Paul", witch="Witch"),
  13. us=dict(bruce="Bruce", jenny="Jenny"),
  14. es=dict(martha="Martha"),
  15. it=dict(sonia="Sonia"))
  16. VOXYGEN_LANGUAGE_DEFAULT = "Michel"
  17. VOXYGEN_URL = "https://www.voxygen.fr/sites/all/modules/voxygen_voices/assets/proxy/index.php"
  18. CACHE_PATH = "/tmp/jarvis/tts/voxygen"
  19. CACHE_EXTENSION = ".tts"
  20. AUDIO_FREQUENCY = 16000
  21. AUDIO_SIZE = -16
  22. AUDIO_CHANNEL = 1
  23. AUDIO_BUFFER = 2048
  24. def say(words=None, voice=None, language="default", cache=None):
  25. voice = get_voice(voice, language)
  26. file_path = get_file_path(words, voice, language)
  27. get_audio(voice, words, file_path, cache)
  28. play_audio(file_path)
  29. remove_temp_file(file_path, cache)
  30. def get_file_path(words, voice, language):
  31. sha1 = hashlib.sha1(words).hexdigest()
  32. filename = voice + "." + sha1 + CACHE_EXTENSION
  33. cache_directory = os.path.join(CACHE_PATH, language)
  34. file_path = os.path.join(cache_directory, filename)
  35. create_directory(cache_directory)
  36. return file_path
  37. def get_voice(voice, language):
  38. if language in VOXYGEN_LANGUAGES and voice in VOXYGEN_LANGUAGES[language]:
  39. return VOXYGEN_LANGUAGES[language][voice]
  40. logging.debug("Cannot find language matching language: %s voice: %s replace by default voice: %s", language, voice, VOXYGEN_LANGUAGE_DEFAULT)
  41. return VOXYGEN_LANGUAGE_DEFAULT
  42. def get_audio(voice, text, file_path, cache):
  43. if not cache or not os.path.exists(file_path):
  44. payload = {
  45. "method": "redirect",
  46. "text": text.encode('utf8'),
  47. "voice": voice
  48. }
  49. r = requests.get(VOXYGEN_URL, params=payload, stream=True)
  50. logging.debug("Trying to get url: %s response code: %s", r.url, r.status_code)
  51. try:
  52. if r.status_code == 200:
  53. write_in_file(file_path, r.content)
  54. except IOError as e:
  55. print("I/O error(%s): %s", e.errno, e.strerror)
  56. except ValueError:
  57. print("Could not convert data to an integer.")
  58. except:
  59. print("Unexpected error: %s", sys.exc_info()[0])
  60. def play_audio(music_file, volume=0.8):
  61. try:
  62. init_player_audio(music_file, volume)
  63. logging.debug("Music file %s loaded!", music_file)
  64. except pygame.error:
  65. remove_file(music_file)
  66. logging.debug("File %s not found! (%s)", music_file, pygame.get_error())
  67. return
  68. start_player_audio()
  69. def init_player_audio(music_file, volume):
  70. pygame.mixer.init(AUDIO_FREQUENCY, AUDIO_SIZE, AUDIO_CHANNEL, AUDIO_BUFFER)
  71. pygame.mixer.music.set_volume(volume)
  72. pygame.mixer.music.load(music_file)
  73. def start_player_audio():
  74. pygame.mixer.music.play()
  75. clock = pygame.time.Clock()
  76. while pygame.mixer.music.get_busy():
  77. clock.tick(10)
  78. return
  79. def remove_temp_file(file_path, cache):
  80. if not cache:
  81. remove_file(file_path)
  82. def remove_file(file_path):
  83. if os.path.exists(file_path):
  84. os.remove(file_path)
  85. def write_in_file(file_path, content):
  86. with open(file_path, "w") as file_open:
  87. file_open.write(content)
  88. def create_directory(cache_path):
  89. if not os.path.exists(cache_path):
  90. os.makedirs(cache_path)
  91. def wipe_cache():
  92. shutil.rmtree(CACHE_PATH)