Rectifier / App /Generate /database /CharacterAPI.py
Mbonea's picture
CharacterAI improvements
6d59db4
raw
history blame
3.94 kB
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())