Dad-Hack: Customizing the Baby Monitor with Tampermonkey

We use a popular brand of network camera as a baby monitor at home. The camera’s been great, but I have one minor quibble with its web interface. It doesn’t work very well in small window sizes.

If I place the window in the corner of my screen while I do something else, for example, the video frame becomes obnoxiously small:

mickey

The camera’s image occupies just a small fraction the page area! If only there were a way I could change this.

Helper Monkeys

Enter the userscript. First popularized with the Greasemonkey add-on for Firefox, userscripts alter websites on the fly as you visit them. Today I’m running them with Tampermonkey for Chrome. Public repositories offer customization scripts for all sorts of websites, but it’s also pretty easy to write your own.

To get started, install Tampermonkey. Tap its toolbar icon, and select Add a new script. An editor opens with a default script. There’s a bunch of metadata at the top; fill out the @match field to control where the script will run. (The pattern is specified according to Chrome’s Match Patterns.

Here’s a minimum working example:


// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://atomicobject.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    console.log("hello, world!");
})();

The Script

Now that we can easily execute our own code on this page, what should we do?

Initially, I’m interested in removing the big white box at the bottom of the window. I’d like my script to detect whenever the element appears and remove it. I’d like this to work even as I click around different screens within the app, so it’s not enough to do it just once.

I started with a polling approach, but I later settled on a MutationObserver, which reacts faster and is much more efficient:


var observer = new MutationObserver(function(mutations) {
    if($('.player-footer').length > 0){
        console.log("removing footer..");
        $('.player-footer').detach();
    }
});
observer.observe(document.querySelector('#home-container'), {
    subtree: true,
    childList: true,
    attributes: false,
    characterData: false,
    attributeOldValue: false,
    characterDataOldValue: false
});

It works! The big white box is gone, and the page has become much more usable in a small window.

But wait, there’s more! While I was rummaging around under the hood, I noticed that the video is a flash object, of the form:


<object name="flash-player" type="application/x-shockwave-flash" data="/flash/video.swf">
  <param name="flashvars" value="uuid=123&sessionToken=456&cameraScale=1&cameraCenterX=0.5&...">
</object>

Hmm. That flashvars value looks a lot like a query string. I wonder if I could visit the .swf file directly, supplying the flashvars via the URL? Yep–it worked! Now I have access to the video frame without a website wrapped around it.

This enables a fun new challenge: creating a “pop-out” link. I added some code in the mutation observer callback to extract the URL and flashvars, and then inserted a link positioned at the top of the page next to the settings gear:

var fp = $('.cards object');
if (fp.length === 1 && $('.my-swf-link').length === 0) {
    console.log('adding button..');
    var link_to_swf = fp.attr('data') + '?' + fp.children("[name='flashvars']").attr('value');
    var myButton = $('');
    myButton.css({
        "position": "absolute",
        "right": "5rem",
        "color": "white",
        "top": "1.5rem",
        "font-size": "1.9rem",
        "outline": "0"
    });
    myButton.insertAfter("h1.card-title");
}

New and Improved

Here’s how it looks with my enhancements:

userscript

Use the same camera? Here’s the current version of my script.

Conclusion

One of my favorite things about the web is how open and accessible software can be. See a cool effect, and wonder how they did it? The implementation is right there for your inspection!

Another side to this openness is that it enables users to exert more control over software running on their own computer, even if the software wasn’t created with this freedom in mind. It’d be very difficult to make changes like these as a user of phone or desktop software!

Like Tron, userscripts fight for the users. Do you use any regularly? What for? If not, I’d encourage you install Tampermonkey or Greasemonkey to try writing a few to tackle frustrations with websites you use regularly.