Is that a record?

Coming to that stage of the development where polish, refinement and optimization are key.

Best thing for it then is ostentatious new features of questionable value but unquestionable (ahem) coolness . Yay!

I've been developing the game completely in the browser so it grated a little having to use native apps to record the gameplay and I thought it might be interesting to have recording as a built-in feature.

Took a chunk out of the weekend to figure it all out.  Here's the gist of how I it went.

Video Capture

I tackled the video side first and this turned out to be intially fairly trivial using HTMLCanvasElement.captureStream().

I quickly noticed however (eagle eyes) that the game background was not being captured. Turns out the defalt matter.js renderer that I rely on uses CSS to set the canvas background rather than rendering onto the canvas which seems like a generally good plan apart from my rather odd use case.

This resulted in a recording with a black background which I could have called a "night mode" feature and called it a day but I decided to push on and try to fix the issue instead.

One quick fork and a new render lifecycle event for matter.js later and I was up and running with a fully canvas rendered game ready to be captured in all its 800x600 glory.

Next step was to add some keyboard controls.  Shift+R to start/stop recording and Shift+X to dismiss the recorded video and I was good to go.

Audio Capture

Audio turned out to be a surprisingly slippery one, requiring me to get much more familiar with the WebAudio APIs than I had planned. 

In the end I manged to string together a working combination of MediaStreamMediaStreamAudioDestinationNode, MediaElementAudioSourceNode, MediaRecorder and pals to achieve my nefarious goals.

Key thing here was to ensure all sounds initiated before or during the recording were connected to both the recorder destination and speaker destination so they could be both heard and recorded.

That's a Wrap!

With audio sorted it was just a matter of merging the streams in a new MediaStream to add audio to the video reording.

Recorder class source code here might be useful to anyone adding a similar feature to your own app or game.

Now that the recording feature is out of the way I guess I have no excuses left but to finish the game itself.  

Thanks for reading this far! Check out Bug vs. Boxes and let me know if recording works for you or if you find any (unexpected) bugs 😉.

Update: Example capture from my son's Chromebook.

Update 2: Keeping all the audio around and cloning some sounds in case they might be recorded turned out to be a significant performance drag so I simplified the recorder to only record new sounds and restarted any sounds that needed to be captured (only the car engine really).

Leave a comment

Log in with to leave a comment.