modelscope / modelscope/FunClip
[Bug] Concatenated audio clips reset each SRT segment to time zero
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 6.3k
- Forks
- 753
- Avg merge
- 19h 55m
- Merged PRs (30d)
- 8
Description
Summary
VideoClipper.clip() concatenates multiple audio regions correctly, but resets the SRT timeline for each region to zero. Later subtitles overlap the first region instead of following the concatenated audio. This occurs with zero start/end offsets and is not specific to an ASR model.
Environment
- FunClip public main:
9e720617949e32da4c0a564d10cf5a64337fe2c2; relevant local source files verified byte-equal. - Linux x86-64, Python 3.12, existing isolated environment installed from repository requirements.
- FunASR 1.4.15, torch/torchaudio 2.10.0+cpu, NumPy 1.26.4, librosa 0.11.0, Gradio 4.44.1, ModelScope 1.40.0.
- Reproduction uses the actual imported
VideoClipper.clipand subtitle helpers, not AST extracts. No browser is involved.
Audio or video input
The minimal case below uses six seconds of synthetic 16 kHz mono audio with supplied recognition state. No model download, ASR inference, hotwords, or LLM is needed. It selects source intervals 1-2 seconds and 4-5 seconds, producing two seconds of output.
The same failure was also observed independently with actual CPU SenseVoiceSmall + FSMN-VAD + CAM++ on one 18-second Chinese recording. All 40 cached model files matched the previously captured public size/SHA-256 metadata. That recording returned one anonymous speaker label; this is not a multi-speaker accuracy evaluation.
Steps to reproduce
From the repository root in an installed environment:
import copy
import sys
sys.path.insert(0, 'funclip')
import numpy as np
from videoclipper import VideoClipper
sentences = [
{'text': 'hello', 'timestamp': [[1000, 2000]], 'spk': 0},
{'text': 'world', 'timestamp': [[4000, 5000]], 'spk': 0},
]
state = {
'audio_input': (16000, np.zeros(96000)),
'recog_res_raw': 'hello world',
'timestamp': [[1000, 2000], [4000, 5000]],
'sentences': sentences,
'sd_sentences': copy.deepcopy(sentences),
}
clipper = VideoClipper(None)
(rate, audio), message, subtitles = clipper.clip(
'hello#world', 0, 0, copy.deepcopy(state)
)
print(rate, len(audio)) # 16000 32000: correct 2-second concatenation
print(subtitles)
# Both cues are 00:00:00,000 --> 00:00:01,000.
# Expected: 0-1 seconds for hello, then 1-2 seconds for world.
The posted snippet was run unchanged. Additional isolated cases use dest_spk='spk0' or timestamp_list=[[16000,32000],[64000,80000]] in the same audio API; both show the same timeline reset. A single hello selection is a passing control.
Expected behavior
The two output subtitle cues should be 0-1s and 1-2s, matching the two-second concatenated waveform. Later regions need their accumulated output-time offset, not a new zero origin.
Actual behavior
All three multi-region selection routes return the correct 32,000 samples, but both cues are 0-1s. The single-region control returns 16,000 samples and a correct 0-1s cue. Exact waveform comparisons pass; subtitle timeline comparisons fail.
In the actual-model case, the exported PCM16 WAV has 275,520 frames at 16 kHz (17.22 seconds), matching the selected source slices. Its three SRT cues are:
| Cue | Actual output time (seconds) | Expected output time (seconds) |
|---|---|---|
| 1 | 0-7.140 | 0-7.140 |
| 2 | 0-6.600 | 7.140-13.740 |
| 3 | 0-3.480 | 13.740-17.220 |
Thus the combined WAV/SRT acceptance fails, even though the waveform and nonempty-subtitle checks pass.
Logs or traceback
16000 32000
1
00:00:00,000 --> 00:00:01,000
hello
2
00:00:00,000 --> 00:00:01,000
world
There is no exception. In clip(), later calls to generate_srt_clip() omit time_acc_ost, so the helper's default 0.0 is reused. The video path already passes an accumulated offset; video export was not run in this reproduction.
Screenshots or clips
The exact minimal output and real exported-WAV/SRT measurements above establish the mismatch without sharing source speech or requiring screenshots.
Related reports and fixes were checked: #155 addressed double-applied nonzero offsets (and the video accumulator), while this audio subtitle reset occurs with offsets set to zero. #129/#144 concerned video/audio alignment, #83 omitted speaker content, #102 included SRT formatting, and #177 fixed repeated-match control flow. This report does not reopen those or claim they share this exact cause. It is also independent of #54 (CLI case), #214 (sample rate), and #215 (Chinese text/timestamp matching).
No production repair, release, acoustic accuracy, browser, video-export, or non-16 kHz acceptance is claimed. Prepared with Codex assistance.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at VideoClipper.clip and trace its audio subtitle calls to generate_srt_clip, comparing them with the video path's accumulated offset handling. Run the supplied six-second reproduction and verify that the waveform remains 32,000 samples while the second cue starts at 1 second instead of resetting to zero.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- audio-video-rtc
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100