diff --git a/funclip/videoclipper.py b/funclip/videoclipper.py index 8655940..fc28368 100644 --- a/funclip/videoclipper.py +++ b/funclip/videoclipper.py @@ -221,6 +221,7 @@ def clip(self, dest_text, start_ost, end_ost, state, dest_spk=None, output_dir=N ts = all_ts # ts.sort() srt_index = 0 + time_acc_ost = 0.0 clip_srt = "" if len(ts): start, end = ts[0] @@ -228,16 +229,30 @@ def clip(self, dest_text, start_ost, end_ost, state, dest_spk=None, output_dir=N end = min(max(0, end+end_ost*16), len(data)) res_audio = data[start:end] start_end_info = "from {} to {}".format(start/16000, end/16000) - srt_clip, _, srt_index = generate_srt_clip(sentences, start/16000.0, end/16000.0, begin_index=srt_index) + srt_clip, _, srt_index = generate_srt_clip( + sentences, + start/16000.0, + end/16000.0, + begin_index=srt_index, + time_acc_ost=time_acc_ost, + ) clip_srt += srt_clip + time_acc_ost += (end - start) / 16000.0 for _ts in ts[1:]: # multiple sentence input or multiple output matched start, end = _ts start = min(max(0, start+start_ost*16), len(data)) end = min(max(0, end+end_ost*16), len(data)) start_end_info += ", from {} to {}".format(start, end) res_audio = np.concatenate([res_audio, data[start:end]], -1) - srt_clip, _, srt_index = generate_srt_clip(sentences, start/16000.0, end/16000.0, begin_index=srt_index-1) + srt_clip, _, srt_index = generate_srt_clip( + sentences, + start/16000.0, + end/16000.0, + begin_index=srt_index-1, + time_acc_ost=time_acc_ost, + ) clip_srt += srt_clip + time_acc_ost += (end - start) / 16000.0 if len(ts): message = "{} periods found in the speech: ".format(len(ts)) + start_end_info + log_append else: @@ -284,8 +299,8 @@ def video_clip(self, state, font_size=32, font_color='white', - add_sub=False, - dest_spk=None, + add_sub=False, + dest_spk=None, output_dir=None, timestamp_list=None): # get from state @@ -567,4 +582,4 @@ def main(cmd=None): if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/tests/test_audio_clip_srt_timeline.py b/tests/test_audio_clip_srt_timeline.py new file mode 100644 index 0000000..f38d332 --- /dev/null +++ b/tests/test_audio_clip_srt_timeline.py @@ -0,0 +1,48 @@ +import copy +import sys +from pathlib import Path + +import numpy as np + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "funclip")) + +from videoclipper import VideoClipper + + +def _state(): + sentences = [ + {"text": "hello", "timestamp": [[1000, 2000]], "spk": 0}, + {"text": "world", "timestamp": [[4000, 5000]], "spk": 0}, + ] + return { + "audio_input": (16000, np.zeros(96000)), + "recog_res_raw": "hello world", + "timestamp": [[1000, 2000], [4000, 5000]], + "sentences": sentences, + "sd_sentences": copy.deepcopy(sentences), + } + + +def test_concatenated_audio_subtitles_accumulate_output_time(): + clipper = VideoClipper(None) + + (rate, audio), _, subtitles = clipper.clip( + "hello#world", 0, 0, copy.deepcopy(_state()) + ) + + assert rate == 16000 + assert len(audio) == 32000 + assert "00:00:00,000 --> 00:00:01,000" in subtitles + assert "00:00:01,000 --> 00:00:02,000" in subtitles + + +def test_explicit_timestamp_list_uses_same_accumulated_timeline(): + clipper = VideoClipper(None) + + (_, audio), _, subtitles = clipper.clip( + "", 0, 0, copy.deepcopy(_state()), + timestamp_list=[[16000, 32000], [64000, 80000]], + ) + + assert len(audio) == 32000 + assert "00:00:01,000 --> 00:00:02,000" in subtitles