Speaker: højst tre samtidige kald til ElevenLabs og nyt forsøg ved 429
CI / test (push) Successful in 24s
CI / test (push) Successful in 24s
Afsløringen bestilte alle trin på én gang og ramte abonnementets loft for samtidige kald. Forklaringen genereres nu allerede, mens der løjes. Claude-Session: https://claude.ai/code/session_01JmhJG6JnhXfzNiKv8f2vHu
This commit is contained in:
@@ -124,6 +124,9 @@ class Room:
|
||||
self.say(text)
|
||||
if ev["type"] == "lie_start":
|
||||
self._at_deadline_minus(10, "lie", "lie_hurry")
|
||||
note = (self.game.question or {}).get("note")
|
||||
if note: # forklaringen kendes allerede nu; lav den, mens der løjes
|
||||
asyncio.get_running_loop().create_task(tts.synth(note))
|
||||
elif ev["type"] == "guess_start":
|
||||
self._at_deadline_minus(5, "guess", "guess_hurry")
|
||||
|
||||
|
||||
+19
-1
@@ -19,7 +19,10 @@ log = logging.getLogger(__name__)
|
||||
|
||||
API = "https://api.elevenlabs.io/v1/text-to-speech/{voice}?output_format=mp3_44100_128"
|
||||
BITRATE = 128_000
|
||||
CONCURRENCY = 3 # ElevenLabs begrænser samtidige kald pr. abonnement (Creator: få)
|
||||
RETRIES_ON_429 = 3
|
||||
_inflight: dict[str, asyncio.Future] = {}
|
||||
_sem: asyncio.Semaphore | None = None
|
||||
|
||||
|
||||
def enabled() -> bool:
|
||||
@@ -74,7 +77,7 @@ async def synth(text: str) -> dict | None:
|
||||
return _result(digest)
|
||||
fut = _inflight.get(digest)
|
||||
if fut is None:
|
||||
fut = asyncio.get_running_loop().create_task(asyncio.to_thread(_fetch, text, cache_path(digest)))
|
||||
fut = asyncio.get_running_loop().create_task(_fetch_limited(text, cache_path(digest)))
|
||||
_inflight[digest] = fut
|
||||
fut.add_done_callback(lambda _f: _inflight.pop(digest, None))
|
||||
try:
|
||||
@@ -85,6 +88,21 @@ async def synth(text: str) -> dict | None:
|
||||
return _result(digest)
|
||||
|
||||
|
||||
async def _fetch_limited(text: str, path: Path) -> None:
|
||||
global _sem
|
||||
if _sem is None:
|
||||
_sem = asyncio.Semaphore(CONCURRENCY)
|
||||
for attempt in range(RETRIES_ON_429 + 1):
|
||||
async with _sem:
|
||||
try:
|
||||
await asyncio.to_thread(_fetch, text, path)
|
||||
return
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code != 429 or attempt == RETRIES_ON_429:
|
||||
raise
|
||||
await asyncio.sleep(0.7 * (attempt + 1))
|
||||
|
||||
|
||||
def _describe(e: Exception) -> str:
|
||||
if isinstance(e, urllib.error.HTTPError):
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user