You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

合并SRT字幕不完整语句以提升DeepL翻译准确性(Python)

合并拆分的SRT字幕语句以提升翻译准确性

需求背景

我有一份SRT格式的视频字幕文件,计划用DeepL翻译,但字幕里的语句被拆分得支离破碎,导致翻译结果准确性不足。

目标功能

实现:如果某行语句未结束,就把后续行的对应内容合并到该行,直到语句完整,同时清空被合并行的文本,处理后效果示例如下。

原字幕内容

1
00:00:00,000 --> 00:00:13,680
Je vais mettre en direct sur l'hôtel comme ça on peut regarder les messages et tout.

2
00:00:13,680 --> 00:00:14,680
Ouais.

3
00:00:14,680 --> 00:00:20,080
Tiens je vais recevoir la notification Romain étant direct.

4
00:00:20,080 --> 00:00:22,720
Vas-y ouvrez le live.

5
00:00:22,720 --> 00:00:25,640
Ouais c'est bon on vous entend.

6
00:00:25,640 --> 00:00:26,640
Nice.

7
00:00:26,640 --> 00:00:28,480
Attends je vais présenter vite fait du coup, je vais attendre que tout le monde vienne.

8
00:00:28,480 --> 00:00:40,640
Salut Raphaël, salut Ismaël, salut Jean-Marc, bonjour à tous, bonjour Clément, bonjour

9
00:00:40,640 --> 00:00:41,640
Thierry.

10
00:00:41,640 --> 00:00:42,640
Bonjour à tous.

11
00:00:42,640 --> 00:00:44,640
Je ne sais pas s'ils nous entendent ou pas normalement.

12
00:00:44,640 --> 00:00:45,640
Si si ils t'entendent là.

13
00:00:45,640 --> 00:00:46,640
On va attendre.

14
00:00:46,640 --> 00:00:51,480
Limite on peut nous filmer en attendant que ça démarre vite fait, attends.

15
00:00:51,480 --> 00:00:53,360
Je vais vous filmer vous.

16
00:00:53,360 --> 00:00:57,520
Bon les gars juste pour faire une petite précision aujourd'hui on va avoir deux intervenants,

17
00:00:57,520 --> 00:01:02,560
on va avoir, je vais couper ma tête, on va avoir du coup CP Dropshipping, je pense que

18
00:01:02,560 --> 00:01:06,320
vous le connaissez, il a une chaîne YouTube, il a un compte Facebook assez suivi donc voilà

19
00:01:06,320 --> 00:01:11,520
avec un très beau t-shirt Balenciaga et aussi Jérémy donc on a deux Dropshippers qui pèsent

20
00:01:11,520 --> 00:01:16,960
assez lourd et voilà Jérémy c'est un administrateur du Discord et qui commence à faire tout

21
00:01:16,960 --> 00:01:21,520
est bien, qui commence à faire pas mal de souis, qui va venir habiter sur Malte bientôt

22
00:01:21,520 --> 00:01:22,520
je crois.

23
00:01:22,520 --> 00:01:25,520
On a regardé les vidéos d'avion là tout à l'heure.

24
00:01:25,520 --> 00:01:28,520
Il faudrait que je le ramène une semaine.

25
00:01:28,520 --> 00:01:30,320
Ah merde, je me suis trompé.

处理后预期效果

1
00:00:00,000 --> 00:00:13,680
Je vais mettre en direct sur l'hôtel comme ça on peut regarder les messages et tout.

2
00:00:13,680 --> 00:00:14,680
Ouais.

3
00:00:14,680 --> 00:00:20,080
Tiens je vais recevoir la notification Romain étant direct.

4
00:00:20,080 --> 00:00:22,720
Vas-y ouvrez le live.

5
00:00:22,720 --> 00:00:25,640
Ouais c'est bon on vous entend.

6
00:00:25,640 --> 00:00:26,640
Nice.

7
00:00:26,640 --> 00:00:28,480
Attends je vais présenter vite fait du coup, je vais attendre que tout le monde vienne.

8
00:00:28,480 --> 00:00:40,640
Salut Raphaël, salut Ismaël, salut Jean-Marc, bonjour à tous, bonjour Clément, bonjour Thierry.

9
00:00:40,640 --> 00:00:41,640

10
00:00:41,640 --> 00:00:42,640
Bonjour à tous.

11
00:00:42,640 --> 00:00:44,640
Je ne sais pas s'ils nous entendent ou pas normalement.

12
00:00:44,640 --> 00:00:45,640
Si si ils t'entendent là.

13
00:00:45,640 --> 00:00:46,640
On va attendre.

14
00:00:46,640 --> 00:00:51,480
Limite on peut nous filmer en attendant que ça démarre vite fait, attends.

15
00:00:51,480 --> 00:00:53,360
Je vais vous filmer vous.

