Google TV

Google TV UI Templates, AJAX, and PHP/MySQL

Shawn Shen, Google TV Developer Relations
April 2011

  1. Overview
  2. UI Templates for Web Apps
  3. Adding AJAX Call
  4. Backend with PHP/MySQL
  5. Summary

Overview

Google TV brings together the web and TV and provides a seamless experience for users to consume content from both sources. As a connected TV platform Google TV runs on the Android operating system and comes with Google Chrome web browser that has built-in Adobe Flash compatibility. Users get their favorite TV programming on Google TV plus full access to the web as well as optimized web apps written in either HTML5 or Flash.

In this article we're going to focus on web apps (i.e. optimized web sites for Google TV). Regular web sites, while readily accessible on the big screen of Google TV, do not provide users the best possible experience because web content tends to be text-heavy. For users sitting back in a couch 10 feet away from the screen, more in tune with passive viewing experience of traditional TV, a heavy load of text and links is not the most effective way to provide a quality user experience. For this reason it is highly recommended that these design guidelines be followed when designing and developing your web apps for Google TV.

If you're looking for inspiration, a good place to check out high quality web apps is the Google TV Spotlight Gallery.

There are resources available that make it easier to develop an optimized UI for Google TV. For example there are two readily available Google TV Web UI libraries:

There is also a set of Google TV templates that developers can leverage in speeding up the development process. Let's take an in-depth look into them in the next section and see how they work.

UI Templates for Web Apps

There are two HTML5 templates and two Flash templates. They are identical in functionality and meant to work exactly the same way as far as the look and feel is concerned.

  • Template 1: Full-featured video playback with Main menu and Detail page
  • Template 2: Single-page playback with Category Bar, Video Carousel, Video View, and Playback Controls all in one single page

Visual Components in Google TV UI Templates

Below is a screenshot of Template 2 implementation that we're going to use as an example to illustrate how these templates work on Google TV.

Before we dive into how to implement AJAX for dynamic loading of video clips and meta data from backend, let's first walk you through the visual components in Template 2. It uses a single-page playback design with the following visual components all in one page:

  • Category Bar: a customizable navigation bar of categories across the top of the page
  • Video Carousel: a scrolling carousel of video clip thumbnails with drop-down bubble of meta data
  • Video View: fullscreen video that remains on screen after other navigation controls automatically fade out after a few seconds of inactivity
  • Playback Controls: a media control to play, pause/stop, fast forward, rewind, plus a progress bar on the bottom

Source Files in Google TV UI Templates

You may download source files of these templates to expedite your development. Be sure to read the HTML5 Template Starter Guide. The file structure of these templates consists of the familiar ingredients of web development, namely CSS, HTML, image resources, and Javascript. For example Template 2 has:

  • CSS styles: styles.css
  • Image files: logos, icons, thumbnail images
  • HTML files: index.html
  • Javascript files:
    • index.js
    • dataprovider.js
    • gtvcore.js
    • keycontrol.js
    • carousel.js
    • videocontrol.js
    • tooltip.js
    • videoprogresbar.js

I highlight the index.js and dataprovider.js files in bold because currently video sources are hard coded in a JSON object in dataprovider.js. This static way of enumerating your video sources obviously does not mirror a real-world application, where your video sources are most likely stored on servers and the associated meta data in a database, and you may want to add/remove them in and out of users' viewing queues in a dynamic fashion. In order to achieve that, we're going to modify these two Javascript files and implement an AJAX call to load video sources dynamically.

Adding AJAX Call

In the Google TV HTML5 Template 2, the following method getData in index.js gets videos:

   templatePage.data = templatePage.dataProvider.getData();

It is defined in dataprovide.js but actually has all videos hard-coded in an array named sources. In a real-world application you'd for sure want to dynamically load videos and their associated meta data from the backend. We'll revisit this in detail when setting up a backend with PHP/MySQL in the next section. Let's first implement an AJAX call to put together a basic mechanism for dynamically loading video sources.

AJAX and Callback

An AJAX call is asynchronous in nature. In this case we need to make sure that UI components are not rendered before the completion of loading video data. To achieve that, we modify the getData function by giving it a callback function called processVideos:

  templatePage.data = templatePage.dataProvider.getData(processVideos);

Next we leverage on the jQuery built-in function $.getJSON to initiate an AJAX call as follows, where the videosources.php, defines an endpoint for fetching video data (more detail about it in next section).

  $.getJSON('videosources.php', function(data) {
    processVideos(data);
  });

Chaining of UI Rendering

Now when calling the method getData in index.js, we need to modify it as follows.

  templatePage.dataProvider.getData(function(data) {
     templatePage.data = data;
     templatePage.renderUIComponents();
  });

Here a new method renderUIComponents responsible for the rendering of UI components is introduced. It gets called only after the AJAX call is completed. The original method gtv.jq.TemplatePage.prototype.start is broken into two parts, where the rendering of UI components dependent on video data is moved into this new method called renderUIComponents. See the full source code files here.

