ESC
开源 更新于 2026-08-01 00:00 3 分钟阅读

decimen-optical-transfer

GitHub 开源项目 decimen-optical-transfer(TypeScript),⭐ 2675

来源:GitHub

Decimen Optical Transfer: fountain-coded QR file transfer

Send a file between two devices using nothing but a screen and a camera. One page displays the file as an endless stream of animated QR codes; another device points its camera at it and reconstructs the file. No network path between the devices, no app, no pairing, no permissions beyond the camera. The payload travels as light.

This is a minimal proof of concept extracted from a larger experiment that reached 128 KB/s phone-to-phone with denser frames, multi-code grids, and an error-corrected color channel. This PoC keeps only the essential trick and transmits a 512 KB image (or a 2 MB one, selectable in the sender’s settings) at a comfortable rate.

Phone receiving a 2 MB image over light: 129.2 KB/s goodput, decoding the sender's animated QR code

Mid-transfer: a phone pulling a 2 MB image out of the air at 129 KB/s.

Try it

npm install
npm run dev
  • On the sending device (a laptop is ideal): open https://localhost:5173/send/ and it starts streaming immediately. Max screen brightness helps.
  • On the receiving device (a phone): open the Network URL Vite prints (https://<lan-ip>:5173/receive/), accept the certificate warning once, tap Start camera, and point it at the code.
  • A few seconds later: Transfer Complete! and the received image, verified by hash.

Why the dev server is https-only: the receiver uses getUserMedia, and browsers remove that API entirely on insecure origins: a phone reaching your dev server over plain http has no camera, full stop (localhost is exempt, but your phone isn’t localhost). That’s a web platform rule, not a choice. The dev server therefore ships with a self-signed certificate (@vitejs/plugin-basic-ssl); the browser will warn on first visit. Tap “Show Details” then “visit this website” (iOS) or “Advanced” then “Proceed” (Android/desktop), and the page is still a secure context, so the camera works. The odd-looking lvh.me hosts Vite prints are a public convenience domain that resolves to 127.0.0.1 (same machine, nothing extra running).

Hold the phone steady, or better, prop it against something. Camera autofocus hunting from hand tremor is the #1 throughput killer.

How it works

The one-way channel problem. A screen-to-camera link has no back-channel: the receiver can’t ask for retransmission, and it will inevitably miss frames (blur, refresh straddling, autofocus). Looping the frames and hoping is miserable: miss one frame and you wait a full cycle for it to come around.

Fountain codes fix this completely. The sender never sends the file’s blocks directly. Each frame is the XOR of a pseudorandom subset of blocks; the subset is derived deterministically from the frame’s sequence number, with subset sizes drawn from a robust-soliton distribution ([Luby transf


(内容已截断,完整内容请访问 GitHub 仓库)