" 两边,再对每段按 ":" 和">

C# 操作字幕文件 C#如何解析和创建SRT或VTT格式的字幕

来源:这里教程网 时间:2026-02-21 17:42:46 作者:

解析 SRT 字幕时,时间戳格式不匹配就直接崩

常见错误是用

DateTime.Parse
直接转
"00:01:23,456"
,但 SRT 的毫秒分隔符是逗号,而 .NET 默认认点号;更糟的是有些文件用分号(老版规范),或缺前导零。一解析就抛
FormatException

正确做法是手写解析逻辑,别依赖通用时间解析:

string.Split
拆开
"-->"
两边,再对每段按
":"
","
";"
分割
小时、分钟、秒转
int
,毫秒部分用
int.TryParse(..., out var ms)
防逗号/分号混用
构造
TimeSpan
new TimeSpan(0, hours, minutes, seconds, ms)
,别碰
DateTime

示例片段:

var parts = line.Split(new[] { " --> " }, StringSplitOptions.None);
var startParts = Regex.Split(parts[0].Trim(), @"[:;,]");
// 然后逐段 int.TryParse

VTT 解析要小心头部的 WEBVTT 声明和注释行

很多人直接

File.ReadAllLines
后从第 0 行开始 parse,结果把
WEBVTT
、空行、
NOTE
行当成了字幕块,导致索引错乱、ID 错位。

VTT 是有明确起始标识的文本格式,必须跳过非字幕内容:

逐行读,遇到第一个符合
^\d+$
的行才开始当作序号(可选),下一行才是时间轴
时间轴行必须含
-->
且前后都有有效时间格式,否则跳过
字幕正文以空行结束;遇到新序号或 EOF 才收尾当前条目 别假设每条都带序号——VTT 允许省略,SRT 则强制有

生成 SRT/VTT 时,换行和编码不处理好,播放器直接拒载

Windows 记事本打开正常,PotPlayer/VLC 却显示乱码或只读第一行?大概率是用了

\n
换行 + UTF-8 无 BOM。SRT/VTT 规范要求 CRLF(
\r\n
),且多数播放器(尤其旧版)只认 UTF-8 with BOM。

写文件时两个关键点不能漏:

Encoding.UTF8.GetBytes
+
File.WriteAllBytes
,或指定
new StreamWriter(path, false, new UTF8Encoding(true))
true
表示带 BOM)
每行结尾必须是
"\r\n"
,别用
Environment.NewLine
——它在 Linux/macOS 是
\n
,会坏掉
SRT 序号后必须跟
\r\n
,时间行后也必须跟
\r\n
,字幕正文末尾不能多一个空行

时间精度差异会让字幕快进或延迟几帧

SRT 只支持毫秒(三位),VTT 支持毫秒甚至微秒(但实际只取三位)。如果你从视频帧时间(比如 23.976 fps 下的

TimeSpan.FromTicks
)直接 ToString() 写入,可能生成
00:01:23.456789
这种非法格式,部分播放器截断、部分报错。

统一做截断处理:

提取总毫秒数:
(int)timeSpan.TotalMilliseconds % 1000
避免四舍五入——字幕对齐靠的是向下取整,否则 999.8ms 会进到下一秒,造成跳断 VTT 中时间推荐用
hh:mm:ss.fff
格式输出,SRT 同理,但分隔符用
,

真正麻烦的是跨格式转换:SRT 转 VTT 时,别把

,456
直接换成
.456
就完事,得确认原始时间源有没有被 double 转换污染过——浮点误差叠一次就偏 1~2ms,连播 10 分钟可能偏半秒。

相关推荐