tonhowtf/omniget · error
Edge TTS nao devolveu audio (o servico pode ter mudado o…
Error message
Edge TTS nao devolveu audio (o servico pode ter mudado o token; tente de novo mais tarde)
What it means
After streaming the TTS request over the WebSocket, synth_chunk expects at least one audio message. If the socket closed (or all messages were parsed) without any audio payload, this error fires, hinting that Microsoft may have changed its DRM token so the service silently returns nothing.
Solutions
- Retry later — the message itself suggests the token/service may be temporarily mismatched
- Update the edge-tts library to a version with a current Sec-MS-GEC token generator
- Verify the requested voice id exists (see list_voices)
- Log raw WebSocket messages to confirm whether the server sends an error frame instead of audio
Example fix
// before
let out = edge_tts::synthesize(&opts, &path, progress).await?;
// after
let out = edge_tts::synthesize(&opts, &path, progress).await
.map_err(|e| if e.to_string().contains("nao devolveu audio") {
anyhow!("TTS upstream empty; check library version / retry later: {e}")
} else { e })?; Defensive patterns
Strategy: retry
Validate before calling
// verify the voice exists first so the service isn't silently rejecting the request
let voices = edge_tts::list_voices().await?;
if !voices.iter().any(|v| v.short_name == opts.voice) { return Err(anyhow!("voz desconhecida")); } Try / catch
match edge_tts::synthesize(&opts, &path, progress).await {
Ok(r) => r,
Err(e) if e.to_string().contains("nao devolveu audio") => {
tokio::time::sleep(Duration::from_secs(5)).await;
edge_tts::synthesize(&opts, &path, progress).await
}
Err(e) => Err(e),
} Prevention
- Pin/update the edge-tts library so the DRM token generator stays current
- Retry before failing the whole job — this is often transient
- Validate voice ids against list_voices before synthesis
When it happens
Trigger: Calling synthesize() when the Edge TTS service accepts the WebSocket but never sends audio: expired/invalid Sec-MS-GEC token, Microsoft service-side contract change, or the request being silently rejected (e.g. bad voice id causing immediate close).
Common situations: Microsoft rotating the DRM token algorithm after a browser update; using an outdated library whose token generator is stale; requesting an invalid/deprecated voice name; service-side outage returning empty streams.
Related errors
- Edge TTS: conexao recusada
- resposta do arXiv sem
- lista de vozes do Edge indisponivel: HTTP
- texto vazio
- o Goodreads respondeu HTTP
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/ca36e279c4ff79bd.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/edge_tts.rs:317
continue;
}
let header_len = u16::from_be_bytes([b[0], b[1]]) as usize;
if b.len() < header_len + 2 {
continue;
}
let header = String::from_utf8_lossy(&b[2..2 + header_len]);
if header.contains("Path:audio") {
audio.extend_from_slice(&b[2 + header_len..]);
got_audio = true;
}
}
Message::Close(_) => break,
_ => {}
}
}
let _ = ws.close(None).await;
if !got_audio {
return Err(anyhow!("Edge TTS nao devolveu audio (o servico pode ter mudado o token; tente de novo mais tarde)"));
}
Ok(ChunkOut { audio, words })
}
/// Agrupa palavras em legendas curtas (até 8 palavras, corta em pausas).
pub fn words_to_cues(words: &[WordBoundary]) -> Vec<Cue> {
let mut cues = Vec::new();
let mut buf: Vec<&WordBoundary> = Vec::new();
let flush = |buf: &mut Vec<&WordBoundary>, cues: &mut Vec<Cue>| {
if buf.is_empty() {
return;
}
let start = buf[0].start_ms;
let last = buf[buf.len() - 1];
let end = last.start_ms + last.duration_ms.max(200);
let text = buf
.iter()
.map(|w| w.text.as_str())View on GitHub (pinned to 8600b91f42)