如何用C#实现SRT(SubRip)字幕文件的时间偏移调整?
如何用C#编写简单工具调整SRT字幕的时间偏移
SRT是常用的字幕文件格式,典型结构如下:
1 00:05:00,400 --> 00:05:15,300 This is an example of a subtitle. 2 00:05:16,400 --> 00:05:25,300 This is an example of a subtitle - 2nd subtitle.
要实现时间偏移调整,核心是解析SRT的时间戳、加上偏移量后重新生成合法的SRT文件,具体实现步骤如下:
1. 定义字幕条目模型
先创建类存储单条字幕的核心信息:
public class SubtitleEntry { public int Index { get; set; } public TimeSpan StartTime { get; set; } public TimeSpan EndTime { get; set; } public List<string> Lines { get; set; } = new List<string>(); }
2. 解析SRT文件
逐行读取文件,按SRT规则拆分出每个字幕条目:
public static List<SubtitleEntry> ParseSrt(string filePath) { var entries = new List<SubtitleEntry>(); var lines = File.ReadAllLines(filePath); int i = 0; while (i < lines.Length) { // 跳过空行 if (string.IsNullOrWhiteSpace(lines[i])) { i++; continue; } var entry = new SubtitleEntry(); // 读取字幕编号 entry.Index = int.Parse(lines[i]); i++; // 读取时间戳行并转换为TimeSpan var timeLine = lines[i].Split(new[] {" --> "}, StringSplitOptions.None); entry.StartTime = ParseTimeSpan(timeLine[0]); entry.EndTime = ParseTimeSpan(timeLine[1]); i++; // 读取字幕内容直到空行 while (i < lines.Length && !string.IsNullOrWhiteSpace(lines[i])) { entry.Lines.Add(lines[i]); i++; } entries.Add(entry); } return entries; } // 转换SRT时间格式(HH:mm:ss,fff)为TimeSpan private static TimeSpan ParseTimeSpan(string timeStr) { var parts = timeStr.Replace(',', '.').Split(':'); var hours = int.Parse(parts[0]); var minutes = int.Parse(parts[1]); var seconds = double.Parse(parts[2]); return TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes) + TimeSpan.FromSeconds(seconds); }
3. 调整时间偏移
给所有字幕的时间戳加上指定偏移量(正数延后,负数提前):
public static void AdjustTimeOffset(List<SubtitleEntry> entries, TimeSpan offset) { foreach (var entry in entries) { entry.StartTime += offset; entry.EndTime += offset; // 避免出现负时间戳 if (entry.StartTime < TimeSpan.Zero) entry.StartTime = TimeSpan.Zero; if (entry.EndTime < TimeSpan.Zero) entry.EndTime = TimeSpan.Zero; } }
4. 生成新的SRT文件
将调整后的字幕重新格式化为SRT标准格式并写入文件:
public static void WriteSrt(List<SubtitleEntry> entries, string outputPath) { using var writer = new StreamWriter(outputPath); foreach (var entry in entries) { writer.WriteLine(entry.Index); writer.WriteLine($"{FormatTimeSpan(entry.StartTime)} --> {FormatTimeSpan(entry.EndTime)}"); foreach (var line in entry.Lines) { writer.WriteLine(line); } writer.WriteLine(); } } // 转换TimeSpan为SRT时间格式(HH:mm:ss,fff) private static string FormatTimeSpan(TimeSpan time) { return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2},{time.Milliseconds:D3}"; }
5. 调用示例
在主函数中整合流程,完成完整的字幕调整:
static void Main(string[] args) { string inputPath = "input.srt"; string outputPath = "output.srt"; // 偏移量示例:延后2秒(正数),提前1.5秒用TimeSpan.FromSeconds(-1.5) TimeSpan offset = TimeSpan.FromSeconds(2); var entries = ParseSrt(inputPath); AdjustTimeOffset(entries, offset); WriteSrt(entries, outputPath); Console.WriteLine("字幕时间调整完成!"); }
注意事项
- 偏移量正负值对应字幕显示的延后/提前
- 处理时会自动过滤负时间戳,避免生成非法格式
- 该工具适配标准SRT格式,若遇到带样式标记的特殊SRT,需额外适配解析逻辑
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

