Video effect booth written in Rust and WebAssembly
Play with it here: https://mtharrison.github.io/wasmbooth/
I wrote this purely to teach myself more about both Rust and WebAssembly and how to use the two together. The aim of this is definitely not to show off the performance of wasm. I haven't benchmarked or compared this to a pure JS implementation but I wouldn't be surprised if it were slower because it copies all the ImageData from canvas into the wasm linear memory on every frame. Additionally it uses convolutional image processing for a few of the effects, which aren't the most efficient algorithms but are elegant and easy to write/understand.
How it works
The front end is usual HTML, CSS, JS. It streams your webcam into an offscreen video element, which is then written to a hidden canvas. On each frame we grab the image data from the canvas and write it into WebAssembly's linear memory at a pre-determined offset. We then call a WebAssembly function that will process those pixels with our chosen filters. Finally, we construct a new ImageData object and put it on a visible canvas.
To capture a still, we write the visible canvas data into a premade template.
lib- Contains the frontend JS which will be bundled into public/bundle.js by webpack
public- Everything that will be served up to the browser including compiled wasm module
src- The Rust source code which will be compiled to wasm
To simply use the app, run the following:
npm install --productionto install hapi (to serve the site)
npm startto start a server
Then browse to
If you want to change JS inside lib, you should run:
npm installto webpack
npm run build-jsafter to bundle the JS again
If you want to change Rust, you should run:
npm run build-wasmto recompile the .wasm module. You will need nighty Rust and the wasm target installed for this. There's a good explanation here
There are some Rust tests, to run them run:
Build the image:
docker build -t mtharrison/wasmbooth .
Run the image (on port 4000):
docker run -p 4000:4000 mtharrison/wasmbooth
Using Docker with docker-compose
docker-compose up --build
PRs welcome to improve the code or approach or to add more effects, this is all about learning! I'm a newbie to both Rust and wasm so please open an issue if you think there's something I missed or could have done better.