modelscope / modelscope/FunClip

[Bug] Concatenated audio clips reset each SRT segment to time zero

Open Beginner friendly
#216 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
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.clip and 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.