Skip to content

fix(voice): anchor SiliconFlow subtitle timeline end to full audio duration - #1268

Merged
harry0703 merged 1 commit into
harry0703:mainfrom
Mihir7027:fix/siliconflow-subtitle-end-truncation
Aug 26, 2026
Merged

fix(voice): anchor SiliconFlow subtitle timeline end to full audio duration#1268
harry0703 merged 1 commit into
harry0703:mainfrom
Mihir7027:fix/siliconflow-subtitle-end-truncation

Conversation

@Mihir7027

Copy link
Copy Markdown
Contributor

Problem

siliconflow_tts built its subtitle offsets with a hand-rolled loop:

sentence_duration = int(sentence_chars * char_duration)

Accumulated integer truncation across multiple sentences means the last
subtitle always ends a few 100-nanosecond units before the actual audio
end. Users see a subtitle gap at the tail of every SiliconFlow-narrated
video.

Fix

Replaced the ad-hoc loop with populate_legacy_submaker_with_full_text,
the shared helper that all other providers (gemini_tts, mimo_tts,
minimax_tts) already use. It explicitly anchors the last subtitle entry
to the real audio_duration_100ns, eliminating the truncation gap.

Also removed a redundant local from moviepy import AudioFileClip import
(already imported at module level) and wrapped audio_clip.close() in a
finally block so the handle is always released.

Tests

Added a unit test that mocks the HTTP response and AudioFileClip,
calls siliconflow_tts with a multi-sentence script, and asserts that
offsets[-1][1] == int(audio_duration_seconds * 10_000_000).

…ration

siliconflow_tts built its subtitle offsets with an ad-hoc loop that
computed each sentence's duration independently using integer division:

    sentence_duration = int(sentence_chars * char_duration)

Accumulated truncation meant the last subtitle always ended a few
100-nanosecond units before the real audio end, leaving a subtitle gap
at the tail of every SiliconFlow-generated video.

The root cause is the same one that was already fixed for all other TTS
providers (gemini_tts, mimo_tts, minimax_tts): use the shared
populate_legacy_submaker_with_full_text helper, which explicitly
anchors the last sentence to audio_duration_100ns.

Also removed the redundant `from moviepy import AudioFileClip` local
import (AudioFileClip is already imported at module level) and wrapped
audio_clip.close() in a finally block so it cannot be skipped on error.

Added a unit test that mocks the HTTP response and AudioFileClip and
asserts the last subtitle offset equals the full audio duration.
@harry0703
harry0703 merged commit 4a92e18 into harry0703:main Aug 26, 2026
3 checks passed
@harry0703

Copy link
Copy Markdown
Owner

Thanks for the fix and the regression test! I rechecked it against the latest main, and the full test suite passes. Merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants