Broadcast Graphics with NodeCG

Update - 2016/02/26: This article is based on NodeCG version ~0.6.0. Since then, some changes have been made in this rapidly changing tool.

NodeCG is a relatively fresh framework for creating broadcast graphics using web stack tools. It's main target audience is the up-and-coming Twitch scene, but as I've found out, it can also find a lot of use in more traditional settings. This blog post is based on my experiences while writing a NodeCG football bundle. You can see the result below:

Web stack tools (by that I mean HTML, JavaScript and CSS) are quickly engulfing the entire programming world. First, there were baby steps in the form of HTML being used in the user interface of desktop software, now entire software suites - server side application engines too - are being crafted entirely using web-style tooling. NodeJS, NW.js and Electron are just a few frameworks/programming environments that allow use of JavaScript outside of the browser window.

JavaScript's appeal is simple - it forgives a lot in terms of hard Computer Science knowledge and offers a very calm learning curve, with very satisfactory results early on. There is an abundance of web stack programmers and ready-made libraries, and that's why more and more companies are turning to these tools for their projects. With NodeCG, another area can be colonized: the TV broadcast.

Before we go

Before trying to set up a set of broadcast graphics using NodeCG, be sure to brush up on your web stack programming skills. You don't need to be a master, but you do need to have a basic knowledge of HTML, CSS (especially CSS transitions and animations!) and JavaScript. Then, install NodeJS. Also, find out how to use NPM (it usually comes with the NodeJS installation) and Bower. These may be unfamilliar to you if you hadn't had contact with the web stack for some time. All of this technology heavily relies on Git and GitHub, so take your time to understand what Git and GitHub does. I also assume that you can find your way around a command prompt. If you are a front-end developer and someone from the Broadcast Technology department just sent you this - you are good to go as you are.

Set-up

Make sure that you have installed NodeJS and NPM. Open a command prompt and install a package called nodecg-cli:

$ npm install -g nodecg-cli

This is a helper application that will simplify interaction with NodeCG. Then create a new directory for your NodeCG installation (I keep a separate NodeCG installation per each project), cd into it and do

$ nodecg setup 0.6.3

Note - 2016/02/26: this was updated to stick to version 0.6.x

This will clone the latest release of NodeCG into your directory and set up everything so that you can start work on your templates.

Afterwards, you can start NodeCG with:

$ nodecg start

This will start it's internal web server (by default on http://localhost:9090/), where you can find the NodeCG control application. The little [i] icon will show the render URL you need to type in into your rendering application (or your web browser for debugging).

Bundles, views and dashboards

NodeCG exploits a feature of certain pieces of software (such as CasparCG and Open Broadcasting Software to just name the open-source ones) to overlay a web page over a live video stream and use that as a broadcast graphic. There is one issue though, if you want your graphics to be dynamic: you need to somehow control what is displayed on your screen. CasparCG solves this by implementing a custom programming interface with which a client application can communicate using it's AMCP protocol with the website visible on screen - this usually requires writing a special desktop application - a controller. OBS on the other hand has no such feature - the open website needs to know on it's own what to display and when.

That's where NodeCG comes in. Using a new technology called Web Sockets it communicates with the website open in the rendering application (CasparCG, OBS or whatever), creating an Out-of-Band control channel. But that's not all - NodeCG provides an entire framework that helps you create the controller as well in a really short time.

In NodeCG vocabulary, a view is the website that is supposed to be viewed by the rendering application (that is what we would usually call a template). A dashboard is the website dedicated to controlling a given view. A set of a view and a dashboard is called a bundle and the nodecg command line tool has specific commands to help manage those.

Creating a bundle

In order to create a bundle, let's use the nodecg tool:

$ nodecg init

This will start a wizard with some helpful questions asked about our new bundle. This will create a directory with the same name as the one we've typed in the bundle init wizard. There we'll need to create two directories on our own: view and dashboard. Within the view directory we need to create a functioning website, that looks just like we want our graphics to look like. I don't want to go into the details, because I would like to concentrate on the stuff that's NodeCG-specific. I'll just say that using jQuery in the view is a good idea, because that's what you have at your disposal in the dashboard.

