| @@ -24,6 +24,8 @@ LABELS = {"elevenlabs": "ElevenLabs Scribe v2", "gladia": "Gladia Solaria"} |
| 24 | TIMEOUT = 30 * 60 | 24 | TIMEOUT = 30 * 60 |
| 25 | POLL_EVERY = 2.0 | 25 | POLL_EVERY = 2.0 |
| 26 | # ElevenLabs renvoie des codes ISO 639-3 | 26 | # ElevenLabs renvoie des codes ISO 639-3 |
| | 27 | +# connexion perdue (paquets perdus, WinError 10060) : reessayee, rien n'a encore ete envoye |
| | 28 | +_http = httpx.Client(transport=httpx.HTTPTransport(retries=3)) |
| 27 | ISO3 = {"fra": "fr", "eng": "en", "spa": "es", "deu": "de", "ita": "it", "por": "pt"} | 29 | ISO3 = {"fra": "fr", "eng": "en", "spa": "es", "deu": "de", "ita": "it", "por": "pt"} |
| 28 | | 30 | |
| 29 | Words = list[tuple[float, float, str]] | 31 | Words = list[tuple[float, float, str]] |
| @@ -48,6 +50,10 @@ class CloudEngine: |
| 48 | try: | 50 | try: |
| 49 | run = self._elevenlabs if self.provider == "elevenlabs" else self._gladia | 51 | run = self._elevenlabs if self.provider == "elevenlabs" else self._gladia |
| 50 | words, detected = run(mp3, language, check_cancel) | 52 | words, detected = run(mp3, language, check_cancel) |
| | 53 | + except httpx.TransportError as e: |
| | 54 | + # coupure reseau, pare-feu, proxy : le message brut (WinError 10060...) ne dit pas qui |
| | 55 | + raise RuntimeError(f"{LABELS[self.provider]} injoignable ({type(e).__name__}) : " |
| | 56 | + "vérifie la connexion, ou repasse sur Whisper dans les réglages") from e |
| 51 | finally: | 57 | finally: |
| 52 | mp3.unlink(missing_ok=True) | 58 | mp3.unlink(missing_ok=True) |
| 53 | segments = group(words) | 59 | segments = group(words) |
| @@ -62,7 +68,7 @@ class CloudEngine: |
| 62 | if language: | 68 | if language: |
| 63 | data["language_code"] = language | 69 | data["language_code"] = language |
| 64 | with audio.open("rb") as f: | 70 | with audio.open("rb") as f: |
| 65 | - r = httpx.post(ELEVENLABS_URL, headers={"xi-api-key": self.key}, data=data, | 71 | + r = _http.post(ELEVENLABS_URL, headers={"xi-api-key": self.key}, data=data, |
| 66 | files={"file": (audio.name, f, "audio/mpeg")}, timeout=TIMEOUT) | 72 | files={"file": (audio.name, f, "audio/mpeg")}, timeout=TIMEOUT) |
| 67 | _raise(r, "ElevenLabs") | 73 | _raise(r, "ElevenLabs") |
| 68 | raw = r.json() | 74 | raw = r.json() |
| @@ -73,18 +79,18 @@ class CloudEngine: |
| 73 | def _gladia(self, audio: Path, language: str | None, check_cancel) -> tuple[Words, str | None]: | 79 | def _gladia(self, audio: Path, language: str | None, check_cancel) -> tuple[Words, str | None]: |
| 74 | h = {"x-gladia-key": self.key} | 80 | h = {"x-gladia-key": self.key} |
| 75 | with audio.open("rb") as f: | 81 | with audio.open("rb") as f: |
| 76 | - up = httpx.post(f"{GLADIA_URL}/upload", headers=h, files={"audio": (audio.name, f, "audio/mpeg")}, | 82 | + up = _http.post(f"{GLADIA_URL}/upload", headers=h, files={"audio": (audio.name, f, "audio/mpeg")}, |
| 77 | timeout=TIMEOUT) | 83 | timeout=TIMEOUT) |
| 78 | _raise(up, "Gladia") | 84 | _raise(up, "Gladia") |
| 79 | body: dict = {"audio_url": up.json()["audio_url"]} | 85 | body: dict = {"audio_url": up.json()["audio_url"]} |
| 80 | if language: | 86 | if language: |
| 81 | body["language_config"] = {"languages": [language]} | 87 | body["language_config"] = {"languages": [language]} |
| 82 | - job = httpx.post(f"{GLADIA_URL}/pre-recorded", headers=h, json=body, timeout=60) | 88 | + job = _http.post(f"{GLADIA_URL}/pre-recorded", headers=h, json=body, timeout=60) |
| 83 | _raise(job, "Gladia") | 89 | _raise(job, "Gladia") |
| 84 | url = f"{GLADIA_URL}/pre-recorded/{job.json()['id']}" | 90 | url = f"{GLADIA_URL}/pre-recorded/{job.json()['id']}" |
| 85 | while True: | 91 | while True: |
| 86 | check_cancel() | 92 | check_cancel() |
| 87 | - r = httpx.get(url, headers=h, timeout=60) | 93 | + r = _http.get(url, headers=h, timeout=60) |
| 88 | _raise(r, "Gladia") | 94 | _raise(r, "Gladia") |
| 89 | raw = r.json() | 95 | raw = r.json() |
| 90 | if raw.get("status") == "done": | 96 | if raw.get("status") == "done": |