Files
opendan/src/aios_kernel/text_to_speech_function.py
T

102 lines
3.5 KiB
Python
Raw Normal View History

2023-09-21 15:52:56 +08:00
import io
import logging
import os
import random
from typing import Dict
from aios_kernel import ComputeKernel
from aios_kernel.ai_function import AIFunction
from pydub import AudioSegment
logger = logging.getLogger(__name__)
class TextToSpeechFunction(AIFunction):
def __init__(self):
self.func_id = "text_to_speech"
2023-09-22 12:22:36 +08:00
self.description = "根据输入的剧本生成音频文件,成功时会返回音频文件路径"
2023-09-21 15:52:56 +08:00
def get_name(self) -> str:
return self.func_id
def get_description(self) -> str:
return self.description
def get_parameters(self) -> Dict:
return {
"type": "object",
"properties": {
"language": {"type": "string", "description": "演播语言", "enum": ["zh", "en"]},
"roles": {"type": "array", "items": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "角色名字"},
"gender": {"type": "string", "description": "角色性别", "enum": ["man", "female"]},
"age": {"type": "string", "description": "年龄", "enum": ["child", "adult"]},
}}},
"lines": {"type": "array", "items": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "角色名字"},
"tone": {"type": "string", "description": "演播情感",
"enum": ["happy", "sad", "angry", "fear", "disgust", "surprise", "neutral"]},
"text": {"type": "string", "description": "台词"},
}
}}
}
}
async def execute(self, **kwargs) -> str:
logger.info(f"execute text_to_speech function: {kwargs}")
language = kwargs.get("language")
if language is None:
language = "zh"
roles = kwargs.get("roles")
lines = kwargs.get("lines")
audio = None
for line in lines:
name = line.get("name")
tone = line.get("tone")
text = line.get("text")
gender = None
age = None
for role in roles:
role_name = role.get("name")
if role_name == name:
gender = role.get("gender")
age = role.get("age")
break
i = 0
while i < 3:
try:
data = await ComputeKernel.get_instance().do_text_to_speech(text, language, gender, age, name, tone)
if audio is None:
audio = AudioSegment.from_mp3(io.BytesIO(data))
else:
audio = audio + AudioSegment.from_mp3(io.BytesIO(data))
break
except Exception as e:
logger.error(f"do_text_to_speech failed: {e}")
i += 1
continue
if audio is not None:
2023-09-22 00:09:21 +08:00
path = os.path.join(os.path.realpath(os.curdir), "{}.mp3".format(''.join(random.sample('zyxwvutsrqponmlkjihgfedcba', 10))))
2023-09-21 15:52:56 +08:00
audio.export(path, format="mp3")
2023-09-22 12:22:36 +08:00
return "exec text_to_speech OKspeech file store at {}".format(path)
2023-09-21 15:52:56 +08:00
else:
2023-09-22 12:22:36 +08:00
return "exec text_to_speech failed"
2023-09-21 15:52:56 +08:00
def is_local(self) -> bool:
return True
def is_in_zone(self) -> bool:
return True
def is_ready_only(self) -> bool:
return False