First of all, please keep in mind, that usually, your rendering software will only keep a single web page open on it's output. That's why I think it's most convenient to have a single index.html file and keep each template (a lower third, a table board, a ticker, etc.) in a separate <div> element. I also keep the JavaScript code & CSS for each template separately. Remember to put a baseline setting for your <body> element in CSS:

body {
    padding: 0;
    margin: 0;
    overflow: hidden;
    width: 1920px;
    height: 1080px;
}

This will help with positioning on your screen. Switch 1920/1080 with 1280/720 if you're doing a 720p production.

Replicants

An important idea in the NodeCG world is the Replicant object. This is a class of an object that you can use to replicate values in the dashboard and view. If you set a value in the dashboard code, the value will also change in the view code. Not only that, but an event will be triggered notifying you that the value has change. This is an example from a view code:

var name = nodecg.Replicant("name", {defaultValue: ""});
name.on('change', function (oldVal, newVal) {
    $('#name').html(newVal);
});

You create the replicants on the dashboard side in the same manner - keep in mind that the first argument of the Replicant constructor (the variable id) has to be the same in both the view and the dashboard code. You can assign values by doing simply:

name.value = $("#name-input").val();

name.value is also a getter with which you can get the value of the variable, outside of the change event. Another great feature of the replicant is that NodeCG takes care of variable persistence. So if your view website or your web browser with your dashboard were to crash, the variables will keep their values. Just remember, that the variables in the dashboard will take some time to restore. I just put the restore code in a short setTimeout, like so:

setTimeout(function () {
    $("#name-input").val(name.value);
}, 500);

Sending events

Another element provided by the nodecg framework is an event service: you can push events with some argument objects from the dashboard into the view. You can make a button send an event like so:

$("#news-lth-cueIn").click(function () {
  nodecg.sendMessage('newsLthCueIn');
});

And then to receive it in the view:

nodecg.listenFor('newsLthCueIn', function () {
  $("#news-lth").removeClass("off");
});

Dashboard

The dashboard is made of panels - windows containing widgets controling a particular aspect of your graphics - a lower third, for example. Each panel is constructed using a Jade file - a shorthand for HTML:

.form-group
        label(for="name-input") Name
        input#name-input.form-control

This will create a div with a class form-group containing a label Name and an input box with id=name-input and a class=form-control. The dashboard portion uses the Bootstrap CSS framework.

You also need to create a file called panels.json in the dashboard directory and declare each panel there:

[
  {
    "name": "news-lth",
    "title": "Lower Third",
    "width": 4,
    "file": "lowerThird.jade",
    "faIcon": "fa-clock-o"
  },
]

If your panel's Jade file is lowerThird.jade, the script file has to be called lowerThird.js for it to be included. The faIcon can be any icon from the FontAwesome package.

Finding help

The NodeCG is a very vibrant community with a lot of community members giving back with great examples of their work that can function as a reference point. Most of them are gaming-oriented, so they often include very extensive integration with systems like gaming servers or Twitch.tv - none the less, the fundamentals are the same. Use the search feature of GitHub to search for NodeCG and you'll find public bundles published by other users.

A good place to look for help is the NodeCG Gitter chat channel: nodecg/nodecg.

Conclusion

NodeCG seems to be an interesting addition to the Open Source broadcasting toolkit. Being HTML/CSS/JavaScript-based makes it compatible with many tools. For me, it's especially interesting in combination with Open Broadcasting Software, where it allows even very small, single-camera broadcast to have live broadcast graphics without the addition of an another graphics generator box or a video switcher. Below you can find a Football match broadcast with only a single camera and a laptop with a USB 3.0 Blackmagic SDI interface. The input video was overlayed with live graphics made in NodeCG and then encoded using Open Broadcasting Software.