With the essential AJAX mechanism set up, let's next take a look at setting up a backend that provides dynamic data via the videosources.php endpoint.

Backend with PHP/MySQL

To set up a backend with PHP/MySQL and customize the content queue of your application, let's break down the task into three parts:

  • Data Format
  • MySQL: Schema and Data
  • PHP Scripts

Data Format

Since we're using jQuery's $.getJSON method in our AJAX call, it is expected that our backend serves back video data in JSON format so that the Javascript in Template 2 can properly parse out. The detailed format goes as follows.

  - categories: [category1, category2, ..., categoryN].
  - category: {name, videos}.
  - videos: [video1, video2, ..., videoN]
  - video: {thumb, title, subtitle, description, sources}
  - sources: [source1, source2, ..., sourceN]
  - source: string with the url | {src, type, codecs}

In a nutshell, this JSON format is a collection of categories, each consists of a name and a collection of videos. Each video in turn consists of meta data like thumbnail, title, subtitle, description, plus a collection of sources. The source can be as simple as a URL string for video or may consist of a more detailed video URL string plus meta data like type, codec, etc. It's much easier to see this data format with an example:

Array
(
  [categories] => Array
    (
      [0] => Array
        (
          [name] => category_1_name
          [videos] => Array
            (
              [0] => Array
                (
                  [sources] => Array
                    (
                      [0] => video_source_url_0 
                      [1] => video_source_url_1 
                      ...
                    )
                  [thumb] => thumb01.jpg
                  [title] => title1 
                  [subtitle] => subtitle1
                  [description] => description1
                )
              ...
            )
         )
       ...
     )
)

MySQL: Schema and Data

Your application needs to dynamically load video data from a database. The following sample schema shows how you might design your database in MySQL.

-- DROP TABLE IF EXISTS `categories`;
CREATE TABLE `categories` (
  `id` varchar(50) NOT NULL default '',
  `name` varchar(50) default NULL,
  `ts` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`),
  KEY (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- DROP TABLE IF EXISTS `videos`;
CREATE TABLE `videos` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `category_id` varchar(50) NOT NULL default '',
  `title` varchar(50) default NULL,
  `subtitle` varchar(50) default NULL,
  `description` varchar(200) default NULL,
  `thumbnail_url` varchar(100) default NULL,
  `video_url` varchar(200) default NULL,
  `ts` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`id`),
  KEY (`category_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

The videos table can be joined with the categories table via category_id. To keep this schema and its associated PHP script simple, I didn't include a table (e.g., a video_urls) to accommodate multiple video URLs, assuming that there is only one video_url per video. In real application there can be multiple video_url for various codecs or bandwidths, where you would need the video_urls table and have it join with the videos table in your SQL query.

PHP Scripts

Now let's implement the code necessary to fetch videos in videosources.php file. As you can see, the script begins with a SELECT query that joins the categories table with the videos table.

$q = "SELECT * FROM videos, categories WHERE videos.category_id = categories.id ORDER BY category_id";
$results = $db->get_results($q);

$category = array();
$category_collection = array();
$videos = array();

$catid = 1;
foreach( $results as $r ) {
    if( $catid != $r->category_id ) {
        // add category array
        $category = array("name" => $r->name, "videos" => $video);
        array_push($category_collection, $category);
        //reset videos array
        $catid = $r->category_id;
        $videos = array();
    }
    $i = array("sources" => array($r->video_url),
      "thumb" =>  $r->thumbnail_url,
      "title" =>  $r->title,
      "subtitle" => $r->subtitle,
      "description" =>  $r->description);
    array_push($videos, $i);

}

// add last category array
$category = array("name" => $r->name, "videos" => $videos);
array_push($category_collection, $category);

// create categories array
$output = array("categories" => $category_collection);

// output categories array in JSON using Zend JSON encoder
echo  Zend_Json::encode($output);

Once the SELECT query executes, the script loops through all fetched records and adds them into a collection of videos, tags on category name, and organizes all categories into a colleciton before sending out the result in JSON format. This JSON data gets processed by the callback function of getData in index.js, as discussed above in the section Adding AJAX Call.

Summary

In this article we have covered how to develop Google TV web apps using the Google TV Templates and showed in detail how to add an AJAX call to fetch videos from a PHP/MySQL backend. Furthermore we showed how to implement a sample MySQL database to store your video data and how to fetch and serve that data with a PHP script.

Next Step

Some developers might be interested in using Google TV HTML5 Templates but with Flash media player instead of that of HTML5. This approach is employed by Baeble Music, where the videocontrol.js file has been modified to include a Flash media player.

Some content owners that have videos available directly from YouTube might be interested in serving them to Google TV users using this kind of template-based approach but having content come directly from YouTube channels.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.