二维码和字幕文件看上去毫无关系,但它们有一个共同点:都是体积很小的「交换格式」,一个字符写错,另一台设备就读不出来。Wi-Fi 二维码里的密码带了分号却没转义,手机相机会毫无反应;SRT 的毫秒分隔符写成了点,部分播放器会把整条字幕丢掉。
这篇文章不重复讲工具界面,而是把真正会出问题的地方讲透:二维码的内容该怎么拼、容量和纠错等级怎么取舍、尺寸与静区怎么定;字幕三种格式的时间语法差在哪、转换时哪些信息会丢、怎样用本地工具定位并修正时间轴。全部操作都在浏览器里完成,Wi-Fi 密码、未发布的视频和字幕草稿不会上传到任何服务器。
一、先确定二维码里装什么,再谈样式
二维码本身只是把一串文本编码成黑白方块。扫码软件解出文本之后,由手机系统按文本的「约定写法」决定是打开网页、连接 Wi-Fi 还是保存联系人。所以顺序必须是:先把文本写对,再调尺寸、颜色和纠错等级。ToolGarden 的二维码生成器接收任意文本,它不会替你拼 Wi-Fi 或名片格式,这一步需要你自己确认。
| 用途 | 文本写法 | 常见错误 |
|---|---|---|
| 网页 | https://example.com/promo?id=42 | 漏写 https://,扫出来只是一串文字而不是可点击的链接 |
| Wi-Fi | WIFI:T:WPA;S:网络名;P:密码;; | 名称或密码含 ; , : \ " 时没有加反斜杠转义;开放网络应写 T:nopass |
| 电话 | tel:+8613800000000 | 写成纯数字,部分相机只当文字显示 |
| 邮件 | mailto:hi@example.com?subject=Hello | 主题里的空格和中文没有做 URL 编码 |
| 名片 | BEGIN:VCARD … END:VCARD | 换行被吞掉;每个字段必须独占一行 |
Wi-Fi 二维码的转义规则(最容易踩的坑)
Wi-Fi 载荷用分号分隔字段,所以名称或密码里如果本身带有反斜杠、分号、逗号、冒号或双引号,就必须在它前面加一个反斜杠。另外,如果 SSID 或密码恰好全是十六进制字符(例如 1234abcd),部分解析器会把它当成十六进制串处理,常见做法是用双引号把它包起来。隐藏网络再加一个 H:true 字段。
# 普通 WPA 网络
WIFI:T:WPA;S:Meeting-Room;P:abc12345;;
# 密码含分号和反斜杠:原密码是 pa;ss\word
WIFI:T:WPA;S:Meeting-Room;P:pa\;ss\\word;;
# 开放网络(没有密码)
WIFI:T:nopass;S:Guest;;
# 隐藏网络
WIFI:T:WPA;S:Hidden-Net;P:abc12345;H:true;;二、容量、纠错等级与尺寸:怎样让它真的扫得出来
二维码有 40 个版本,版本 N 的边长是 17 + 4N 个模块(版本 1 是 21×21,版本 40 是 177×177)。内容越长,需要的版本越高,模块越多,同样的打印尺寸下每个模块就越小。纠错等级 L、M、Q、H 分别大约能恢复 7%、15%、25%、30% 的损坏数据,代价是同样内容需要更多模块。下面是字节模式下几个常用版本的容量(单位:字节),可以据此估算你的内容会落在哪个版本。
| 版本(边长) | L | M | Q | H |
|---|---|---|---|---|
| 1(21×21) | 17 | 14 | 11 | 7 |
| 3(29×29) | 53 | 42 | 32 | 24 |
| 5(37×37) | 106 | 84 | 62 | 44 |
| 7(45×45) | 154 | 122 | 86 | 64 |
| 10(57×57) | 271 | 213 | 151 | 119 |
容量按 UTF-8 字节计算,一个汉字占 3 字节,所以中文内容比同样字数的英文更容易把版本顶高。生成结果面板会显示输入的字节数,你可以直接拿它去对照上表。
实例:带统计参数的长链接 vs 短链接
假设要把 https://example.com/spring-sale?utm_source=poster&utm_medium=qr&utm_campaign=2026spring 做成海报二维码,这条链接是 87 字节。默认的 M 级别下版本 5 只能装 84 字节,不够,得升到版本 6(41×41)。换成 28 字节的短链接 https://example.com/s/spring,M 级别下版本 2 只装 26 字节,所以落在版本 3(29×29),模块总数(841 对 1681)正好少了一半。生成器默认输出 320 像素、静区 2 个模块:41×41 的码加两侧静区共 45 个模块,每个模块约 7 像素;29×29 的码共 33 个模块,每个模块约 9.7 像素。同样的海报面积,短链接的模块更大,远距离更容易对焦。
尺寸、静区与扫描距离
- 尺寸:生成器的尺寸范围是 160 到 1024 像素,默认 320。网页展示 240 像素以上通常够用;要印刷,直接导出 1024 像素再在排版软件里缩小,比放大小图清晰得多。
- 静区:二维码规范要求四周留 4 个模块宽的空白,生成器默认只有 2(可调 0 到 8)。要印刷或贴在深色背景上,建议调到 4。静区被图案、边框或相邻文字侵占,是「屏幕上能扫、纸上扫不出」最常见的原因。
- 对比度:生成器使用近黑色模块(#111111)和白色背景,对比度已是最高,不需要再调色。不要自己把它反色再放到深色底上,部分扫码软件对反色码的支持不稳定。
- 扫描距离:行业里常用的经验值是扫描距离约为码宽的 10 倍。2 厘米见方的码大约在 20 厘米处最好扫;展板上的码要按观看距离反推尺寸。
加中心 logo 的代价
在生成器里上传 logo 时,纠错等级会自动切到 H,logo 的白底圆角外框占码边长的 28%,约 7.8% 的面积(0.28² ≈ 0.078),logo 图案本体占边长的 22%。这部分被遮住的数据靠 H 级约 30% 的冗余兜底,所以不要指望再把 logo 放大。更要紧的是,H 级让同样内容的版本升高:一条 40 字节的链接在 M 级是版本 3(29×29),在 H 级要版本 5(37×37),模块变小,扫描距离缩短。如果二维码本来就要印在小标签上,宁可不放 logo。
三、识别与验证:印刷之前让「另一台设备」读一遍
二维码识别工具支持上传 PNG、JPG、WebP、GIF、BMP 图片(单个文件不超过 12MB,像素不超过 2400 万),也可以打开摄像头实时扫描,两者都在本地用 jsQR 解码,图片和视频帧不会发送出去,解码时还会尝试反色图案。它的价值有三点:
- 印刷前验证:把准备送印的 PNG 拖进去,确认解出的文本与你输入的逐字一致,尤其是 Wi-Fi 的转义和 URL 的参数。
- 安全查看陌生二维码:先看解出的文本再决定是否访问,而不是让手机相机直接跳转。短链接和带跟踪参数的长链接在这里一目了然。
- 定位「扫不出来」:把现场拍的照片拖进去。如果工具也解不出,问题通常在图像本身(反光、倾斜、太小、静区被占);如果工具能解、手机相机不能,问题多半在内容格式(Wi-Fi 转义、系统不支持的协议头)。
| 症状 | 最可能的原因 | 怎么排查 |
|---|---|---|
| 屏幕能扫,纸上扫不出 | 静区被侵占、打印分辨率不足、模块被油墨糊住 | 导出 1024 像素版本,静区调到 4,拍印样放进识别工具 |
| 扫出来是乱码文字 | 编码或内容被截断 | 对比识别结果与原文本,查看字节数是否超过版本容量 |
| Wi-Fi 码扫了没反应 | 头部不是 WIFI:,或密码里的特殊字符没转义 | 用识别工具读出文本,逐字段检查分号与反斜杠 |
| 加了 logo 后偶尔扫不出 | logo 占用面积过大,H 级冗余被用尽 | 换小 logo,或去掉 logo 并缩短内容 |
| 远处扫不出,近处可以 | 模块太小 | 缩短内容(改短链接)、放大打印尺寸 |
四、字幕:SRT、VTT、LRC 的语法差在哪
三种格式都是纯文本,差别集中在时间戳的写法和能携带的信息。理解这些差别,才能知道转换时哪些东西会丢、为什么播放器不认。
| 项目 | SRT | WebVTT | LRC |
|---|---|---|---|
| 时间写法 | 00:01:02,500(毫秒前是逗号) | 00:01:02.500(点号),小时可省略为 01:02.500 | [01:02.50](分:秒.百分秒) |
| 是否有结束时间 | 有,用 --> 连接开始与结束 | 有,同 SRT | 通常只有开始时间,结束默认到下一行开始 |
| 文件头 | 无,每条以序号开头 | 必须以 WEBVTT 开头 | 可带 [ti:] [ar:] 等标签 |
| 附加能力 | 基本无(常夹带 HTML 标签) | 位置/对齐设置、NOTE 注释、STYLE 样式 | 歌词行级同步,部分扩展支持逐字 |
| 典型场景 | 本地播放器、剪辑软件、视频平台上传 | 网页 video 标签的 track | 音乐播放器歌词 |
字幕工具的实际行为(从代码确认)
- 格式识别:先看文件扩展名(.vtt/.srt/.lrc),其次看内容是否以 WEBVTT 开头(兼容 BOM),再看是否含 -->,含则当 SRT,否则当 LRC。
- 导出 SRT 时序号总是从 1 重新编号,并按开始时间排序;导出 VTT 会补上 WEBVTT 头;导出 LRC 时每行是 [分:秒.百分秒]<分:秒.百分秒>文本,同时写入开始和结束时间,多行文本会被折叠为一行。
- 导入 LRC 时 [ti:] [ar:] [al:] [by:] [offset:] 这类标签行会被跳过,其中 [offset:] 不会被应用到时间上。
- 一行 LRC 可以带多个时间标签(重复副歌),会展开成多条字幕。
- 编辑器可以加载本地音频或视频,点击表格行即可跳到对应时刻;播放到某个位置后点「设为开始」或「设为结束」就能把当前播放时间写进选中的字幕;也可以直接在时间单元格里手改。如果结束时间不晚于开始时间,会自动设成开始后 1 秒。
实例一:LRC 转 SRT,注意那个固定的 3 秒
LRC 没有结束时间。工具的处理是:每行先默认持续 3 秒,如果下一行更早开始,就截到下一行开始为止。
# 输入 LRC
[ti:Demo]
[00:12.00]Hello world
[00:15.50]Second line
[00:21.00]Third line
# 输出 SRT
1
00:00:12,000 --> 00:00:15,000
Hello world
2
00:00:15,500 --> 00:00:18,500
Second line
3
00:00:21,000 --> 00:00:24,000
Third line注意第二行在 18.5 秒就消失了,而第三行 21 秒才出现,中间有 2.5 秒空白。如果你希望字幕一直挂到下一句出现,就需要在编辑器里把每条的结束时间改成下一条的开始时间。长间奏的歌词最容易遇到这种情况。
实例二:SRT 转 VTT 给网页播放器用
# 输入 SRT
1
00:00:01,000 --> 00:00:03,500
欢迎观看
# 输出 VTT
WEBVTT
00:00:01.000 --> 00:00:03.500
欢迎观看<video controls src="demo.mp4">
<track kind="subtitles" src="demo.vtt" srclang="zh" label="中文" default>
</video>网页里的 track 要求字幕文件与页面同源,或服务端返回允许跨域的响应头,并且 MIME 类型应为 text/vtt。在本地直接双击打开 HTML 时,浏览器往往因为 file:// 的限制不加载字幕,这不是字幕文件的问题。
五、字幕常见故障与排查
| 现象 | 原因 | 处理 |
|---|---|---|
| 导入后提示没有有效字幕行 | 文件不是 SRT/VTT/LRC,或时间行写法不符 | 检查是否有 --> ;LRC 是否是 [分:秒.xx] |
| VTT 里部分字幕没读到 | 时间写成 01:02.500(省略小时),而工具要求「时:分:秒」三段 | 手动补成 00:01:02.500 再导入 |
| 中文变成乱码 | 原文件是 GBK、Big5 等非 UTF-8 编码,工具按 UTF-8 读取 | 先用文本编辑器另存为 UTF-8 再导入 |
| 转 VTT 后位置、对齐设置没了 | cue 设置(position、align)和 NOTE、STYLE 块不会被保留 | 转换后需要手动在 VTT 中补回,或确认是否真的需要 |
| LRC 转出来整体偏早或偏晚 | 原文件有 [offset:] 标签,工具会跳过它 | 把偏移量手动折算到每条的时间里 |
| 歌词一闪而过 | LRC 无结束时间,默认只显示 3 秒 | 在编辑器里延长结束时间 |
整体平移时间轴:工具没有一键功能时怎么办
字幕制作工具可以逐条设置开始和结束,但没有「全体延后 2.5 秒」这样的批量按钮。如果整条时间轴只是统一偏移,用下面这个小脚本对 SRT 文本做一次平移更省事,在浏览器开发者工具的控制台里粘贴运行即可,再把结果贴回字幕工具做最终检查。
const shiftMs = 2500; // 正数延后,负数提前
const pad = (n, w) => String(n).padStart(w, '0');
function shiftSrt(srt) {
return srt.replace(/(\d{2}):(\d{2}):(\d{2}),(\d{3})/g, (_, h, m, s, ms) => {
const total = Math.max(0, ((+h * 60 + +m) * 60 + +s) * 1000 + +ms + shiftMs);
return pad(Math.floor(total / 3600000), 2) + ':' +
pad(Math.floor(total % 3600000 / 60000), 2) + ':' +
pad(Math.floor(total % 60000 / 1000), 2) + ',' + pad(total % 1000, 3);
});
}六、什么时候不该用这套方法
- 需要统计扫码次数、能随时改目标网址的「活码」:静态二维码一旦印出就改不了,这类需求要用带跳转服务的方案,并接受它的隐私和长期可用性代价。
- 支付、登录凭证等高敏感内容:二维码只是编码,不是加密。
- 超长文本:内容接近版本 40 的上限时模块极密,几乎无法可靠扫描,应改为链接或文件下载。
- 带样式的字幕:ASS/SSA 的字体、颜色、卡拉 OK 特效,以及烧录进画面的硬字幕,不在 SRT/VTT/LRC 的表达范围内。
- 自动听写:字幕制作工具负责编辑、校时和转换,本身不识别语音。
- 逐字高亮的卡拉 OK 歌词:每行的时间标签之后的词级时间不会被解析。