May 102012
 

A few weeks ago, the online gaming community that I belong to (The Legion) deployed a new website to integrate information about the professional e-sports teams with the existing community, forum-based website. As a part of that, we wanted to include the ability to embed and view streams on the home page, with additional information about stream status. Luckily, twitch.tv includes a very powerful and flexible REST API for determining if a stream is online, with output formats in XML, JSON, or JSONP. After the preliminary support for twitch.tv was added, which covered most of the community, we wanted to add the ability to embed streams from another popular streaming website, own3d.tv, as there are a few popular players on the team who use it instead.

Unfortunately, own3d.tv’s API is significantly lacking in features. While twitch.tv returns extensive metadata about the channel, including game played, stream title, streamer name (popular channels can have multiple people stream to them at different times), viewers, preview image URLs, and other interesting information, the entire own3d.tv response consists of stream status (live/not), viewer count, and time spent streaming. To make matters worse, the own3d.tv API is undocumented and appears to have a single endpoint that returns data only in XML format: http://api.own3d.tv/liveCheck.php?live_id=(integer id here). The twitch.tv REST API allows a user to request information about any number of channels simultaneously, while the own3d API appears to only allow a single query per request.

Due to the way that cross-domain AJAX requests are handled (i.e. they aren’t), JSONP emerges as the most useful format for a REST API to be used in building a web application using javascript. I don’t know if this is the standard approach, but the easiest thing to do with twitch.tv appears to be to define a handler function, such as handleTwitchResponse and then insert a script tag into the HTML referencing the REST API endpoint as a source for script, with output set to JSONP and the appropriate handler supplied:

<script type="text/javascript" src="http://api.justin.tv/api/stream/list.json?channel=channel1,channel2,channel3&jsonp=handleTwitchResponse">

The resulting object supplied by twitch.tv’s servers will be wrapped in a function call to handleTwitchResponse, which immediately hooks it into your own local processing system. It would be great if own3d.tv supported the same approach (for flexibility), but it does not, so we are forced to create our own workaround.

To that end, I wrote a short php script that exposes an interface similar to the one used by twitch.tv, where a JSONP handler can be supplied, along with multiple stream IDs, and the results will be returned in an array:

/**
 * Script to forward requests to own3d.tv and return them in JSONP format for our
 * local stuff to handle.
 */

$ids = explode(',', $_GET['live_id']);
$outout = array();

foreach ($ids as $id) {
	$xml = file_get_contents('http://api.own3d.tv/liveCheck.php?live_id='.((int)$id));
	$sxml = new SimpleXMLElement($xml);
	$results = array('isLive' => (string)$sxml->liveEvent->isLive,
					'liveViewers' => (int)$sxml->liveEvent->liveViewers,
					'live_id' => (int)$id,
					'liveDuration' => (int) $sxml->liveEvent->liveDuration);
	$output[] = $results;
}

if (isset($_GET['jsonp']))
	echo $_GET['jsonp'].'('.json_encode($output).');';
else
	echo json_encode($output);

The script itself is pretty simple, as mostly it just glues together a few pieces and changes the format of the data. A comma-separated list of IDs is expected as a GET parameter, along with an optional JSONP callback, presenting a format almost identical to the twitch.tv interface. If no callback is supplied, standard JSON formatting is used instead. Using the ability to make HTTP requests via fopen() (which requires Allow fopen URL wrappers to be set to true in php.ini), it fetches information for each ID individually from own3d.tv, then parses the XML into a PHP array, and spits it out using the built-in JSON-encoding functions provided within PHP.

Note: This script does not translate the names used by own3d.tv to match those used by twitch.tv, but it does add the live_id to the response, in order to allow you to identify which stream a particular status object corresponds to when receiving multiple aggregated into a single response. I did this somewhat intentionally, because it is more useful as a drop in replacement for systems that wish to conserve the own3d.tv naming conventions. You can also readily rename the javascript object properties after all the data has been received by the client, before forwarding the object to a standard twitch.tv handler, which means that it’s also kind of a moot argument.

The script should be stored locally on your server. Then, it can be accessed with standard AJAX, or, for consistency, in a manner identical to how the twitch.tv script is referenced:

<script type="text/javascript" src="own3d_check.php?live_id=1234,1235,1236&jsonp=handleOwnedResponse"></script>

If you find yourself in a situation where you need to deal with own3d.tv streams and their API before it is improved, feel free to use the above script as a reference (or just borrow it I suppose?). Hopefully they will realize that twitch.tv is leagues ahead of them at the moment in this aspect of web streaming, and in order to stay competitive they need to address API needs of external websites.

About Greg Malysa

I am a EE PhD student whose interests include computer architecture, analog circuit design, digital signal processing, and programming in a wide variety of languages. I do a lot of hands-on implementation work, such as doing PCB layout, assembling prototypes, and writing software for both embedded and general purpose systems. I also enjoy research and do many academic or proof-of-concept projects just to see if something can be done. If it involves electricity, I probably think it is interesting.

Leave a Reply