16
00:00:53,360 --> 00:00:57,520
Bon les gars juste pour faire une petite précision aujourd'hui on va avoir deux intervenants, on va avoir, je vais couper ma tête, on va avoir du coup CP Dropshipping, je pense que vous le connaissez, il a une chaîne YouTube, il a un compte Facebook assez suivi donc voilà avec un très beau t-shirt Balenciaga et aussi Jérémy donc on a deux Dropshippers qui pèsent assez lourd et voilà Jérémy c'est un administrateur du Discord et qui commence à faire tout est bien, qui commence à faire pas mal de souis, qui va venir habiter sur Malte bientôt je crois.

17
00:00:57,520 --> 00:01:02,560

18
00:01:02,560 --> 00:01:06,320

19
00:01:06,320 --> 00:01:11,520

20
00:01:11,520 --> 00:01:16,960

21
00:01:16,960 --> 00:01:21,520

22
00:01:21,520 --> 00:01:22,520

23
00:01:22,520 --> 00:01:25,520
On a regardé les vidéos d'avion là tout à l'heure.

24
00:01:25,520 --> 00:01:28,520
Il faudrait que je le ramène une semaine.

25
00:01:28,520 --> 00:01:30,320
Ah merde, je me suis trompé.

已尝试代码

import re

file = open('files/FINAL/v23FINAL.srt') 
content = file.readlines()
new = ''

i = 2
max = len(content) - 1

while i < max :
    now = str(content[i][-2])
    next = str(content[i+4][-2])

    print(now + '\n' + next)

    if now != '.' or now != '?' or now != '!':
        for j in range(len(content[i+4])):
            if content[i+4][j] == '.' or content[i+4][j] == '?' or content[i+4][j] == '!':
                print(content[i+4][0:j+1])
                print(content[i+4][j+2:len(content)-2])
                break

        i += 4

    else:
        new += content[i]
        new += content[i+1]
        new += content[i+2]
        new += '\n'

        i += 4


with open('newText.srt', 'a') as n:
    n.write(new)

Python解决方案

下面是完整的实现代码,核心逻辑是先解析SRT字幕为结构化数据,再合并未结束的语句,最后重新生成符合格式的SRT文件:

def parse_srt(file_path):
    """解析SRT文件,返回字幕条目列表,每个条目是包含序号、时间轴、文本的字典"""
    subtitles = []
    with open(file_path, 'r', encoding='utf-8') as f:
        lines = [line.rstrip('\n') for line in f]
    
    i = 0
    while i < len(lines):
        if lines[i].strip().isdigit():
            idx = lines[i].strip()
            time_line = lines[i+1].strip()
            text_lines = []
            j = i+2
            while j < len(lines) and lines[j].strip() != '':
                text_lines.append(lines[j].strip())
                j += 1
            subtitles.append({
                'index': idx,
                'time': time_line,
                'text': ' '.join(text_lines)
            })
            i = j + 1
        else:
            i += 1
    return subtitles

def merge_split_sentences(subtitles):
    """合并未结束的语句,清空被合并条目的文本"""
    merged_subs = subtitles.copy()
    i = 0
    while i < len(merged_subs):
        current_text = merged_subs[i]['text']
        # 检查当前文本是否以句末标点结尾
        if not current_text.endswith(('.', '?', '!')) and i < len(merged_subs)-1:
            next_idx = i + 1
            # 持续合并后续条目直到找到句末标点
            while next_idx < len(merged_subs):
                next_text = merged_subs[next_idx]['text']
                merged_subs[i]['text'] += ' ' + next_text
                merged_subs[next_idx]['text'] = ''
                if next_text.endswith(('.', '?', '!')):
                    break
                next_idx += 1
            i = next_idx
        i += 1
    return merged_subs

def write_srt(subtitles, output_path):
    """将处理后的字幕条目写入SRT文件"""
    with open(output_path, 'w', encoding='utf-8') as f:
        for sub in subtitles:
            f.write(sub['index'] + '\n')
            f.write(sub['time'] + '\n')
            f.write(sub['text'] + '\n\n')

# 主流程
input_srt = 'files/FINAL/v23FINAL.srt'
output_srt = 'merged_subtitles.srt'

subs = parse_srt(input_srt)
merged_subs = merge_split_sentences(subs)
write_srt(merged_subs, output_srt)

代码说明

  1. parse_srt函数:把SRT文件的内容解析成结构化的字典列表,每个字典包含字幕的序号、时间轴和文本,方便后续处理。
  2. merge_split_sentences函数:遍历字幕条目,检查当前条目的文本是否以句末标点(. ? !)结尾,如果没有,就把后续条目的文本合并进来,并清空后续条目的文本,直到遇到包含句末标点的条目为止。
  3. write_srt函数:把处理后的结构化字幕数据重新写入成标准的SRT格式文件。

使用时只需要修改input_srt和output_srt的路径即可。


内容的提问来源于stack exchange,提问作者Ömer Work

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:00:56