频道字幕导成本地索引后,播放器时间轴对不上
给一个更新了三年的频道做字幕检索,本地已经用 yt-dlp 拉下了约 900 条 vtt,总时长加起来 60 多小时。做完索引后,用播放器跳转到字幕命中的时间点,画面总是比字幕慢两三秒,而且长视频偏得更明显。
我先怀疑索引里的时间戳写错了,后来把一条 vtt 的 cue 直接对到视频上,发现字幕本身是准的,问题出在索引里的时间字段和播放器用的时间基准不一致。vtt 里的 00:12:34.500 是相对视频起点的,但我的索引把时间转成了秒后,又按数据库里的 published_at 那套时区逻辑处理了一遍,等于多加了偏移。
做法很简单:索引只存相对秒数,不碰时区,播放器跳转时直接用这个秒数。解析 vtt 时把 HH:MM:SS.mmm 转成浮点秒:
import re
def vtt_ts(s):
h, m, rest = s.split(':')
sec, ms = rest.split('.')
return int(h) * 3600 + int(m) * 60 + int(sec) + int(ms) / 1000
入库字段用 REAL 存秒,别用 TIME 或带时区的 TIMESTAMP。查询命中后返回 start_sec,播放器那边 currentTime = start_sec 就完事。
代价是索引里丢了原始文本格式,想回看某条 cue 的原文得回 vtt 文件里翻;另外浮点秒在长视频里有毫秒级误差,60 分钟大概差 3 毫秒,对字幕定位够用,但如果要做逐帧对齐就不行。
失效的地方我也踩过:一是自动生成的字幕 vtt 里 cue 有重叠,同一条字幕会拆成多个时间片,索引里按 start_sec 排序后会出现重复文本,得去重;二是有些老视频的 vtt 是 WEBVTT 头后直接跟样式块,正则匹配时间行会误抓 STYLE 里的内容,得先跳过非 cue 块;三是视频被平台重新转码后时长会变,本地索引的秒数就对不上了,只能重拉。
现在索引跑起来能用了,但我还没想好怎么处理频道里那些后来被删掉或设为私有的视频,索引里留着它们的字幕,播放器打开会 404。你们本地归档时是定期清理失效条目,还是留着当历史记录?
0 条评论
还没有评论,写下第一条。