你好,小窝工具大佬,能否请你帮助优化一下srt文件内容合并代码?

我写了一段代码,功能是合并srt文件中上句结束时间和下句开始时间相同的行,目前的状态是:
1合并后的句子没有问题,合并后每一句的结束时间没有问题。
2合并后每一句的开始时间不对。

我实在太菜鸟了,每一句的开始时间就是不对,

恳请大神帮忙,谢谢

11个回答默认排序 投票数排序
ww
ww
这家伙很懒,什么也没写~
6月前

我这边是有缩进格式的,复制过来就变成现在的样子了

小蜗
小蜗回复ww
这家伙很懒,什么也没写~
6月前

你发的代码莫法看

小蜗
小蜗
这家伙很懒,什么也没写~
6月前

发布信息的时候,在网页端使用代码块发布:

import os
def merge_srt_files(folder):
    # 创建一个空列表,用于存储找到的 srt 文件
    srt_files = []
    # 遍历文件夹中的所有文件和子文件夹
    for file in os.scandir(folder):
    # 如果是文件,且文件名以 .srt 结尾
    if file.is_file() and file.name.endswith(".srt"):
    # 将文件的绝对路径添加到列表中
    srt_files.append(file.path)
ww
ww
这家伙很懒,什么也没写~
6月前

还是没懂怎样发才保持原貌,点了块级代码,复制过来还是不对

