导语:WiFi?不存在的。蓝牙?不需要。共享网络?No。两台设备之间唯一需要的就是:屏幕、摄像头,还有光。一位开发者出于对广告和劣质流媒体的不满,用 Claude Code 一晚上写出了 Decimen——一个用屏幕闪烁 QR 码流传输文件的极客玩具,目前在 GitHub 已获得 375 星。条条大路通 shell,条条大路也通文件。
一、事情起因:被广告逼出来的灵感
故事的起点很接地气——开发者受够了广告和糟糕的流媒体体验。
他想要一个缓存式 MP3 播放器,还要能方便地把歌曲从一台手机传到另一台手机。最关键的诉求是:两台手机不需要处于同一个网络。
然后他意识到:闪烁的 QR 码本身就能携带数据。
一晚上,整个可工作的原型就诞生了。
二、这个工具怎么玩?
Decimen Optical Transfer 的玩法简单粗暴:
- 发送端:打开
https://localhost:5173/send/ ,屏幕立刻开始闪烁 QR 码流(建议最大亮度)
- 接收端:打开 Vite 打印的网络 URL
https://:5173/receive/ ,允许摄像头权限,把相机对准屏幕
- 几秒钟后:屏幕上跳出 "Transfer Complete!",接收到的文件已通过哈希校验

实战数据:
- 传输速率:约 129KB/s(手持状态)
- 优化后:手持 128KB/s,稳定放置 186KB/s
- 一张 2MB 图片:几秒钟搞定
三、技术核心:喷泉码
这个项目最聪明的地方在于它解决了单向传输的死结:
屏幕→摄像头是单向链路——接收方永远没法告诉发送方“我漏了一帧”。
传统做法是把所有帧循环播放,指望接收方凑齐。但这种方式很烂:漏了一帧,你得等整整一轮才能等到。
Decimen 用的是喷泉码(Fountain Codes):
发送方永远不会直接发送文件的原始分块。每一帧是文件所有分块的一个伪随机子集的异或组合。子集根据帧序号确定性派生,子集大小服从鲁棒孤子分布(Robust Soliton Distribution)。
接收方只需要收集到大约 K×1.15 个不同的帧(K 是文件的分块总数),按任意顺序都行,就能“剥洋葱”一样把文件还原出来。
核心优势:
- 丢帧只是损失一点时间,不会破坏传输的正确性
- 发送方和接收方的帧率根本不需要匹配
- 接收方可以中途开始对准屏幕,立刻锁定传输
如果你对这种编码背后的数学原理以及相关精妙的算法设计感兴趣,它们都属于算法/数据结构领域的经典应用场景。
四、实现细节:踩过的坑
这个项目用纯 Web 技术实现,但有几个坑值得说道:
4.1 浏览器引擎的地狱
不同 JavaScript 引擎对 Math.log 的实现有微差。喷泉码要求发送方和接收方构造比特一致的孤子分布,否则 V8 和 JavaScriptCore 之间的差异会让整个传输静默失败。解决方案:自己手写一个确定性的 log 函数,严格按 IEEE-754 规范操作。
4.2 iOS 的摄像头谎言
iOS 对 frameRate: {ideal: 60} 静默返回 30 帧,必须用 {exact: 60} 才能真正拿到 60 帧(1280 宽度的捕获下)。然后还要fallback。每次都要读回 getSettings() 验证。
4.3 帧回调的僵尸问题
requestVideoFrameCallback 的回调链会跨越流生命周期存活,下次流开启时会被旧的回调链接管。没有代际计数器(generation counter),每次 stop/start 都会泄漏一个僵尸捕获循环。
4.4 进度条的假象
LT 算法的 peeling 求解是后置级联的——前面大部分时间看起来像卡在原地,最后突然跳到 100%。所以进度条必须跟踪已收集的帧数,而不是已求解的块数。
4.5 QR 纠错等级的选择
QR 内置纠错(ECC)和喷泉码解决的是不同问题(损坏 vs 擦除)。Decimen 选最小纠错等级(L)——帧级 ECC 加喷泉码是更优的组合。
五、配置参数
发送端和接收端都有可调参数:
发送端(Settings 面板):
| 参数 |
默认值 |
说明 |
| payload size |
512KB / 2MB |
传输文件大小选择 |
| tx fps |
24 |
每帧至少占 2 个显示刷新周期 |
| bytes / frame |
1465(QR v27) |
接收端能解的情况下越密越快;2953(v40)在近距离手机上可用 |
| error correction level |
L |
见 4.5 |
| display size |
- |
QR 码显示尺寸 |
接收端:
| 参数 |
说明 |
| capture width |
摄像头捕获宽度 |
| capture fps |
解码摄像头帧率 |
| decode worker count |
解码工作线程数 |
六、相关项目
作者提到这个概念并非原创,有几个前辈值得一看:
- mohankumarelec/airgapped-qr-code-transfer:浏览器端的 QR 文件传输,带压缩和顺序分块
- divan/txqr(2018):Go 写的动画 QR+喷泉码方案,有两篇优秀文章解释为什么喷泉码比循环播放好
- sz3/libcimbar:超越了 QR,自己设计了一种高密度彩色码专为这个信道设计
值得一提的是,喷泉码这种精巧的编码方案,其设计思想与计算机基础领域中的核心原理密不可分,值得深入探究。
七、演示视频
开发者演示 Demo:手机对准笔记本屏幕,几秒钟完成一张图片的传输
八、开源信息
出处:本文综合编译自 X 平台 Om Patel 的推文,原文地址:https://x.com/om_patel5/status/2083055062054539572

想了解这类极客项目的更多玩法或与同好交流,不妨来云栈社区看看。