"""
title: Aliyun CosyVoice TTS
description: 使用阿里云CosyVoice进行文本到语音转换
author: [Your Name]
version: 0.1.0
category: tts
input_type: text
output_type: audio
"""
import asyncio
import json
import uuid
import os
import websockets
from pydantic import BaseModel, Field
from typing import Callable, Union, Any, Dict, Tuple
from config import UPLOAD_DIR
from apps.webui.models.files import Files
class Action:
class Valves(BaseModel):
ALIYUN_APPKEY: str = Field(
default=None, description="Your Aliyun AppKey."
)
ALIYUN_TOKEN: str = Field(
default=None, description="Your Aliyun Token."
)
DEFAULT_VOICE: str = Field(
default="xiaoyun", description="Default voice to use."
)
def __init__(self):
self.valves = self.Valves()
async def text_to_speech(self, text: str, voice: str = None) -> Dict[str, Any]:
if not text:
raise ValueError("No text provided for TTS conversion.")
if not self.valves.ALIYUN_APPKEY or not self.valves.ALIYUN_TOKEN:
raise ValueError("Aliyun AppKey and Token must be set in the plugin settings.")
voice = voice or self.valves.DEFAULT_VOICE
try:
audio_data = await self._generate_audio(text, voice)
file_name = f"{uuid.uuid4()}.wav"
file_path = self._create_file(file_name, f"CosyVoice TTS - {voice}", audio_data, "audio/wav")
file_url = self._get_file_url(file_path)
return {
"type": "audio",
"url": file_url,
"title": f"CosyVoice TTS - {voice}"
}
except Exception as e:
raise Exception(f"生成音频时发生错误: {str(e)}")
async def _generate_audio(self, text: str, voice: str) -> bytes:
# ... (保持原有的_generate_audio方法不变)
def _create_file(self, file_name: str, title: str, content: Union[str, bytes],
content_type: str) -> str:
# ... (保持原有的_create_file方法不变,但移除__user__参数)
def _get_file_url(self, file_id: str) -> str:
# ... (保持原有的_get_file_url方法不变)
async def get_voices(self) -> List[Dict[str, str]]:
# 这里应该实现获取可用声音列表的逻辑
# 由于阿里云CosyVoice可能没有直接的API来获取声音列表,我们可以手动定义一些常用的声音
return [
{"id": "xiaoyun", "name": "小云"},
{"id": "xiaogang", "name": "小刚"},
{"id": "xiaomei", "name": "小美"},
# 可以根据实际情况添加更多声音
]
def tts():
return Action()