hugvey/hugvey/voice.py
2019-02-19 10:18:17 +01:00

80 lines
2.6 KiB
Python

import os
import time
import json
import logging
import threading
#from requests_threads import AsyncSession
from hashlib import sha1
import asyncio
from tornado.httpclient import AsyncHTTPClient, HTTPRequest
logger = logging.getLogger("voice")
class VoiceStorage(object):
"""
Store & keep voices that are not part of the story json
"""
def __init__(self, cache_dir, token):
self.cache_dir = cache_dir
if not os.path.exists(self.cache_dir):
raise Exception(f"Cache dir does not exists: {self.cache_dir}")
# self.request_session = AsyncSession(n=5)
self.pendingRequests = {}
self.token = token
def getId(self, text):
return sha1(text.encode()).hexdigest()
def getFilename(self, text, isVariable=False):
subdir = 'static' if not isVariable else 'variable'
id = self.getId(text)
prefix = id[:2]
storageDir = os.path.join(self.cache_dir, subdir, prefix)
fn = os.path.join(storageDir, f"{id}.wav")
return fn
async def requestFile(self, text, isVariable=False) -> str:
id = self.getId(text)
fn = self.getFilename(text)
if os.path.exists(fn):
return fn
if id in self.pendingRequests:
await self.pendingRequests[id].wait()
if os.path.exists(fn):
return fn
return None
dirname = os.path.dirname(fn)
if not os.path.exists(dirname):
logger.debug(f"create directory for file: {dirname}")
os.makedirs(dirname, exist_ok=True)
self.pendingRequests[id] = asyncio.Event()
http_client = AsyncHTTPClient()
request = HTTPRequest(
method="POST",
url="https://avatar.lyrebird.ai/api/v0/generate",
body=json.dumps({"text": text}),
headers={"authorization": f"Bearer {self.token}"}
)
try:
response = await http_client.fetch(request)
except Exception as e:
logger.exception(e)
self.pendingRequests[id].set()
return None
else:
if response.code != 200:
logger.critical(f"No proper response! {response.code}")
self.pendingRequests[id].set()
return None
logger.debug(f"Wrote body: {response.code}")
with open(fn, "wb") as f:
f.write(response.body)
self.pendingRequests[id].set()
print(type(fn), fn)
return fn