Tester / App /Generate /database /CharacterAPI.py
Mbonea's picture
CharacterAI improvements
6d59db4
import aiohttp
import asyncio
import os
import uuid
import tempfile
from typing import List, Dict, Any
from pydantic import BaseModel
class AlignmentData(BaseModel):
word: str
start: float
end: float
def to_dict(self) -> dict:
return {
"word": self.word,
"alignedWord": self.word,
"startTime": self.start,
"endTime": self.end,
"hasFailedAlignment": False,
}
class CharacterAITTS:
def __init__(self):
self.api_url = "https://yakova-embedding.hf.space"
self.dir = str(tempfile.mkdtemp())
self.descript = "https://yakova-embedding.hf.space"
self.headers = {"Connection": "keep-alive", "Content-Type": "application/json"}
async def _make_transcript(self, links, text):
data = {"audio_url": links, "text": text, "file_extenstion": ".mp3"}
response_data = await self._make_request(
"post", "descript_transcript", json=data, external=self.descript
)
if not response_data:
data["audio_url"] = data["audio_url"][0]
print(data)
response_data = await self.aligner(
"post",
"align/url",
json=data,
)
print(response_data)
response_data = self.process_alignments(
data=response_data["alignment"], offset=0
)
return response_data
def process_alignments(
self, data: List[Dict[str, Any]], offset: float = 0
) -> List[Dict[str, Any]]:
alignments = [AlignmentData(**item) for item in data]
return [alignment.to_dict() for alignment in alignments]
async def aligner(
self,
method,
endpoint,
json=None,
external="https://yakova-aligner.hf.space/align/url",
):
async with aiohttp.ClientSession() as session:
if external:
url = f"{external}"
else:
url = f"{self.api_url}/{endpoint}"
async with getattr(session, method)(url=url, json=json) as response:
return await response.json()
async def _make_request(self, method, endpoint, json=None, external=None):
async with aiohttp.ClientSession() as session:
if external:
url = f"{external}/{endpoint}"
else:
url = f"{self.api_url}/{endpoint}"
async with getattr(session, method)(url=url, json=json) as response:
return await response.json()
async def say(self, text, speaker=None):
data = {"text": text, "voice": speaker}
response_data = await self._make_request("post", "cai_tts", json=data)
# print(response_data)
audio_url = response_data["audio"]
temp = await self.download_file(audio_url)
return audio_url, temp
async def download_file(self, url):
filename = str(uuid.uuid4()) + ".mp3"
os.makedirs(self.dir, exist_ok=True)
save_path = os.path.join(self.dir, filename)
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
with open(save_path, "wb") as file:
while True:
chunk = await response.content.read(1024)
if not chunk:
break
file.write(chunk)
return save_path
# # Usage
# async def main():
# tts = CharacterAITTS()
# url, temp = await tts.say(
# "Did you know that you don't have the balls to talk to me"
# )
# tranny = await tts._make_transcript(
# links=[url], text="Did you know that you don't have the balls to talk to me"
# )
# print(tranny)
# # Run the main function
# asyncio.run(main())