{"id":4520,"date":"2013-06-07T10:47:28","date_gmt":"2013-06-07T10:47:28","guid":{"rendered":"http:\/\/178.62.14.192\/?p=4520"},"modified":"2013-06-07T10:47:28","modified_gmt":"2013-06-07T10:47:28","slug":"build-your-own-google-tv-using-raspberrypi-nodejs-and-socket-io","status":"publish","type":"post","link":"https:\/\/www.recantha.co.uk\/blog\/?p=4520","title":{"rendered":"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io"},"content":{"rendered":"<p style=\"text-align: center;\"><a href=\"http:\/\/blog.donaldderek.com\/2013\/06\/build-your-own-google-tv-using-raspberrypi-nodejs-and-socket-io\/\"><img decoding=\"async\" alt=\"Build your own Google TV Using RaspberryPi, NodeJS and Socket.io | Donald's Blog\" src=\"\/blog\/wp-content\/uploads\/2013\/06\/raspberrypi_tv_google_tv1.jpg\" \/><\/a><\/p>\n<p>Donald Derek has blogged a fantastic tutorial that shows you how to create a Google TV-alike interface to the Raspberry Pi.\u00a0<a href=\"http:\/\/blog.donaldderek.com\/2013\/06\/build-your-own-google-tv-using-raspberrypi-nodejs-and-socket-io\/\">Read all about it here<\/a><\/p>\n<p>Update: The last time I tried to visit the blog, it was down, so here is the blog post for posterity:<\/p>\n<h1>What\u2019s Google TV ?<\/h1>\n<p>Turned out that Google is also doing its own thing for the 10-foot screen. Google announced 2 versions of their famous\u00a0new TV, the first is called the Buddy Box which is currently an expensive box manufactured by\u00a0<a href=\"http:\/\/www.google.com\/tv\/get.html\" target=\"_blank\">Sony<\/a>\u00a0and the second is an Integrated TV\u00a0built right into the TV set that will be\u00a0announced\u00a0soon.<\/p>\n<p>The Google TV looks something like that:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"google_tv_preview\" src=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png?resize=560%2C314\" width=\"560\" height=\"314\" \/><\/a><\/p>\n<p>Google TV preview<\/p>\n<p><strong>Developers:<\/strong>\u00a0you can start building your own Web Apps for the Google TV or renovate any android app to fit the 10\u2032 Screen, all the resources can be found at Google\u2019s Developers\u00a0<a href=\"https:\/\/developers.google.com\/tv\/\" target=\"_blank\">Site<\/a><\/p>\n<h1>Build your own Google TV<\/h1>\n<p>Hackers &amp; makers like to re-invent the wheel, and it\u2019s always fun when you do. So we\u2019re going to\u00a0<strong>build our own version of the Google TV<\/strong>\u00a0using the following open source technologies:<\/p>\n<p><strong>Hardware:<\/strong><\/p>\n<ul>\n<li>The\u00a0<a href=\"http:\/\/www.raspberrypi.org\/\" target=\"_blank\">RaspberryPi<\/a><\/li>\n<\/ul>\n<p><strong>Software Stack:<\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/www.raspbian.org\/\" target=\"_blank\">Raspbian<\/a>\u00a0OS \u2013 a Debian distro specially made for the rPi<\/li>\n<li><a href=\"http:\/\/nodejs.org\/\" target=\"_blank\">NodeJs<\/a>\n<ul>\n<li><a href=\"http:\/\/socket.io\/\" target=\"_blank\">Socket.io<\/a>\u00a0\u2013 to handle the connection between our remote and our TV via websockets<\/li>\n<li><a href=\"http:\/\/expressjs.com\/\" target=\"_blank\">Express<\/a>\u00a0\u2013 to handle some basic http requests<\/li>\n<li><a href=\"https:\/\/npmjs.org\/package\/omxcontrol\" target=\"_blank\">Omxcontrol<\/a>\u00a0\u2013 a simple module to control the OMXPlayer which is the best video player on the rPi<\/li>\n<\/ul>\n<\/li>\n<li><a href=\"http:\/\/www.chromium.org\/Home\" target=\"_blank\">Chromium<\/a>\u00a0Browser<\/li>\n<li><a href=\"http:\/\/omxplayer.sconde.net\/\" target=\"_blank\">OMXPlayer<\/a><\/li>\n<li><a href=\"http:\/\/rg3.github.io\/youtube-dl\/\" target=\"_blank\">Youtube-dl<\/a>\u00a0\u2013 a script that let you download youtube videos<\/li>\n<li><a href=\"http:\/\/quojs.tapquo.com\/\" target=\"_blank\">QuoJS<\/a>\u00a0\u2013 to handle swipe gestures on the mobile web app<\/li>\n<li>HTML5, CSS3 transitions, Javascript, and\u00a0<a href=\"http:\/\/mustache.github.io\/\" target=\"_blank\">Moustache<\/a>\u00a0as a template engine<\/li>\n<li>Youtube API<\/li>\n<\/ul>\n<h2>The end result<\/h2>\n<p><a href=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/raspberrypi_tv_google_tv.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"raspberrypi_tv_google_tv\" src=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/raspberrypi_tv_google_tv.jpg?resize=560%2C420\" width=\"560\" height=\"420\" \/><\/a><\/p>\n<p>Raspberry Pi TV with its special remote controller<\/p>\n<p>&nbsp;<\/p>\n<h1>Walkthrough<\/h1>\n<p>The project is divided into 4 main categories:<\/p>\n<ol>\n<li>Installing the software stack<\/li>\n<li>Basic shell commands &amp; scripts<\/li>\n<li>Building the backend: NodeJS + Express + Socket.io<\/li>\n<li>Building the front end<\/li>\n<\/ol>\n<h2>1.Installing the software stack:<\/h2>\n<h4>Install Raspbian &amp; NodeJS<\/h4>\n<p>Follow this\u00a0<a href=\"http:\/\/blog.rueedlinger.ch\/2013\/03\/raspberry-pi-and-nodejs-basic-setup\/\">tutorial<\/a>\u00a0to install Raspbian and Node Js on your Raspberry Pi<\/p>\n<h4>Install Chromium &amp; Youtube-dl<\/h4>\n<p>Install Chromium Browser for the Raspberry Pi\u00a0<a href=\"http:\/\/elinux.org\/RPi_Chromium\" target=\"_blank\">Source<\/a><\/p>\n<pre>sudo apt-get install chromium-browser<\/pre>\n<p>In order to have a better display you can also install MC core fonts using<\/p>\n<pre>sudo apt-get install ttf-mscorefonts-installer<\/pre>\n<p>Install and Update Youtube Downloader<\/p>\n<pre>sudo apt-get install youtube-dl\u00a0\n\nsudo\u00a0youtube-dl -U<\/pre>\n<address>Note-1: There\u2019s a problem when you want to stream videos on the RaspberryPi from youtube in Chromium, they\u2019re\u00a0extremely\u00a0slow because the videos are not being rendered on the GPU. Youtube-dl comes as a quick alternative, the video is downloaded instead then played by the OMXPlayer which will render our videos on the GPU giving us a good quality of HD videos.<\/address>\n<address>Note-2: The OMXPlayer is installed by default on the Raspbian.<\/address>\n<h3>2.Basic shell commands &amp; scripts<\/h3>\n<p>If you\u2019re using SSH to connect to your RaspberryPi you should first add \u201cDISPLAY=:0.0\u2033 to your env variables, by simply executing<\/p>\n<pre>export DISPLAY=:0.0<\/pre>\n<p>To check all your\u00a0environment\u00a0variables<\/p>\n<pre>env<\/pre>\n<p>Test Chromium in Kiosk Mode:<\/p>\n<pre>chromium --kiosk http:\/\/www.google.com<\/pre>\n<p>Test Youtube-dl<\/p>\n<pre>youtube-dl <i>youtube_video_url<\/i><\/pre>\n<p>I\u2019ve added few parameters to youtube-dl to change the name of the downloaded file to be just the \u201c-o youtube ID [dot] the extension\u201d and with the \u201c-f \/22\/18 \u201d I can force this script to download for me a 720p version of the video. Check out the full list of supported youtube formats\u00a0<a href=\"http:\/\/en.wikipedia.org\/wiki\/YouTube#Quality_and_codecs\" target=\"_blank\">here<\/a><\/p>\n<pre>youtube-dl \u00a0-o \"%(id)s.%(ext)s\" -f \/22\/18 youtube_video_url<\/pre>\n<p>After downloading the video, try playing it using OMXPLayer<\/p>\n<pre>omxplayer youtube_video_file<\/pre>\n<p>Have fun trying the keyboard shortcuts to pause\/resume your video and a lot\u00a0<a href=\"http:\/\/omxplayer.sconde.net\/\" target=\"_blank\">more<\/a><\/p>\n<p>Fancy! Let\u2019s automate this process using Node JS<\/p>\n<h2>Building the backend: NodeJS + Express + Socket.io<\/h2>\n<p>The source code is intended to be simple for the sake of the workshop. Here\u2019s the project\u2019s hierarchy:<\/p>\n<ul>\n<li>public\n<ul>\n<li>js<\/li>\n<li>css<\/li>\n<li>images<\/li>\n<li>fonts<\/li>\n<li>index.html<\/li>\n<li>remote.html<\/li>\n<\/ul>\n<\/li>\n<li>app.js<\/li>\n<li>package.json<\/li>\n<\/ul>\n<p><strong>Package.json<\/strong>\u00a0\u2013 A JSON file needed by npm to auto-install\u00a0dependencies\u00a0and save some basic info about your project<\/p>\n<pre><code>{\n    \"name\": \"GoogleTV-rPi\",\n    \"version\": \"0.0.1\",\n    \"private\": false,\n    \"scripts\": {\n        \"start\": \"node app.js\"\n    },\n    \"dependencies\": {\n    \"express\": \"3.1.1\",\n    \"socket.io\":\"0.9.14\",\n    \"omxcontrol\":\"*\"\n    }\n}<\/code><\/pre>\n<p>after creating this file, go to your app directory and run the following to install the dependencies.<\/p>\n<pre>npm install<\/pre>\n<address>Note-3: Notice that a folder called\u00a0<em><strong>node_modules<\/strong>\u00a0<\/em>will be created prior to this action, if you like to use git, don\u2019t forget to create a\u00a0<strong>.gitignore<\/strong>\u00a0file and simply write into it \u201c<strong>node_modules<\/strong>\u201d this will ignore the folder node_modules from being added to your git project<\/address>\n<p>Create the app.js file and lets start by creating our basic HTTP Express Server<\/p>\n<pre><code>var express = require('express')\n  , app = express()  \n  , server = require('http').createServer(app)\n  , path = require('path')\n\n\/\/ all environments\napp.set('port', process.env.TEST_PORT || 8080);\napp.use(express.favicon());\napp.use(express.logger('dev'));\napp.use(express.bodyParser());\napp.use(express.methodOverride());\napp.use(express.static(path.join(__dirname, 'public')));\n\n\/\/Routes\napp.get('\/', function (req, res) {\n  res.sendfile(__dirname + '\/public\/index.html');\n});\n\napp.get('\/remote', function (req, res) {\n  res.sendfile(__dirname + '\/public\/remote.html');\n});\n\nserver.listen(app.get('port'), function(){\n  console.log('Express server listening on port ' + app.get('port'));\n});\n\n<\/code><\/pre>\n<p>This is our basic Express HTTP server configuration with our routes. To test what\u2019ve done so far, you should first create the index.html and remote.html files inside the public\/ directory, write your favorite \u201cHello, World\u201d messages into them, then go back to your terminal and execute<\/p>\n<pre>node app.js<\/pre>\n<p>or<\/p>\n<pre>npm start<\/pre>\n<address>Note-4: That will only work if you have added the following piece of code to your package.json<\/address>\n<pre><code>...\n\"scripts\": {\n        \"start\": \"node app.js\"\n    },\n...\n<\/code><\/pre>\n<p>Once your server starts it will output that\u00a0<strong>Express server listening on port 8080<\/strong><br \/>\nTo test your \u201cHello, World\u201d pages you should run this application in the background by simply doing<\/p>\n<pre>node app.js &amp;<\/pre>\n<p>Now this is the most primitive way to launch a Node application in the background, while learning node you might bump into some modules that automates this simple task, just like<a href=\"https:\/\/github.com\/nodejitsu\/forever\" target=\"_blank\">Forever.js<\/a><\/p>\n<p>Now we have our Node Application up and running in the background, let\u2019s open chromium in kiosk mode and test our Hello, World pages.<\/p>\n<pre>chromium --kiosk http:\/\/localhost:8080<\/pre>\n<h2>Adding the Socket.io Magic<\/h2>\n<p>I strongly\u00a0believe that WebSockets are the foundation of the modern web, I always like to point out the following analogy that helped me understand Socket.io<\/p>\n<p>When AJAX first popped out, old skool developers felt its magic, but they\u2019ve encountered many problems due to how different browsers handle Asynchronous JavaScript and XML requests. jQuery came with the solution by providing a nice and minimal set of functions to deal with the browsers nightmare. Socket.io did the same but for WebSockets, even more!<\/p>\n<p>In order to provide realtime connectivity on every browser, Socket.IO selects the most capable transport at runtime, without it affecting the API.<\/p>\n<ol>\n<li>WebSocket<\/li>\n<li>Adobe\u00ae Flash\u00ae Socket<\/li>\n<li>AJAX long polling<\/li>\n<li>AJAX multipart streaming<\/li>\n<li>Forever Iframe<\/li>\n<li>JSONP Polling<\/li>\n<\/ol>\n<p>In order to integrate Socket.io we should add the following to our\u00a0<strong>app.js<\/strong>\u00a0file:<\/p>\n<pre><code>var express = require('express')\n  , app = express()  \n  , server = require('http').createServer(app)\n  , path = require('path')\n  , io = require('socket.io').listen(server)\n  , spawn = require('child_process').spawn<\/code><\/pre>\n<p>and to minify the logs add this:<\/p>\n<pre><code>\/\/Socket.io Config\nio.set('log level', 1);\n<\/code><\/pre>\n<p>When developing with Socket.io always think like you\u2019re creating a Hello, World Chat Application. I\u2019ve added a simple Chat Application done with Node &amp; Socket.io on\u00a0<a href=\"https:\/\/github.com\/DonaldDerek\/Chat-Node\" target=\"_blank\">a github repo<\/a>\u00a0for the sake of this tutorial!<\/p>\n<p>Our Socket.io Server is ready, but it doesn\u2019t do anything, we should implement how we process messages and events sent from the client to the server.<\/p>\n<p>Here\u2019s how you implement this on the server\u2019s side, note that you should also implement how you handle messages on the client\u2019s side, we will see that as we progress throughout this tutorial.<\/p>\n<pre><code>io.sockets.on('connection', function (socket) {\n    socket.emit('message', { message: 'welcome to the chat' });\n    socket.on('send', function (data) {\n        \/\/Emit to all\n        io.sockets.emit('message', data);\n    });\n});\n<\/code><\/pre>\n<p>Now our server Emits the message \u201cmessage\u201d whenever a new client is connected, and waits for an event name \u201csend\u201d to process the data and emit it back to all connected clients<\/p>\n<p>In our case We have two types of clients: The RaspberryPi Display (Screen) and the Mobile Web Application (Remote)<\/p>\n<pre><code>var ss;\n\/\/Socket.io Server\nio.sockets.on('connection', function (socket) {\n\n socket.on(\"screen\", function(data){\n   socket.type = \"screen\";\n   \/\/Save the screen socket\n   ss = socket;\n   console.log(\"Screen ready...\");\n });\n\n socket.on(\"remote\", function(data){\n   socket.type = \"remote\";\n   console.log(\"Remote ready...\");\n   if(ss != undefined){\n      console.log(\"Synced...\");\n   }\n });\n)};\n<\/code><\/pre>\n<h3>Client Side Sockets Handeling<\/h3>\n<p>inside remote.html we should have the following:<\/p>\n<pre><code>\n    &lt;script src=\"\/socket.io\/socket.io.js\"&gt; &lt;\/script&gt;\n    &lt;script&gt;\n      \/\/use http:\/\/raspberryPi.local if your using Avahi Service \n          \/\/or use your RasperryPi IP instead\n          var socket = io.connect('http:\/\/raspberrypi.local:8080');\n      socket.on('connect', function(data){\n        socket.emit('screen');\n      });\n    &lt;\/script&gt;\n<\/code><\/pre>\n<p>On our index.html<\/p>\n<pre><code>\n    &lt;script src=\"\/socket.io\/socket.io.js\"&gt; &lt;\/script&gt;\n    &lt;script&gt;\n      \/\/use http:\/\/raspberryPi.local if your using Avahi Service \n          \/\/or use your RasperryPi IP instead\n          var socket = io.connect('http:\/\/raspberrypi.local:8080');\n      socket.on('connect', function(data){\n        socket.emit('screen');\n      });\n    &lt;\/script&gt;\n\n<\/code><\/pre>\n<h3>Execute Shell Commands from Node Server<\/h3>\n<address>Node enables us to run a system command within a new child process, and listen in on its input\/output. This includes being able to pass arguments to the command, and even pipe the results of one command to another.\u00a0<\/address>\n<p>The basic way of executing shell commands from NodeJS is very simple<\/p>\n<pre><code>spawn('echo',['foobar']);<\/code><\/pre>\n<p>But if you want to pipe in the output, you should add the following function to your app.js file:<\/p>\n<pre><code>\/\/Run and pipe shell script output \nfunction run_shell(cmd, args, cb, end) {\n    var spawn = require('child_process').spawn,\n        child = spawn(cmd, args),\n        me = this;\n    child.stdout.on('data', function (buffer) { cb(me, buffer) });\n    child.stdout.on('end', end);\n}\n<\/code><\/pre>\n<h3>Adding OMXControl \u2013 the OMXPlayer controller Node Module<\/h3>\n<p>Luckily I found a node module on\u00a0<a href=\"https:\/\/npmjs.org\/package\/omxcontrol\" target=\"_blank\">npmjs.org<\/a>\u00a0that let you control your OMXPlayer using Express!<br \/>\njust add the following to your app.js file to use it.<\/p>\n<pre><code>var omx = require('omxcontrol');\n\n\/\/use it with express\napp.use(omx());\n<\/code><\/pre>\n<p>This will create for us the following routes, that we can use to control and play our videos:<\/p>\n<pre>http:\/\/localhost:8080\/omx\/start\/:filename\n\nhttp:\/\/localhost:8080\/omx\/pause\n\nhttp:\/\/localhost:8080\/omx\/quit<\/pre>\n<p>Pretty Awesome!<\/p>\n<h3>Putting it all together<\/h3>\n<p>Our evolved app.js file<\/p>\n<pre><code>\n\/**\n * Module dependencies.\n *\/\n\nvar express = require('express')\n  , app = express()  \n  , server = require('http').createServer(app)\n  , path = require('path')\n  , io = require('socket.io').listen(server)\n  , spawn = require('child_process').spawn\n  , omx = require('omxcontrol');\n\n\/\/ all environments\napp.set('port', process.env.TEST_PORT || 8080);\napp.use(express.favicon());\napp.use(express.logger('dev'));\napp.use(express.bodyParser());\napp.use(express.methodOverride());\napp.use(express.static(path.join(__dirname, 'public')));\napp.use(omx());\n\n\/\/Routes\napp.get('\/', function (req, res) {\n  res.sendfile(__dirname + '\/public\/index.html');\n});\n\napp.get('\/remote', function (req, res) {\n  res.sendfile(__dirname + '\/public\/remote.html');\n});\n\n\/\/Socket.io Congfig\nio.set('log level', 1);\n\nserver.listen(app.get('port'), function(){\n  console.log('Express server listening on port ' + app.get('port'));\n});\n\n\/\/Run and pipe shell script output \nfunction run_shell(cmd, args, cb, end) {\n    var spawn = require('child_process').spawn,\n        child = spawn(cmd, args),\n        me = this;\n    child.stdout.on('data', function (buffer) { cb(me, buffer) });\n    child.stdout.on('end', end);\n}\n\n\/\/Save the Screen Socket in this variable\nvar ss;\n\/\/Socket.io Server\nio.sockets.on('connection', function (socket) {\n\n socket.on(\"screen\", function(data){\n   socket.type = \"screen\";\n   ss = socket;\n   console.log(\"Screen ready...\");\n });\n socket.on(\"remote\", function(data){\n   socket.type = \"remote\";\n   console.log(\"Remote ready...\");\n });\n\n socket.on(\"controll\", function(data){\n    console.log(data);\n   if(socket.type === \"remote\"){\n\n     if(data.action === \"tap\"){\n         if(ss != undefined){\n            ss.emit(\"controlling\", {action:\"enter\"}); \n            }\n     }\n     else if(data.action === \"swipeLeft\"){\n      if(ss != undefined){\n          ss.emit(\"controlling\", {action:\"goLeft\"}); \n          }\n     }\n     else if(data.action === \"swipeRight\"){\n       if(ss != undefined){\n           ss.emit(\"controlling\", {action:\"goRight\"}); \n           }\n     }\n   }\n });\n\n socket.on(\"video\", function(data){\n\n    if( data.action === \"play\"){\n    var id = data.video_id,\n         url = \"http:\/\/www.youtube.com\/watch?v=\"+id;\n\n    var runShell = new run_shell('youtube-dl',['-o','%(id)s.%(ext)s','-f','\/18\/22',url],\n        function (me, buffer) { \n            me.stdout += buffer.toString();\n            socket.emit(\"loading\",{output: me.stdout});\n            console.log(me.stdout)\n         },\n        function () { \n            \/\/child = spawn('omxplayer',[id+'.mp4']);\n            omx.start(id+'.mp4');\n        });\n    }    \n\n });\n});\n<\/code><\/pre>\n<h2>Building the front-end<\/h2>\n<p><a href=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/front_end_raspberry_pi_tv.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"Raspberry Pi TV Screen Front-end \" src=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/front_end_raspberry_pi_tv-1024x640.png?resize=560%2C349\" width=\"560\" height=\"349\" \/><\/a><\/p>\n<p>Raspberry Pi TV Screen Front-end<\/p>\n<p>Describing in details how I built the front-end is outside the scope of this tutorial, however I would like to point out few tips that I discovered while doing this project over the weekend.<\/p>\n<p>When designing for the 10\u2032 Screen there\u2019s some design considerations that you should follow, Google\u00a0assembled\u00a0a nice set of these standards on their\u00a0<a href=\"https:\/\/developers.google.com\/tv\/web\/docs\/design_for_tv\" target=\"_blank\">Developers Site<\/a><\/p>\n<p><a href=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/raspberry_pi_tv_remote.jpg\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"Raspberry Pi TV Remote\" src=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/raspberry_pi_tv_remote.jpg?resize=245%2C491\" width=\"245\" height=\"491\" \/><\/a><\/p>\n<p>Raspberry Pi TV Remote<\/p>\n<p>Instead of creating a typical\u00a0remote, full of fake buttons, I decided to give\u00a0<a href=\"http:\/\/quojs.tapquo.com\/\" target=\"_blank\">QuoJS<\/a>\u00a0a try, it\u2019s really fantastic and easy to use!<\/p>\n<pre><code>$$(\".r-container\").swipeLeft(function(){\nsocket.emit('control',{action:\"swipeLeft\"}); \n});\n<\/code><\/pre>\n<p>Here\u2019s an example of how I send the message \u201cControl\u201d back to the server with the data action:\u201dswipeLeft\u201d<br \/>\nthe server will handle that message by sending it to the screen, the screen client will handle this message by moving the selected square to the next app (Watch, Listen, Play)<\/p>\n<p>I\u2019ve also\u00a0stumbled upon few trick that will let your iPhone mobile web app look like a native one with a nice icon and a splash screen.<br \/>\nJust add the following to your HTML &lt;head&gt;&lt;\/head&gt; blocks<\/p>\n<pre><code>&lt;link rel=\"apple-touch-icon\" href=\"images\/custom_icon.png\"\/&gt;\n&lt;link rel=\"apple-touch-startup-image\" href=\"images\/startup.png\"&gt;\n&lt;meta name=\"viewport\" content=\"width=device-width initial-scale=1, maximum-scale=1, user-scalable=no\" \/&gt;\n&lt;meta name=\"apple-mobile-web-app-title\" content=\"Remote\"&gt;\n&lt;meta name=\"apple-mobile-web-app-capable\" content=\"yes\"&gt;<\/code><\/pre>\n<h2>Wrap-up<\/h2>\n<p>This project is still a work in progress, updates coming soon. If you liked this tutorial please don\u2019t forget to check the source code on\u00a0<a href=\"https:\/\/github.com\/DonaldDerek\/googleTV\" target=\"_blank\">Github<\/a>\u00a0and show some love by starring it .<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/logo_ll.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"logo_ll\" src=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/logo_ll.png?resize=376%2C84\" width=\"376\" height=\"84\" \/><\/a><\/p>\n<p>Special Thanks to everyone who attended the workshop at\u00a0<a href=\"http:\/\/lambalabs.org\/doku.php\" target=\"_blank\">Lamba Labs Beirut Hackerspace<\/a>we hack and make pretty cool things there, come and join us if you can!<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/gdg_beirut.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"gdg_beirut\" src=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/gdg_beirut.png?resize=108%2C108\" width=\"108\" height=\"108\" \/><\/a><\/p>\n<p>This workshop is also powered by\u00a0<a href=\"https:\/\/plus.google.com\/u\/0\/102062106640051908932\" target=\"_blank\">GDG Beirut<\/a>\u00a0and the idea was baked during my\u00a0<a href=\"http:\/\/www.slideshare.net\/DonaldDerek\/google-io-extended-build-your-own-google-tv\" target=\"_blank\">lightning talk<\/a>\u00a0at the\u00a0<a href=\"https:\/\/plus.google.com\/u\/0\/events\/cp2togh80nq76q6p301ed3vkodo\" target=\"_blank\">Google IO Extend Beirut 2013<\/a><\/p>\n<p><a href=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/t3_log_en.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"t3_log_en\" src=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/t3_log_en.png?resize=81%2C81\" width=\"81\" height=\"81\" \/><\/a><\/p>\n<p>This tutorial is sponsored by\u00a0<a href=\"http:\/\/t3me.com\/\" target=\"_blank\">T3 Middle East<\/a><\/p>\n<p><a href=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/logo_mena.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"logo_mena\" src=\"https:\/\/i0.wp.com\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/logo_mena.png?resize=241%2C82\" width=\"241\" height=\"82\" \/><\/a><\/p>\n<p>And it was fully recorded by\u00a0<a href=\"http:\/\/menaversity.com\/\" target=\"_blank\">Menaveristy<\/a>\u00a0Videos coming soon.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Donald Derek has blogged a fantastic tutorial that shows you how to create a Google TV-alike interface to the Raspberry Pi.\u00a0Read all about it here Update: The last time I tried to visit the blog, it was down, so here&hellip;<\/p>\n<p class=\"more-link-p\"><a class=\"more-link\" href=\"https:\/\/www.recantha.co.uk\/blog\/?p=4520\">Read more &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[30,39],"tags":[],"class_list":["post-4520","post","type-post","status-publish","format-standard","hentry","category-media-centre","category-programming"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io - Raspberry Pi Pod<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.recantha.co.uk\/blog\/?p=4520\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io - Raspberry Pi Pod\" \/>\n<meta property=\"og:description\" content=\"Donald Derek has blogged a fantastic tutorial that shows you how to create a Google TV-alike interface to the Raspberry Pi.\u00a0Read all about it here Update: The last time I tried to visit the blog, it was down, so here&hellip;Read more &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.recantha.co.uk\/blog\/?p=4520\" \/>\n<meta property=\"og:site_name\" content=\"Raspberry Pi Pod\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/recantha\/\" \/>\n<meta property=\"article:published_time\" content=\"2013-06-07T10:47:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2013\/06\/raspberrypi_tv_google_tv1.jpg\" \/>\n<meta name=\"author\" content=\"Michael Horne\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@recantha\" \/>\n<meta name=\"twitter:site\" content=\"@recantha\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michael Horne\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520\"},\"author\":{\"name\":\"Michael Horne\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/person\/c27c4ef2ee1c18b130f1fcd5dcdbb263\"},\"headline\":\"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io\",\"datePublished\":\"2013-06-07T10:47:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520\"},\"wordCount\":1634,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png\",\"articleSection\":[\"Media centre\",\"Programming\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.recantha.co.uk\/blog\/?p=4520#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520\",\"url\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520\",\"name\":\"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io - Raspberry Pi Pod\",\"isPartOf\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png\",\"datePublished\":\"2013-06-07T10:47:28+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.recantha.co.uk\/blog\/?p=4520\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520#primaryimage\",\"url\":\"http:\/\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png\",\"contentUrl\":\"http:\/\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/?p=4520#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.recantha.co.uk\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#website\",\"url\":\"https:\/\/www.recantha.co.uk\/blog\/\",\"name\":\"Raspberry Pi Pod\",\"description\":\"Experiences with the Raspberry Pi micro computer and microcontroller\",\"publisher\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.recantha.co.uk\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#organization\",\"name\":\"Raspberry Pi Pod\",\"url\":\"https:\/\/www.recantha.co.uk\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2016\/03\/cropped-PiPod-Logo-v3.png?fit=800%2C337&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2016\/03\/cropped-PiPod-Logo-v3.png?fit=800%2C337&ssl=1\",\"width\":800,\"height\":337,\"caption\":\"Raspberry Pi Pod\"},\"image\":{\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/recantha\/\",\"https:\/\/x.com\/recantha\",\"https:\/\/www.linkedin.com\/in\/recantha\/\",\"https:\/\/www.youtube.com\/channel\/UCK4F9blabxzmk8Inzhs8tpg\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/person\/c27c4ef2ee1c18b130f1fcd5dcdbb263\",\"name\":\"Michael Horne\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/479778b0677caadde0ceb54c4129804ef674914607e3ed0998808148357d10d8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/479778b0677caadde0ceb54c4129804ef674914607e3ed0998808148357d10d8?s=96&d=mm&r=g\",\"caption\":\"Michael Horne\"},\"url\":\"https:\/\/www.recantha.co.uk\/blog\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io - Raspberry Pi Pod","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.recantha.co.uk\/blog\/?p=4520","og_locale":"en_US","og_type":"article","og_title":"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io - Raspberry Pi Pod","og_description":"Donald Derek has blogged a fantastic tutorial that shows you how to create a Google TV-alike interface to the Raspberry Pi.\u00a0Read all about it here Update: The last time I tried to visit the blog, it was down, so here&hellip;Read more &rarr;","og_url":"https:\/\/www.recantha.co.uk\/blog\/?p=4520","og_site_name":"Raspberry Pi Pod","article_publisher":"https:\/\/www.facebook.com\/recantha\/","article_published_time":"2013-06-07T10:47:28+00:00","og_image":[{"url":"https:\/\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2013\/06\/raspberrypi_tv_google_tv1.jpg","type":"","width":"","height":""}],"author":"Michael Horne","twitter_card":"summary_large_image","twitter_creator":"@recantha","twitter_site":"@recantha","twitter_misc":{"Written by":"Michael Horne","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520#article","isPartOf":{"@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520"},"author":{"name":"Michael Horne","@id":"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/person\/c27c4ef2ee1c18b130f1fcd5dcdbb263"},"headline":"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io","datePublished":"2013-06-07T10:47:28+00:00","mainEntityOfPage":{"@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520"},"wordCount":1634,"commentCount":2,"publisher":{"@id":"https:\/\/www.recantha.co.uk\/blog\/#organization"},"image":{"@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520#primaryimage"},"thumbnailUrl":"http:\/\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png","articleSection":["Media centre","Programming"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.recantha.co.uk\/blog\/?p=4520#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520","url":"https:\/\/www.recantha.co.uk\/blog\/?p=4520","name":"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io - Raspberry Pi Pod","isPartOf":{"@id":"https:\/\/www.recantha.co.uk\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520#primaryimage"},"image":{"@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520#primaryimage"},"thumbnailUrl":"http:\/\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png","datePublished":"2013-06-07T10:47:28+00:00","breadcrumb":{"@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.recantha.co.uk\/blog\/?p=4520"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520#primaryimage","url":"http:\/\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png","contentUrl":"http:\/\/blog.donaldderek.com\/wp-content\/uploads\/2013\/06\/google_tv_preview-1024x576.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.recantha.co.uk\/blog\/?p=4520#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.recantha.co.uk\/blog"},{"@type":"ListItem","position":2,"name":"Build your own Google TV Using #RaspberryPi, NodeJS and Socket.io"}]},{"@type":"WebSite","@id":"https:\/\/www.recantha.co.uk\/blog\/#website","url":"https:\/\/www.recantha.co.uk\/blog\/","name":"Raspberry Pi Pod","description":"Experiences with the Raspberry Pi micro computer and microcontroller","publisher":{"@id":"https:\/\/www.recantha.co.uk\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.recantha.co.uk\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.recantha.co.uk\/blog\/#organization","name":"Raspberry Pi Pod","url":"https:\/\/www.recantha.co.uk\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2016\/03\/cropped-PiPod-Logo-v3.png?fit=800%2C337&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2016\/03\/cropped-PiPod-Logo-v3.png?fit=800%2C337&ssl=1","width":800,"height":337,"caption":"Raspberry Pi Pod"},"image":{"@id":"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/recantha\/","https:\/\/x.com\/recantha","https:\/\/www.linkedin.com\/in\/recantha\/","https:\/\/www.youtube.com\/channel\/UCK4F9blabxzmk8Inzhs8tpg"]},{"@type":"Person","@id":"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/person\/c27c4ef2ee1c18b130f1fcd5dcdbb263","name":"Michael Horne","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.recantha.co.uk\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/479778b0677caadde0ceb54c4129804ef674914607e3ed0998808148357d10d8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/479778b0677caadde0ceb54c4129804ef674914607e3ed0998808148357d10d8?s=96&d=mm&r=g","caption":"Michael Horne"},"url":"https:\/\/www.recantha.co.uk\/blog\/?author=1"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2RsaV-1aU","jetpack-related-posts":[{"id":5370,"url":"https:\/\/www.recantha.co.uk\/blog\/?p=5370","url_meta":{"origin":4520,"position":0},"title":"Building a Google TV with a #RaspberryPi &#8211; workshop","author":"Michael Horne","date":"31 July 2013","format":false,"excerpt":"Here's a great video from Donald Derek of MenaVersity. It's a recorded interactive workshop showing how to use a Pi, NodeJS and Socket.io to build a Google TV system.","rel":"","context":"In &quot;Media centre&quot;","block_context":{"text":"Media centre","link":"https:\/\/www.recantha.co.uk\/blog\/?cat=30"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":14304,"url":"https:\/\/www.recantha.co.uk\/blog\/?p=14304","url_meta":{"origin":4520,"position":1},"title":"Cambridge TV covers the Raspberry Pi Big Birthday Weekend","author":"Michael Horne","date":"9 March 2016","format":false,"excerpt":"Great work again from Cambridge TV as they attend the\u00a0Big Birthday Weekend and interview various people including Philip Colligan, Liz Upton and Crazy Squeak. If you attended the weekend, see if you can spot yourself!","rel":"","context":"In &quot;Big Birthday Weekend&quot;","block_context":{"text":"Big Birthday Weekend","link":"https:\/\/www.recantha.co.uk\/blog\/?cat=84"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.cambridge-tv.co.uk\/wp-content\/uploads\/2015\/03\/CambridgeTV1.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.cambridge-tv.co.uk\/wp-content\/uploads\/2015\/03\/CambridgeTV1.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.cambridge-tv.co.uk\/wp-content\/uploads\/2015\/03\/CambridgeTV1.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.cambridge-tv.co.uk\/wp-content\/uploads\/2015\/03\/CambridgeTV1.png?resize=700%2C400 2x, https:\/\/i0.wp.com\/www.cambridge-tv.co.uk\/wp-content\/uploads\/2015\/03\/CambridgeTV1.png?resize=1050%2C600 3x, https:\/\/i0.wp.com\/www.cambridge-tv.co.uk\/wp-content\/uploads\/2015\/03\/CambridgeTV1.png?resize=1400%2C800 4x"},"classes":[]},{"id":13825,"url":"https:\/\/www.recantha.co.uk\/blog\/?p=13825","url_meta":{"origin":4520,"position":2},"title":"Interested in the Raspberry Pi Astro Pi launch? Get thee to NASA&#8217;s stream","author":"Michael Horne","date":"6 December 2015","format":false,"excerpt":"If you want to see the launch of the rocket with the Astro Pi units onboard, get over to UStream now to watch NASA TV!","rel":"","context":"In &quot;GPIO boards&quot;","block_context":{"text":"GPIO boards","link":"https:\/\/www.recantha.co.uk\/blog\/?cat=20"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/12\/atlas.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/12\/atlas.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/12\/atlas.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/12\/atlas.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/12\/atlas.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":12109,"url":"https:\/\/www.recantha.co.uk\/blog\/?p=12109","url_meta":{"origin":4520,"position":3},"title":"Raspberry Pi television schedule helper for the visually impaired","author":"Michael Horne","date":"5 March 2015","format":false,"excerpt":"Hackaday.io user Chewable Drapery (Dean Walker)'s\u00a0grandfather-in-law is 92 and is gradually losing his sight. In particular, he has real problems reading the on-screen television guide. So, Chewable has constructed a box and a controller, called EVA, using a Raspberry Pi that downloads the TV schedule from an internet API and\u2026","rel":"","context":"In &quot;Geeky Techiness&quot;","block_context":{"text":"Geeky Techiness","link":"https:\/\/www.recantha.co.uk\/blog\/?cat=22"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/03\/eva.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/03\/eva.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/03\/eva.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2015\/03\/eva.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":17554,"url":"https:\/\/www.recantha.co.uk\/blog\/?p=17554","url_meta":{"origin":4520,"position":4},"title":"Google AIY project kit available soon in both UK and USA","author":"Michael Horne","date":"29 August 2017","format":false,"excerpt":"Exciting news for those of you still without a Google AIY Project Kit\u00a0that came free with The Mag Pi 57. Micro Center in the USA and Pimoroni in the UK have announced that they will be stocking the kit in coming months. Micro Center are saying that it's available for\u2026","rel":"","context":"In &quot;AIY&quot;","block_context":{"text":"AIY","link":"https:\/\/www.recantha.co.uk\/blog\/?cat=368"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.recantha.co.uk\/blog\/wp-content\/uploads\/2017\/08\/aiy.jpg?fit=480%2C480&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":14114,"url":"https:\/\/www.recantha.co.uk\/blog\/?p=14114","url_meta":{"origin":4520,"position":5},"title":"Ipswich Raspberry Jam &#8211; 27th February","author":"Michael Horne","date":"1 February 2016","format":false,"excerpt":"Andy Proctor has just announced that tickets are on sale for the next Ipswich Raspberry Jam. This one will take place on 27th February from 10am-4pm at the\u00a0UCS Waterfront Building. If you're in the area, it'll be well worth checking it out. Tickets are \u00a31.50 and are available here.","rel":"","context":"In &quot;Events&quot;","block_context":{"text":"Events","link":"https:\/\/www.recantha.co.uk\/blog\/?cat=19"},"img":{"alt_text":"","src":"https:\/\/img.evbuc.com\/https%3A%2F%2Fimg.evbuc.com%2Fhttps%253A%252F%252Fcdn.evbuc.com%252Fimages%252F18341369%252F146642405308%252F1%252Foriginal.jpg%3Frect%3D0%252C0%252C2160%252C1080%26s%3D33d7fd3224b872da8543f5736a8fd031?h=150&w=300&s=9a1c9d4771e4f66c0003d1b903b736b4","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4520","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4520"}],"version-history":[{"count":0,"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4520\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4520"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.recantha.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}