Building a multiplayer motion-detection interface in 30 lines of code

header.png

This tutorial shows how to build a multiplayer motion detection interface in just 30 lines of code using the Pusher realtime interface.

Introduction

This tutorial will show how to convert a very cool Magical Xylophone, which demonstrates how to use JavaScript and a WebCam for motion detection, to be multiplayer in just 30* lines of code. You can also try out the Multiplayer Magical Xylophone before reading on.

This article is part of our series of tutorials ‘Building Realtime Applications’, updated on a regular basis.

One of the best things about Pusher is how you can add realtime interactive functionality to existing application with very little effort.

Love how I could make this Xylophone app j.mp/Wwi17R originally by @soundstep multiplayer in 30 lines of code j.mp/T9q1M6

— Phil Leggetter (@leggetter) January 30, 2013

* HTML and JavaScript; both client and server, including logging. The code was done over a couple of commits due to a mistake I made, but 30 lines of code seems about right.

Include the Pusher JavaScript library

pusher-js

Connect

I’ve added some logging here which is always handy when developing. I then connect to Pusher by creating a new Pusher instance. Then a subscription is made to a private-notes channel. The ‘private-‘ means that subscription authentication needs to take place – I’ll cover that later.

log-subscribe

Update the Note object structure

There wasn’t an easy way of identifying which note was being played without accessing the DOM. So I added an index property to the structure which can then be used to access the note in an array.

note-structure

Bind to note events

When a note is played by another user the app wants to know about it. This is done by binding to an event on the private-notes channel. In this case it’s a client-note-on event which means that a note is being played (it’s in the ‘on’ position). The client- prefix is important since it identifies that the event was triggered by another client (more info on this below).

The app also has to play the note that’s just be played by the other user – otherwise it wouldn’t be a multi-user app. This is easy since the note structure, which is also used when the event is triggered (again, more info coming up), has the index property:

bind-handle

Trigger the note event

When a note is being played by the current user you want to distribute that as an event to the other users who are using the Xylophone app. You do this by triggering an event on the channel. Based on the existing code, which handled only playing a note if it wasn’t already being played, the event should only be triggered if the attempt to play a note was successful.

Check if the sound can, and will, be played:

can-sound-play

In an earlier note I mentioned a mistake. Line 162 above is it. This actually resulted in a cascade of events. Whoops!

If it will, trigger the event:

trigger

We’re not quite there yet. Earlier, a subscription was made to a private- channel and a client- event bound to. Here’s a bit more information about them:

  • Private channels are part of our authentication mechanism and represent a fantastic feature when building production applications. When it comes to fun hacks – like this – they are a necessary addition.
  • Client events are events that have been triggered by clients where messages are sent via Pusher to other connected clients. Since your app server doesn’t have a chance to authenticate and validate these events Pusher only allows them to be triggered on channels which have been authenticated.

So, let’s do the authentication:

Add the Pusher node.js library as a dependency

The original example didn’t come with any back-end code so I decided to run the app on node.js. Once it was up and running I then updated package.json to include the pusher npm module and ran npm update.

package

Authenticate the Private channel subscription

With the Pusher node library installed, channel authentication can be implemented. The node library comes with helper functions to make this a very simple process:

auth

Check if multiplayer motion detection is working

If you run the application on a device with a webcam and a browser that supports getUserMedia you’ll see the application functioning. Everytime you play a note it will trigger an event which will be received by any other users with the app open. You can see events being logged in the JavaScript console, which is there via the Pusher.log code:

js-logging

Demo & Enhancements

Thats everything! Why not try out the Multiplayer Xylophone app and start composing with your friends.

Ok, it’s probably not production ready quite yet but you can always fork the multiplay xylophone code on github and update the functionality to use presence channels so you can see who else is online and maybe create a game where you have to play songs with friends

Have fun!

For more about building realtime applications, check out our