This tutorial will get your DIY snapchat up and running quickly. The benefit of using the PubNub Data Stream Network for image transfer is not only speed and reliability, but also relieves you of the need to worry about infrastructure. In this case, you’ll get the same speed and reliability anywhere on Earth. Check out the working DIY Snapchat demo here (you may have to enable your desktop camera).
You can continue to build on this tutorial and apply it to any use case where you need to send a compressed image to a recipient in realtime. For example, maybe you have a security camera set up, and want it to send an image whenever it detects movement at your front door. It can all be done using this tutorial as a starting point.
DIY Snapchat Tutorial Overview
In this DIY Snapchat tutorial, there are five steps we’ll go through to send an image over PubNub:
- Check for access to getUserMedia()
- Capture the image
- Compress & encode the image
- Send the image
- Destroy the image after a countdown
We’ll go over each of these in depth. However, to summarize: we use getUserMedia() to capture the image, the toDataURL() function to compress and base-64 encode it, and PubNub to send the image. Note that the getUserMedia function is only available in Chrome, Firefox, and Opera. For the purposes of this demo, we’ll grab an image from the web if the function isn’t enabled. Want to see it in action or go straight to the source code? Here’s the working DIY Snapchat demo and DIY Snapchat source code:
Building Out the HTML
Before building out the HTML you’ll first need to sign up for a PubNub account. Once you sign up, you can get your unique PubNub keys in the PubNub Developer Portal. Once you have, clone the GitHub repository, and enter your unique PubNub keys on the PubNub initialization, for example:
For the purposes of this demo, we’ll predefine our HTML elements. We need a video, two images, a canvas, and a button (in addition to our formatting). The video allows us to see the frame we want to capture, the first image provides an alternative when a user’s browser doesn’t support getUserMedia(), the canvas displays the picture we take, and the second image displays the copy of the image we send with PubNub.
Connect to PubNub and Subscribe on Our Channel
We need to do one more thing to setup up our DIY Snapchat, and that’s connect to PubNub.
The subscribe component of this step simulates a potential recipient receiving the encoded image and displaying it (in our case, on the second image element).
Check for getUserMedia() Access
To see if we’ll use a captured or a default image, we use the following function to check for the availability of the different flavors of getUserMedia. Now, we can set the default image to appear when we don’t have access.
Capture Video & take a picture
Now that we know getUserMedia() is available to us, we can add video listeners and show our video. If it’s not available, nothing will happen here, as we have to check through each flavor of the function to see which to use. Once we are listening for a video, we can grab a snapshot (or load the default image) when the take snap photo button is pressed.
Compress & Encode the Image
For this part, we’ll write a function that returns a base-64 encoded version of a compressed copy of our image. It turns out that base-64 encoding an image is as simple toDataURL() function call. The less straightforward part is compression below a specific size (I chose 20Kb to remain well below PubNub’s 32Kb message size limit). We do this with a while loop that repeatedly compresses the image until it meets our size requirement (or gets too lossy). This way we get as much quality as possible while remaining within the limit. It follows that we add a function call to our compression function in our “button pressed” callback. I’ve never encountered any issues getting the image small enough.
Send the Image Over PubNub
The next step is to send the image on PubNub. This is as simple as calling the publish method on your PubNub object with the encoded image as the payload. This once again occurs in our “Button Clicked” callback. Since we’ve already set up the handling of the received message, your app should be good to go. Go ahead and give it a try or play with the demo at the top of this page. Enjoy!
Since we’ve already set up the handling of the received message, you can now send and receive images over pubNub!.
Destroy the Image After a Countdown
The novel feature of Snapchat is that its images self destruct. We can implement this feature in a single function:
We begin by creating globals for the countdown and an asynchronous function caller. We declare them in global scope so new calls to the function can reset the countdown and caller.
destroyImage function itself, we begin by getting the destruction status paragraph element (the image is passed as a parameter). We also reset the countdown and timer variables. Next, the destroy function is defined. Destroy is called recursively with a 1 second delay between each call. This delay is what we use to time our countdown (and update our labels/variables accordingly). The base case of the recursion is that the countdown expires and we delete the image data and reset the label.
Finally, all we have to do is call
destroyImage when we handle message receipt over PubNub in the subscribe call:
That’s it! You’ve just built a prototype of Snapchat. You can compare your code with the DIY Snapchat demo’s code here. Enjoy!