Copy data between MacBooks visually, using flashing screens and cameras
Warning! The transmit portion of this project rapidly flashes the entire screen (at ~15 Hz) in order to send data. Please be forewarned in case you or others are sensitive to flashing lights. You can still read the source, though!
John J. Workman (@workmajj)
I worked on this software during my time as a Recurse Center facilitator. If you'd like to join a warm community of programmers dedicated to self-improvement, you should consider applying. :-)
(Thanks to Jess Sorrell and Tom Ballinger for inspiring this hack!)
This project consists of two programs which together let you copy data between MacBooks visually, without traditional direct or networked connections. The programs—a transmitting half (tx
) and a receiving half (rx
)—operate after aligning the two computers physically, so the transmitting laptop's screen faces the receiving laptop's camera. The transmitting MacBook then flashes its screen in a pattern representing binary data, which the receiving machine sees and decodes.
Because of how rgbcp
accesses the camera—piping in raw bytes via ffmpeg
's avfoundation
device—it does require OS X. The C source is platform-independent, however. At some point I may write camera code in Objective-C.
I was inspired to do this project after reading a tweet in which Jess Sorrell and Tom Ballinger described similar work. I didn't know the details of their implementation, though, so I started imagining how I would solve the problem from scratch. I compared notes with Tom a few weeks later at RC, and it turns out we had very similar approaches. I think Jess and Tom ended up doing a few nice features (e.g., adaptive frames) that hadn't even occurred to me, however!
TODO
To use rgbcp
to copy data between two MacBooks:
-
rgbcp
depends onncurses
for sending andffmpeg
for receiving. Recent versions of OS X includencurses
by default, but you'll need to installffmpeg
. Using Homebrew:$ brew install ffmpeg
-
Next, clone the project from GitHub on both computers and build it from source:
$ git clone https://github.com/workmajj/rgbcp.git $ cd rgbcp $ make
-
If the transmitting computer's terminal uses a non-standard color palette like Solarized, you'll need to revert it temporarily. Colors don't need to be exact, but red, green, and blue should look roughly correct.
-
Now pick some data you'd like to send, and cue up the transmitting computer. Try not to choose something huge because
rgbcp
's throughput is low (7.5 bytes/sec)—text will do just fine. Type this, but don't run it yet:$ echo "How funny you are today New York" | ./tx
-
And cue up (but don't run) this on the receiving MacBook:
ffmpeg -loglevel panic -f avfoundation -pixel_format 0rgb -framerate 30 \ -video_size 320x240 -i "default:none" -f rawvideo - | ./rx
-
Place both laptops so that they face each other on a level surface, ideally close enough that they touch.
-
Finally, start the receiving computer (it should know to wait on a special input pattern), and then start the transmitting computer. The receiving MacBook will print the text to
stdout
as it comes across and is decoded. -
Feel free to try this again using binary data. You can pipe in any type of file through
stdin
.
If you don't have two MacBooks, you can test the receiving half (rx
) by transmitting data from a mobile device:
-
Starting from the project directory, use your laptop to serve the HTML/JS test pages:
$ cd test $ python -m SimpleHTTPServer 8000
-
Then, in another terminal window, get your machine ready to receive data as usual.
-
Finally, open a test page on your phone by navigating to
http://<laptop_ip_address>:8000/text.html
, and quickly place your phone's display in front of your MacBook's iSight camera (you can basically press the phone to it). -
If you need to restart the transmission, simply reload the test page.
This software is published under the terms of the BSD 3-clause license.
See the LICENSE file for more info.