ww
ww
这家伙很懒,什么也没写~
6月前
```# 导入 os 模块,用于操作文件和目录
import os

# 定义一个函数,接受一个文件夹路径作为参数
def merge_srt_files(folder):
    # 创建一个空列表,用于存储找到的 srt 文件
    srt_files = []
    # 遍历文件夹中的所有文件和子文件夹
    for file in os.scandir(folder):
        # 如果是文件,且文件名以 .srt 结尾
        if file.is_file() and file.name.endswith(".srt"):
            # 将文件的绝对路径添加到列表中
            srt_files.append(file.path)
    # 如果没有找到任何 srt 文件,打印提示信息并返回
    if not srt_files:
        print("没有找到任何 srt 文件")
        return
    # 创建一个空列表,用于存储合并后的 srt 内容
    merged_srt = []
    # 遍历列表中的每个 srt 文件
    for srt_file in srt_files:
        # 打开文件,以只读模式
        with open(srt_file, "r", encoding="utf-8") as f:
            # 读取文件的所有行,返回一个列表
            lines = f.readlines()
            # 初始化一个空字符串,用于存储当前的字幕序号
            index = ""
            # 初始化一个空字符串,用于存储当前的字幕时间轴
            timeline = ""
            # 初始化一个空列表,用于存储当前的字幕内容
            content = []
            # 遍历文件的每一行
            for line in lines:
                # 去掉行尾的换行符
                line = line.strip()
                # 如果行为空,表示一个字幕段落的结束
                if not line:
                    # 如果有字幕序号,时间轴和内容
                    if index and timeline and content:
                        # 将字幕内容转换为一个字符串,用空格连接
                        content = " ".join(content)
                        # 将字幕序号,时间轴和内容作为一个元组添加到列表中
                        merged_srt.append((index, timeline, content))
                    # 重置字幕序号,时间轴和内容
                    index = ""
                    timeline = ""
                    content = []
                # 如果行是纯数字,表示一个字幕序号的开始
                elif line.isdigit():
                    # 将行赋值给字幕序号
                    index = line
                # 如果行包含 --> 字符,表示一个字幕时间轴的开始
                elif "-->" in line:
                    # 将行赋值给字幕时间轴
                    timeline = line
                # 否则,表示一个字幕内容的一部分
                else:
                    # 将行添加到字幕内容列表中
                    content.append(line)
    # 如果列表为空,表示没有合并任何 srt 文件,打印提示信息并返回
    if not merged_srt:
        print("没有合并任何 srt 文件")
        return
    # 创建一个新的列表,用于存储合并后的 srt 内容
    new_srt = []
    # 初始化一个空字符串,用于存储上一行的字幕开始时间
    prev_start = ""
    # 初始化一个空字符串,用于存储上一行的字幕结束时间
    prev_end = ""
    # 初始化一个空字符串,用于存储当前的字幕内容
    curr_content = ""
    # 遍历列表中的每个元组,按照字幕序号的升序排序
    for index, timeline, content in sorted(merged_srt, key=lambda x: int(x[0])):
        # 将时间轴按照 --> 字符分割,得到开始时间和结束时间
        start, end = timeline.split("-->")
        # 去掉开始时间和结束时间的空格
        start = start.strip()
        end = end.strip()
        # 如果开始时间和上一行的结束时间相同,表示需要合并字幕内容
        if start == prev_end:
            # 将当前的字幕内容追加到上一行的字幕内容后面,用空格分隔
            curr_content += " " + content
            # 删除当前的字幕序号,时间轴和内容
            index = ""
            timeline = ""
            content = ""
            # 更新时间轴为上一行的时间轴,用上一行的开始时间和当前的结束时间组成
            timeline = prev_start + " --> " + end
        # 否则,表示需要开始一个新的字幕段落
        else:
            # 如果有上一行的字幕内容
            if curr_content:
                # 将上一行的字幕内容添加到新的列表中
                new_srt.append((prev_start, prev_end, curr_content))
            # 将当前的字幕内容赋值给上一行的字幕内容
            curr_content = content
            # 记录当前的时间轴为上一行的时间轴
            prev_timeline = timeline
        # 将当前的开始时间赋值给上一行的开始时间
        prev_start = start
        # 将当前的结束时间赋值给上一行的结束时间
        prev_end = end
    # 如果有上一行的字幕内容
    if curr_content:
        # 将上一行的字幕内容添加到新的列表中
        new_srt.append((prev_start, prev_end, curr_content))
    # 创建一个新的文件名,用于输出合并后的 srt 文件
    new_file = os.path.join(folder, "merged.srt")
    # 打开文件,以写入模式,如果文件不存在,将创建一个新文件
    with open(new_file, "w", encoding="utf-8") as f:
        # 初始化一个变量,用于存储新的字幕序号
        new_index = 1
        # 遍历新的列表中的每个字幕内容
        for start, end, content in new_srt:
            # 写入新的字幕序号,末尾加上换行符
            f.write(str(new_index) + "\n")
            # 写入字幕时间轴,末尾加上换行符
            f.write(start + " --> " + end + "\n")
            # 写入字幕内容,末尾加上两个换行符
            f.write(content + "\n\n")
            # 将新的字幕序号加一
            new_index += 1
    # 打印提示信息,显示输出文件的路径
    print(f"合并后的 srt 文件已输出到 {new_file}")

# 调用函数,传入当前文件夹的路径
merge_srt_files(os.getcwd())
ww
ww
这家伙很懒,什么也没写~
6月前

大神如果肯帮忙,改好后也可集成在你的小窝工具里面。

再见旧时光
再见旧时光
QQ:986004469 Email:vutool@qq.com
6月前

读取srt文件,把srt文件中 开始时间和下一个字幕块结束时间合并为一行:

from decimal import Decimal
def parse_subtitle_blocks(subtitle_file):
    with open(subtitle_file, 'r', encoding='utf-8') as file:
        lines = file.readlines()

    subtitle_blocks = []
    i = 0
    while i < len(lines):
        line = lines[i].strip()
        if line.isdigit():  # 判断是否为字幕序号
            block_number = int(line)
            i += 1
            start_time, end_time = lines[i].strip().split(' --> ')  # 获取当前字幕块的开始时间和结束时间
            subtitle_text = ""
            i += 1
            while i < len(lines) and lines[i].strip() != "":
                subtitle_text += lines[i].strip() + " "
                i += 1
            subtitle_blocks.append({
                "number": block_number,
                "start_time": start_time,
                "end_time": end_time,
                "text": subtitle_text.strip()
            })
        else:
            i += 1

    return subtitle_blocks
def sub(a,b):
    return Decimal(str(a)) - Decimal(str(b))

def marg_srt(all_list):
    new_lis=[]
    lis=None
    for li in all_list:
        if lis:
           if lis['end_time']==li['start_time']:
               print(lis['number'])
               lis['text']=lis['text']+li['text']
               lis['end_time']=li['end_time']

           else:
               new_lis.append(lis)
               lis=li

        else:
            lis = li

    if len(li)>0:
        new_lis.append(lis)
    return new_lis
# 示例用法
def write_subtitle_file&#40;subtitle_blocks,output_file&#41;:
    with open(output_file, 'w', encoding='utf-8') as file:
        for index,block in enumerate(subtitle_blocks):
            file.write(str(index+1) + "\n")
            file.write(block["start_time"] + " --> " + block["end_time"] + "\n")
            file.write(block["text"] + "\n")
            file.write("\n")


subtitle_file = 'input.srt'  # 字幕文件路径
subtitle_blocks = parse_subtitle_blocks(subtitle_file)
srt_list=marg_srt(subtitle_blocks)
write_subtitle_file&#40;srt_list,'out.srt'&#41;
再见旧时光
再见旧时光
QQ:986004469 Email:vutool@qq.com
6月前
from decimal import Decimal
def parse_subtitle_blocks(subtitle_file):
    with open(subtitle_file, 'r', encoding='utf-8') as file:
        lines = file.readlines()

    subtitle_blocks = []
    i = 0
    while i < len(lines):
        line = lines[i].strip()
        if line.isdigit():  # 判断是否为字幕序号
            block_number = int(line)
            i += 1
            start_time, end_time = lines[i].strip().split(' --> ')  # 获取当前字幕块的开始时间和结束时间
            subtitle_text = ""
            i += 1
            while i < len(lines) and lines[i].strip() != "":
                subtitle_text += lines[i].strip() + " "
                i += 1
            subtitle_blocks.append({
                "number": block_number,
                "start_time": start_time,
                "end_time": end_time,
                "text": subtitle_text.strip()
            })
        else:
            i += 1

    return subtitle_blocks
def sub(a,b):
    return Decimal(str(a)) - Decimal(str(b))

def marg_srt(all_list):
    new_lis=[]
    lis=None
    for li in all_list:
        if lis:
           if lis['end_time']==li['start_time']:
               print(lis['number'])
               lis['text']=lis['text']+li['text']
               lis['end_time']=li['end_time']

           else:
               new_lis.append(lis)
               lis=li

        else:
            lis = li

    if len(li)>0:
        new_lis.append(lis)
    return new_lis
# 示例用法


    

subtitle_file = 'input.srt'  # 字幕文件路径
output_file="out.srt" # 输出文件
subtitle_blocks = parse_subtitle_blocks(subtitle_file)
srt_list=marg_srt(subtitle_blocks)
with open(output_file, 'w', encoding='utf-8') as file:
    for index, block in enumerate(subtitle_blocks):
        file.write(str(index + 1) + "\n")
        file.write(block["start_time"] + " --> " + block["end_time"] + "\n")
        file.write(block["text"] + "\n")
        file.write("\n")
ww
ww
这家伙很懒,什么也没写~
6月前

非常感谢大神,我再研究一下。使用场景:自动生成的英语字幕,如果不合并,翻译成汉语后就错误百出。

再见旧时光
再见旧时光回复ww
QQ:986004469 Email:vutool@qq.com
6月前

喜欢的话 赞助一下哇 开发不易。

ww
ww
这家伙很懒,什么也没写~
6月前

可以赞助的,前天赞助了30,还会赞助,首先感谢你的帮助,我是不懂写代码的,都是找的教程,照抄,我复制你的第二次发的代码,运行,运行的的结果还是有很多时间相接的行没有合并:
合并前:
1
00:00:00,708 --> 00:00:03,333
the ultimate goal is not only to find

2
00:00:03,333 --> 00:00:05,166
three different species of worms here

3
00:00:05,166 --> 00:00:06,291
on the banks of Maine

4
00:00:06,291 --> 00:00:09,000
but also to test out the bite between the bloodworm

5
00:00:09,000 --> 00:00:15,125
the clamworm and the famed sandworm that is a living

6
00:00:15,125 --> 00:00:17,916
oh nightmare look at that thing

7
00:00:20,875 --> 00:00:21,666
get to Diggin

8
00:00:21,666 --> 00:00:22,958
on this bizarre adventure

9
00:00:22,958 --> 00:00:26,458
I will be working alongside the legendary Pat Spain

10
00:00:26,958 --> 00:00:28,875
this man is wildlife biologist

11
00:00:29,000 --> 00:00:30,208
cryptozoologist

合并后:
1
00:00:00,708 --> 00:00:15,12
the ultimate goal is not only to findthree different species of worms hereon the banks of Mainebut also to test out the bite between the bloodwormthe clamworm and the famed sandworm that is a living

2
00:00:03,333 --> 00:00:05,166
three different species of worms here

3
00:00:05,166 --> 00:00:06,291
on the banks of Maine

4
00:00:06,291 --> 00:00:09,000
but also to test out the bite between the bloodworm

5
00:00:09,000 --> 00:00:15,12
the clamworm and the famed sandworm that is a living

6
00:00:15,125 --> 00:00:17,916
oh nightmare look at that thing

7
00:00:20,875 --> 00:00:26,458
get to Digginon this bizarre adventureI will be working alongside the legendary Pat Spain

8
00:00:21,666 --> 00:00:22,958
on this bizarre adventure

9
00:00:22,958 --> 00:00:26,458
I will be working alongside the legendary Pat Spain

10
00:00:26,958 --> 00:00:28,875
this man is wildlife biologist

11
00:00:29,000 --> 00:00:30,208
cryptozoologist

再见旧时光
再见旧时光
QQ:986004469 Email:vutool@qq.com
6月前

第二次把函数换为普通方法的,变量放错了。

srt_list = marg_srt(subtitle_blocks) # 是合并的结果。
#把合并结果 srt_list 来生成srt 。之前错在没有使用合并结果 srt_list
with open(output_file, 'w', encoding='utf-8') as file:
    for index, block in enumerate(srt_list):
aaa=r"C:\Users\Administrator\Desktop\xx\aa.srt"
subtitle_file = aaa  # 字幕文件路径
output_file = "out.srt"  # 输出文件
subtitle_blocks = parse_subtitle_blocks(subtitle_file)
srt_list = marg_srt(subtitle_blocks)

with open(output_file, 'w', encoding='utf-8') as file:
    for index, block in enumerate(srt_list):
        file.write(str(index + 1) + "\n")
        file.write(block["start_time"] + " --> " + block["end_time"] + "\n")
        file.write(block["text"] + "\n")
        file.write("\n")
请先登录
0
1
0
13