本帖使用社区开源推广,符合推广要求。我申明并遵循社区要求的以下内容:
- 我的帖子已经打上 开源推广 标签: 是
- 我的开源项目完整开源,无未开源部分: 是
- 我的开源项目已链接认可 LINUX DO 社区: 是
- 我帖子内的项目介绍,AI生成、润色内容部分已截图发出: 是
- 以上选择我承诺是永久有效的,接受社区和佬友监督: 是
以下为项目介绍正文内容,AI生成、润色内容已使用截图方式发出
(本项目已在readme.md 友链linux.do社区)
live demo: https://qr.linkto.host/
github 链接: GitHub - infrost/RaptorQR: Ultra-fast offline file and text transfer over animated QR codes with WASM fast_qr, ZXing and RaptorQ. · GitHub
这个项目大概是前段时间突发奇想,想看看“离线摄像头拍屏幕识别数据”这条赛道的上限大概在哪。
如果你不想看我叨叨的话,太长不快就是:工程实现上已经能稳定100-200多KB/s,上限应该在几百KB/s。,iPhone16上测得传6.5MB文件用时44s,目前我应该是做到了这个赛道的全网最快。(4QR并行,每秒30X4=120张二维码)
(benchmark下按这个参数跑全流程,1200个随机二维码,随机丢200个二维码,20% repair rate的模拟理论值大约是180KB/s,已经很接近上限了,仓库里有可以复现的benchmark和test,当然最好的方法就是实际扫码感受一下)
一开始是想像 sz3/libcimbar / Cimbar 那种自定义彩色码或者Aztec Code之类的编码,后来发现虽然彩色码信息高,但是识别逻辑远没有二维码成熟,ZXing还有wasm的识别方案,能做到我手机(iPhone16)上测得平均每秒钟识别100+个V30二维码(V20甚至能测到了每秒钟300个码)
二维码传文件编码上面难点就是漏扫二维码/不按顺序扫/怎么办。不过好消息是fountain code并不是个特别冷门的领域,而且很多卫星向地球广播的方案都要用类似编码。为了速度和正确性我就没有重复造轮子,拿了raptorQ标准(RFC6330)的rust实现,然后我把它编译成了wasm。
最后的瓶颈是二维码生成,大部分现有的纯二维码传文件项目速度其实都卡在这里。我也是同样的操作把rust实现的fastqr编译成了wasm,然后js(typescript)直接内存直读fastqr的生成区的原始二维码矩阵,后台走web worker多线程并行生成,然后用rAF丢到canvas里面去画二维码再插值放大。这个三板斧下来,生成可以在我浏览器上8个二维码@60fps也就是每秒钟480个二维码都没有压力。
(zxing writer其实也能生成二维码,但是测下来zxing的二维码生成能力甚至不如纯js的二维码生成逻辑,可能是因为来回拷贝数据和gc的问题,所以我编译wasm的时候直接让它划出一块区间永远在上面写数据,就不用gc了)
直觉上根据传奇祖师爷香农的guide,要想完美还原信号,采样率至少要是原始信号频率的两倍。手机摄像头api能暴露出来的最多就60fps,那比较不浪费资源的生成速率实际上只有30fps了。虽然我这个直觉毫无道理吧,但我在测试上真就发现,对于一个60fps的摄像头来说,30fps确实是个甜点区间,再高的话二维码识别速率其实反而会降低,我不知道是因为物理屏幕刷新率和二维码生成帧之间的某种问题,还是LCD像素切换的残影问题(我是165HZ的屏幕,可能240HZ的会比较好),还是实际上手机采样率根本到不了60fps又或者是快门速度问题,总之就是效果没那么好,但具体为什么还需要后续去验证。
我屏幕是16寸的,测试下来大概是4个二维码平行扫描,大小是V30,30fps能达到最佳的效率。
这个项目用了monorepo,所以想要底层的wasm包来研究,可以直接npm/pnpm install我的包;或者玩玩就用我的live demo或者自己vercel跑跑玩玩。
just for fun
