You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ali_voice.py 2.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. # -*- coding: utf-8 -*-
  2. """
  3. Author: chazzjimel
  4. Email: chazzjimel@gmail.com
  5. wechat:cheung-z-x
  6. Description:
  7. ali voice service
  8. """
  9. import json
  10. import os
  11. import re
  12. import time
  13. from bridge.reply import Reply, ReplyType
  14. from common.log import logger
  15. from voice.voice import Voice
  16. from voice.ali.ali_api import AliyunTokenGenerator
  17. from voice.ali.ali_api import text_to_speech_aliyun
  18. def textContainsEmoji(text):
  19. # 此正则表达式匹配大多数表情符号和特殊字符
  20. pattern = re.compile(
  21. '[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\U0001F700-\U0001F77F\U0001F780-\U0001F7FF\U0001F800-\U0001F8FF\U0001F900-\U0001F9FF\U0001FA00-\U0001FA6F\U0001FA70-\U0001FAFF\U00002702-\U000027B0\U00002600-\U000026FF]')
  22. return bool(pattern.search(text))
  23. class AliVoice(Voice):
  24. def __init__(self):
  25. try:
  26. curdir = os.path.dirname(__file__)
  27. config_path = os.path.join(curdir, "config.json")
  28. with open(config_path, "r") as fr:
  29. config = json.load(fr)
  30. self.token = None
  31. self.token_expire_time = 0
  32. self.api_url = config.get("api_url")
  33. self.appkey = config.get("appkey")
  34. self.access_key_id = config.get("access_key_id")
  35. self.access_key_secret = config.get("access_key_secret")
  36. except Exception as e:
  37. logger.warn("AliVoice init failed: %s, ignore " % e)
  38. # def voiceToText(self, voice_file):
  39. # pass
  40. def textToVoice(self, text):
  41. text = re.sub(r'[^\u4e00-\u9fa5\u3040-\u30FF\uAC00-\uD7AFa-zA-Z0-9'
  42. r'äöüÄÖÜáéíóúÁÉÍÓÚàèìòùÀÈÌÒÙâêîôûÂÊÎÔÛçÇñÑ,。!?,.]', '', text)
  43. # 提取 token_id 值
  44. token_id = self.get_valid_token()
  45. fileName = text_to_speech_aliyun(self.api_url, text, self.appkey, token_id)
  46. if fileName:
  47. logger.info("[Ali] textToVoice text={} voice file name={}".format(text, fileName))
  48. reply = Reply(ReplyType.VOICE, fileName)
  49. else:
  50. reply = Reply(ReplyType.ERROR, "抱歉,语音合成失败")
  51. return reply
  52. def get_valid_token(self):
  53. current_time = time.time()
  54. if self.token is None or current_time >= self.token_expire_time:
  55. get_token = AliyunTokenGenerator(self.access_key_id, self.access_key_secret)
  56. token_str = get_token.get_token()
  57. token_data = json.loads(token_str)
  58. self.token = token_data["Token"]["Id"]
  59. # 将过期时间减少一小段时间(例如5分钟),以避免在边界条件下的过期
  60. self.token_expire_time = token_data["Token"]["ExpireTime"] - 300
  61. logger.debug(f"新获取的阿里云token:{self.token}")
  62. else:
  63. logger.debug("使用缓存的token")
  64. return self.token