elevenlabs: text-to-dialogue (v3/v4) alignment timestamps are chunk-relative, breaking synced transcripts
Maintainer thường phản hồi trong vòng 1 ngày
@satheeshk50 đang làm issue này rồi.
Từ ngày 13/10/2026.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 58/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- python
- Lĩnh vực
- audio-video-rtc
Hướng nghiên cứu
Read the ElevenLabs plugin’s _DialogueConnection._recv_loop and _accumulate_alignment path, introduced in #6838, and compare it with the regular text-to-speech websocket handling. Reproduce with eleven_v4_turbo and sync_alignment=True, checking how alignment behaves across audio chunks, including chunks without alignment. Done means timed words increase monotonically across the utterance and match the audio, as they do for eleven_flash_v2_5.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Bug Description
For text-to-dialogue models (eleven_v3*, eleven_v4*), the ElevenLabs plugin emits word timings that are wrong when sync_alignment=True. The timings restart near 0 on every audio chunk instead of increasing across the utterance.
The text-to-dialogue websocket returns alignment.char_start_times_ms relative to each chunk. The regular text-to-speech websocket returns them relative to the start of the context. _DialogueConnection._recv_loop passes the chunk-relative values straight into _accumulate_alignment, which treats them as relative to the context. This path was introduced in #6838.
As a result, with use_tts_aligned_transcript=True and sync_transcription=True, the timed transcript for a 13s utterance spans only 0–0.8s. Timestamps go backwards, and some words have end_time < start_time. Synced captions don't track the audio.
Expected Behavior
Timed words should increase monotonically across the utterance and line up with the audio, as they do for eleven_flash_v2_5.
Reproduction Steps
1. Set ELEVEN_API_KEY and run the script below.
2. Compare the flash and v4 output.
import asyncio, sys, aiohttp
from livekit.plugins import elevenlabs
from livekit.agents.tts.tts import USERDATA_TIMED_TRANSCRIPT
TEXT = ["Thanks, that's helpful. ", "Dr. Smith said it cost $1,250 on 3/4/2025, around 5pm. ",
"Can you walk me through what happened next? ", "And how did that make you feel at the time?"]
async def run(model):
async with aiohttp.ClientSession() as http:
tts = elevenlabs.TTS(model=model, language="en", encoding="pcm_24000", http_session=http)
stream = tts.stream()
for t in TEXT:
stream.push_text(t)
stream.end_input()
audio_s, words = 0.0, []
async for ev in stream:
for w in ev.frame.userdata.get(USERDATA_TIMED_TRANSCRIPT, []) or []:
words.append((audio_s, w))
audio_s += ev.frame.duration
await stream.aclose(); await tts.aclose()
print(f"=== {model}: audio {audio_s:.2f}s")
for at, w in words:
print(f" {w.start_time:6.2f}-{w.end_time:5.2f}s (audio pos {at:5.2f}s) {str(w)!r}")
for m in sys.argv[1:]:
asyncio.run(run(m))
# python repro.py eleven_flash_v2_5 eleven_v4_turbo
Abridged output:
=== eleven_flash_v2_5: audio 9.35s # monotonic, matches audio
0.02- 0.46s (audio pos 0.00s) 'Thanks, '
4.90- 5.41s (audio pos 5.29s) '5pm. '
8.94- 9.38s (audio pos 9.29s) 'time? '
=== eleven_v4_turbo: audio 13.28s # resets every chunk; max start_time 0.80s, 10 backward jumps
0.00- 0.32s (audio pos 0.49s) 'Thanks, '
0.48- 0.00s (audio pos 1.69s) 'helpful. '
0.16- 0.00s (audio pos 8.49s) '5pm. '
0.24- 0.72s (audio pos 13.09s) 'time? '
Raw websocket messages confirm the API behavior. On text-to-speech/.../multi-stream-input, charStartTimesMs keeps increasing across messages (0 … 499, 534 … 2159, …). On text-to-dialogue/multi-stream-input, every message's char_start_times_ms starts at 0. The dialogue endpoint also sends some audio messages with no alignment.
Operating System
macOS 15
Models Used
ElevenLabs eleven_v4_turbo (also affects eleven_v3 / eleven_v3_conversational via the same path)
Package Versions
livekit-agents==1.8.4
livekit-plugins-elevenlabs==1.8.4
# also present in 1.8.6 / main (a7c62e30)
Session/Room/Call IDs
No response
Proposed Solution
# In _DialogueConnection, keep a per-context audio offset and add it to each chunk's
# alignment before calling _accumulate_alignment. Base the offset on the decoded audio
# duration pushed so far, not on the previous chunk's last char end, because some audio
# chunks carry no alignment. With PCM: offset_ms += len(pcm_bytes) / (2 * sample_rate) * 1000.
# Pipecat's ElevenLabsDialogueTTSService applies a similar running offset,
# advancing by each chunk's alignment span.
Additional Context
Pipecat handles this in its dialogue service: "Alignment times restart at zero in every message, so the clock advances by each chunk's span."
The ElevenLabs docs describe alignment as timing data "for the chunk" but don't specify the time base.
Screenshots and Recordings
No response
- Ngôn ngữ chính
- Python
- Star
- 14.6k
- Fork
- 3.9k
- Merge trung bình
- 3 ngày 3 giờ
- Pull request đã merge (30 ngày)
- 171
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của livekit/agents
-
Assistant markup is stripped from chat history when expressive mode is offCó thể đã có người làm @ShivamSharma43 đã nhận 7 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
docs: openai.LLM vs openai.responses.LLM for HTTP OpenAI-compat hostsCó thể làm lại được @AbarnaaSree đã nhận 46 ngày trước và không có pull request nào đang mở. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
livekit/agents#7022 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
google: support Live Avatar video output for Gemini 3.8 Live (avatar_config, VIDEO modality)Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 22/100
livekit/agents#7843 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 40/100
Maintainer thường phản hồi trong vòng 1 ngày
-
StreamPacerWrapper.end_input() sets _input_ended before buffered sentences reach _sentences; last sentence(s) silently never sent to TTSCó thể đã có người làm @Hugo-DDT đã nhận hôm nay. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 25/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của livekit/agents
Issue tương tự
-
approved Good First Issue scope: docs
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
hiero-ledger/hiero-sdk-python#2730 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
wemake-services/wemake-django-template#3178 · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
md/asciidoc/csv: an explicit `encoding="utf-8"` keeps a leading BOM, the auto-detect path drops itĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
docling-project/docling#4846 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
neurostuff/NiMARE#1181 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
pytest-dev/pytest#15180 ·
Maintainer thường phản hồi trong vòng 1 ngày