You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

VTT字幕时间戳修改问题:Python代码写入位置错误求助

解决VTT字幕时间戳替换后内容写入位置错误的问题

嘿,我明白你遇到的麻烦了——你的代码现在把修改后的时间戳行一股脑写在文件开头,既没保留不需要修改的行,也没替换对应位置的原内容对吧?咱们来搞定这个问题。

问题根源

你原来用了r+模式打开文件,然后seek(0)后直接写入修改后的行,但这种方式有两个问题:

  1. 只处理了时间戳行,完全丢掉了字幕序号、台词内容这些不需要修改的行;
  2. 从文件开头写入会直接覆盖原有内容,导致所有新内容堆在开头,结构完全乱掉。

解决方案:先处理所有行,再一次性写入

正确的思路是先把文件里的每一行都读出来,处理需要修改的时间戳行,保留其他行,最后把完整的处理结果一次性写入文件。这样既能保证所有行都在正确位置,也不会覆盖出错。

这里给你补全并优化后的代码:

from sys import argv

script, filename = argv
# 把输入的调整系数转成浮点数,避免字符串运算错误
adjustment = float(input("Adjustment multiplier: "))

# 先读取所有行并处理,把结果存在列表里
processed_lines = []
with open(filename, "r") as video:
    for line in video:
        # 保留换行符的处理,避免最后格式混乱
        stripped_line = line.rstrip('\n')
        # 判断是否是时间戳行(用-->来判断更准确)
        if "-->" in stripped_line:
            # 分割开始和结束时间戳
            start_str, end_str = stripped_line.split(" --> ")
            
            # 定义工具函数:把时间字符串转成毫秒数
            def time_to_ms(time_str):
                hours, mins, sec_ms = time_str.split(':')
                secs, ms = sec_ms.split('.')
                return int(hours)*3600000 + int(mins)*60000 + int(secs)*1000 + int(ms)
            
            # 计算调整后的毫秒数
            adjusted_start_ms = time_to_ms(start_str) * adjustment
            adjusted_end_ms = time_to_ms(end_str) * adjustment
            
            # 定义工具函数:把毫秒数转回VTT格式的时间字符串
            def ms_to_time(ms):
                hours = int(ms // 3600000)
                ms %= 3600000
                mins = int(ms // 60000)
                ms %= 60000
                secs = int(ms // 1000)
                remaining_ms = int(ms % 1000)
                # 用格式化字符串保证两位数的时/分/秒,三位数的毫秒
                return f"{hours:02d}:{mins:02d}:{secs:02d}.{remaining_ms:03d}"
            
            # 生成新的时间戳行
            new_timestamp_line = f"{ms_to_time(adjusted_start_ms)} --> {ms_to_time(adjusted_end_ms)}"
            processed_lines.append(new_timestamp_line)
        else:
            # 非时间戳行直接保留(比如字幕序号、台词内容)
            processed_lines.append(stripped_line)

# 把处理后的所有内容写入文件(w模式会清空原文件后写入,保证内容正确)
with open(filename, "w") as video:
    # 把列表里的行用换行符连接,最后再加一个换行保证文件格式正确
    video.write('\n'.join(processed_lines) + '\n')

关键优化点

  • with语句管理文件,不用手动调用close(),既安全又省心;
  • 优化了时间戳行的判断逻辑(用-->),比原来的l[:2] == "00"更准确,不会误判其他开头是00的行;
  • 把所有处理后的行存在列表里,最后一次性写入,保证整个文件的结构和原文件一致,只是替换了时间戳;
  • 补全了时间戳和毫秒的转换逻辑,确保格式完全符合VTT要求。

内容的提问来源于stack exchange,提问作者Will Howard

火山引擎 最新活动