Donald Derek a blogué un tutoriel fantastique qui vous montre comment créer une interface similaire à Google TV avec le Raspberry Pi. Lisez tout a propos de ça ici
Mise à jour: La dernière fois que j’ai essayé de visiter le blog, il était en panne, alors voici le billet de blog pour la postérité:
Il s’est avéré que Google fait également sa propre chose pour l’écran de 10 pieds. Google a annoncé 2 versions de leur célèbre nouveau téléviseur, la première s’appelle la Buddy Box qui est actuellement une boîte coûteuse fabriquée par Sony et le second est un téléviseur intégré directement intégré au téléviseur qui sera annoncé prochainement.
La Google TV ressemble à quelque chose comme ça:
Aperçu de Google TV
Développeurs: vous pouvez commencer à créer vos propres applications Web pour Google TV ou rénover n’importe quelle application Android pour l’adapter à l’écran de 10 pieds, toutes les ressources sont disponibles chez les développeurs de Google Site
Les hackers et les fabricants aiment réinventer la roue, et c’est toujours amusant quand vous le faites. Alors nous allons construire notre propre version de Google TV en utilisant les technologies open source suivantes:
Matériel:
Pile de logiciels:
- Raspbian OS – une distribution Debian spécialement conçue pour le rPi
- NodeJs
- Socket.io – gérer la connexion entre notre télécommande et notre téléviseur via des websockets
- Express – pour gérer certaines requêtes http basiques
- Omxcontrol – un module simple pour contrôler l’OMXPlayer qui est le meilleur lecteur vidéo sur le rPi
- Chrome Navigateur
- OMXPlayer
- Youtube-dl – un script qui vous permet de télécharger des vidéos youtube
- QuoJS – pour gérer les gestes de balayage sur l’application Web mobile
- HTML5, transitions CSS3, Javascript et Moustache comme moteur de modèle
- API Youtube
Le résultat final
Raspberry Pi TV avec sa télécommande spéciale
Le projet est divisé en 4 catégories principales:
- Installation de la pile logicielle
- Commandes et scripts de base du shell
- Construire le backend: NodeJS + Express + Socket.io
- Construire le front-end
1.Installation de la pile logicielle:
Installez Raspbian et NodeJS
Suivez ceci Didacticiel pour installer Raspbian et Node Js sur votre Raspberry Pi
Installez Chromium et Youtube-dl
Installez le navigateur Chromium pour le Raspberry Pi La source
sudo apt-get install chromium-browser
Afin d’avoir un meilleur affichage, vous pouvez également installer les polices principales MC en utilisant
sudo apt-get install ttf-mscorefonts-installer
Installer et mettre à jour Youtube Downloader
sudo apt-get install youtube-dl sudo youtube-dl -UNote-1: Il y a un problème lorsque vous souhaitez diffuser des vidéos sur le RaspberryPi à partir de YouTube dans Chromium, elles sont extrêmement lentes car les vidéos ne sont pas rendues sur le GPU. Youtube-dl est une alternative rapide, la vidéo est téléchargée à la place puis jouée par l’OMXPlayer qui rendra nos vidéos sur le GPU nous donnant une bonne qualité de vidéos HD. Note-2: OMXPlayer est installé par défaut sur le Raspbian.
Commandes et scripts de base du shell
Si vous utilisez SSH pour vous connecter à votre RaspberryPi, vous devez d’abord ajouter « DISPLAY =: 0.0 » à vos variables d’environnement, en exécutant simplement
export DISPLAY=:0.0
Pour vérifier toutes vos variables d’environnement
env
Tester le chrome en mode kiosque:
chromium --kiosk http://www.google.com
Tester Youtube-dl
youtube-dl youtube_video_url
J’ai ajouté quelques paramètres à youtube-dl pour changer le nom du fichier téléchargé afin qu’il ne soit que « -o youtube ID [dot] l’extension »et avec le« -f / 22/18 »je peux forcer ce script à me télécharger une version 720p de la vidéo. Consultez la liste complète des formats YouTube pris en charge ici
youtube-dl -o "%(id)s.%(ext)s" -f /22/18 youtube_video_url
Après avoir téléchargé la vidéo, essayez de la lire en utilisant OMXPLayer
omxplayer youtube_video_file
Amusez-vous en essayant les raccourcis clavier pour mettre en pause / reprendre votre vidéo et beaucoup plus
Fantaisie! Automatisons ce processus à l’aide de Node JS
Construire le backend: NodeJS + Express + Socket.io
Le code source se veut simple pour le plaisir de l’atelier. Voici la hiérarchie du projet:
- Publique
- js
- css
- images
- polices
- index.html
- remote.html
- app.js
- package.json
Package.json – Un fichier JSON nécessaire à npm pour installer automatiquement les dépendances et enregistrer des informations de base sur votre projet
{
"name": "GoogleTV-rPi",
"version": "0.0.1",
"private": false,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.1.1",
"socket.io":"0.9.14",
"omxcontrol":"*"
}
}
après avoir créé ce fichier, accédez au répertoire de votre application et exécutez ce qui suit pour installer les dépendances.
npm installNote-3: Notez qu’un dossier appelé node_modules sera créé avant cette action, si vous aimez utiliser git, n’oubliez pas de créer un .gitignore fichier et écrivez-y simplement « node_modules« Cela ignorera le dossier node_modules d’être ajouté à votre projet git
Créez le fichier app.js et commençons par créer notre serveur HTTP Express de base
var express = require('express')
, app = express()
, server = require('http').createServer(app)
, path = require('path')
// all environments
app.set('port', process.env.TEST_PORT || 8080);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
//Routes
app.get("https://www.raspberryme.com/", function (req, res) {
res.sendfile(__dirname + '/public/index.html');
});
app.get('/remote', function (req, res) {
res.sendfile(__dirname + '/public/remote.html');
});
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Ceci est notre configuration de serveur HTTP Express de base avec nos routes. Pour tester ce que vous avez fait jusqu’à présent, vous devez d’abord créer les fichiers index.html et remote.html dans le répertoire public /, y écrire vos messages « Hello, World » préférés, puis retourner sur votre terminal et exécuter
node app.js
ou
npm startNote-4: Cela ne fonctionnera que si vous avez ajouté le morceau de code suivant à votre package.json
...
"scripts": {
"start": "node app.js"
},
...
Une fois que votre serveur démarre, il affichera que Serveur express à l’écoute sur le port 8080
Pour tester vos pages « Hello, World », vous devez exécuter cette application en arrière-plan en faisant simplement
node app.js &
Maintenant, c’est le moyen le plus primitif de lancer une application Node en arrière-plan, tout en apprenant le nœud, vous pourriez tomber sur certains modules qui automatisent cette tâche simple, tout commeForever.js
Maintenant, notre application Node est opérationnelle en arrière-plan, ouvrons chrome en mode kiosque et testons nos pages Hello, World.
chromium --kiosk http://localhost:8080
Ajout de Socket.io Magic
Je crois fermement que les WebSockets sont la base du Web moderne, j’aime toujours souligner l’analogie suivante qui m’a aidé à comprendre Socket.io
Lorsque AJAX est apparu pour la première fois, les anciens développeurs de skool ont ressenti sa magie, mais ils ont rencontré de nombreux problèmes en raison de la façon dont différents navigateurs gèrent les requêtes JavaScript et XML asynchrones. jQuery est venu avec la solution en fournissant un ensemble agréable et minimal de fonctions pour faire face au cauchemar des navigateurs. Socket.io a fait de même mais pour les WebSockets, encore plus!
Afin de fournir une connectivité en temps réel sur chaque navigateur, Socket.IO sélectionne le transport le plus performant au moment de l’exécution, sans que cela n’affecte l’API.
- WebSocket
- Prise Adobe® Flash®
- Interrogation longue AJAX
- Diffusion en plusieurs parties AJAX
- Forever Iframe
- Interrogation JSONP
Afin d’intégrer Socket.io, nous devons ajouter ce qui suit à notre app.js fichier:
var express = require('express')
, app = express()
, server = require('http').createServer(app)
, path = require('path')
, io = require('socket.io').listen(server)
, spawn = require('child_process').spawn
et pour réduire les journaux, ajoutez ceci:
//Socket.io Config
io.set('log level', 1);
Lorsque vous développez avec Socket.io, pensez toujours comme si vous créez une application Hello, World Chat. J’ai ajouté une application de chat simple réalisée avec Node & Socket.io sur un dépôt github pour le bien de ce tutoriel!
Notre serveur Socket.io est prêt, mais il ne fait rien, nous devons implémenter la façon dont nous traitons les messages et les événements envoyés du client au serveur.
Voici comment vous implémentez cela du côté du serveur, notez que vous devez également implémenter la façon dont vous gérez les messages du côté du client, nous verrons cela au fur et à mesure que nous progressons tout au long de ce tutoriel.
io.sockets.on('connection', function (socket) {
socket.emit('message', { message: 'welcome to the chat' });
socket.on('send', function (data) {
//Emit to all
io.sockets.emit('message', data);
});
});
Maintenant, notre serveur émet le message «message» chaque fois qu’un nouveau client est connecté, et attend un nom d’événement «envoyer» pour traiter les données et les renvoyer à tous les clients connectés
Dans notre cas, nous avons deux types de clients: l’écran RaspberryPi (écran) et l’application Web mobile (à distance)
var ss;
//Socket.io Server
io.sockets.on('connection', function (socket) {
socket.on("screen", function(data){
socket.type = "screen";
//Save the screen socket
ss = socket;
console.log("Screen ready...");
});
socket.on("remote", function(data){
socket.type = "remote";
console.log("Remote ready...");
if(ss != undefined){
console.log("Synced...");
}
});
)};
Manipulation des prises côté client
à l’intérieur de remote.html, nous devrions avoir ce qui suit:
<script src="https://www.raspberryme.com/socket.io/socket.io.js"> </script>
<script>
//use http://raspberryPi.local if your using Avahi Service
//or use your RasperryPi IP instead
var socket = io.connect('http://raspberrypi.local:8080');
socket.on('connect', function(data){
socket.emit('screen');
});
</script>
Sur notre index.html
<script src="https://www.raspberryme.com/socket.io/socket.io.js"> </script>
<script>
//use http://raspberryPi.local if your using Avahi Service
//or use your RasperryPi IP instead
var socket = io.connect('http://raspberrypi.local:8080');
socket.on('connect', function(data){
socket.emit('screen');
});
</script>
Exécuter les commandes Shell à partir du serveur de nœuds
Node nous permet d’exécuter une commande système dans un nouveau processus enfant et d’écouter ses entrées / sorties. Cela inclut la possibilité de transmettre des arguments à la commande et même de diriger les résultats d’une commande vers une autre.La manière de base d’exécuter des commandes shell depuis NodeJS est très simple
spawn('echo',['foobar']);
Mais si vous souhaitez diriger la sortie, vous devez ajouter la fonction suivante à votre fichier app.js:
//Run and pipe shell script output
function run_shell(cmd, args, cb, end) {
var spawn = require('child_process').spawn,
child = spawn(cmd, args),
me = this;
child.stdout.on('data', function (buffer) { cb(me, buffer) });
child.stdout.on('end', end);
}
Ajout d’OMXControl – le module de nœud de contrôleur OMXPlayer
Heureusement, j’ai trouvé un module de nœud sur npmjs.org qui vous permettent de contrôler votre OMXPlayer en utilisant Express!
ajoutez simplement ce qui suit à votre fichier app.js pour l’utiliser.
var omx = require('omxcontrol');
//use it with express
app.use(omx());
Cela créera pour nous les itinéraires suivants, que nous pouvons utiliser pour contrôler et lire nos vidéos:
http://localhost:8080/omx/start/:filename http://localhost:8080/omx/pause http://localhost:8080/omx/quit
Plutôt génial!
Mettre tous ensemble
Notre fichier app.js évolué
/**
* Module dependencies.
*/
var express = require('express')
, app = express()
, server = require('http').createServer(app)
, path = require('path')
, io = require('socket.io').listen(server)
, spawn = require('child_process').spawn
, omx = require('omxcontrol');
// all environments
app.set('port', process.env.TEST_PORT || 8080);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(omx());
//Routes
app.get("https://www.raspberryme.com/", function (req, res) {
res.sendfile(__dirname + '/public/index.html');
});
app.get('/remote', function (req, res) {
res.sendfile(__dirname + '/public/remote.html');
});
//Socket.io Congfig
io.set('log level', 1);
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
//Run and pipe shell script output
function run_shell(cmd, args, cb, end) {
var spawn = require('child_process').spawn,
child = spawn(cmd, args),
me = this;
child.stdout.on('data', function (buffer) { cb(me, buffer) });
child.stdout.on('end', end);
}
//Save the Screen Socket in this variable
var ss;
//Socket.io Server
io.sockets.on('connection', function (socket) {
socket.on("screen", function(data){
socket.type = "screen";
ss = socket;
console.log("Screen ready...");
});
socket.on("remote", function(data){
socket.type = "remote";
console.log("Remote ready...");
});
socket.on("controll", function(data){
console.log(data);
if(socket.type === "remote"){
if(data.action === "tap"){
if(ss != undefined){
ss.emit("controlling", {action:"enter"});
}
}
else if(data.action === "swipeLeft"){
if(ss != undefined){
ss.emit("controlling", {action:"goLeft"});
}
}
else if(data.action === "swipeRight"){
if(ss != undefined){
ss.emit("controlling", {action:"goRight"});
}
}
}
});
socket.on("video", function(data){
if( data.action === "play"){
var id = data.video_id,
url = "http://www.youtube.com/watch?v="+id;
var runShell = new run_shell('youtube-dl',['-o','%(id)s.%(ext)s','-f','/18/22',url],
function (me, buffer) {
me.stdout += buffer.toString();
socket.emit("loading",{output: me.stdout});
console.log(me.stdout)
},
function () {
//child = spawn('omxplayer',[id+'.mp4']);
omx.start(id+'.mp4');
});
}
});
});
Construire le front-end
Écran de télévision Raspberry Pi Front-end
Décrire en détail comment j’ai construit le front-end n’entre pas dans le cadre de ce tutoriel, mais je voudrais souligner quelques astuces que j’ai découvertes en faisant ce projet au cours du week-end.
Lors de la conception de l’écran 10 ′, vous devez suivre certaines considérations de conception, Google a rassemblé un bel ensemble de ces normes sur leur Site des développeurs
Télécommande Raspberry Pi TV
Au lieu de créer une télécommande typique, pleine de faux boutons, j’ai décidé de donner QuoJS à essayer, c’est vraiment fantastique et facile à utiliser!
$$(".r-container").swipeLeft(function(){
socket.emit('control',{action:"swipeLeft"});
});
Voici un exemple de la façon dont j’envoie le message « Control » au serveur avec l’action de données: « swipeLeft »
le serveur gérera ce message en l’envoyant à l’écran, le client d’écran gérera ce message en déplaçant le carré sélectionné vers l’application suivante (Watch, Listen, Play)
Je suis également tombé sur quelques astuces qui permettront à votre application Web mobile iPhone de ressembler à une application native avec une belle icône et un écran de démarrage.
Ajoutez simplement ce qui suit à vos blocs HTML
<link rel="apple-touch-icon" href="https://www.raspberryme.com/blog/images/custom_icon.png"/>
<link rel="apple-touch-startup-image" href="images/startup.png">
<meta name="viewport" content="width=device-width initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-title" content="Remote">
<meta name="apple-mobile-web-app-capable" content="yes">
Conclusion
Ce projet est toujours un travail en cours, des mises à jour seront bientôt disponibles. Si vous avez aimé ce tutoriel, n’oubliez pas de vérifier le code source sur Github et montrez un peu d’amour en le mettant en vedette.
Un merci spécial à tous ceux qui ont assisté à l’atelier à Lamba Labs Beirut Hackerspacenous piratons et faisons des choses assez cool là-bas, venez nous rejoindre si vous le pouvez!
Cet atelier est également alimenté par GDG Beyrouth et l’idée a été cuite pendant mon discours éclair au Google IO Extend Beyrouth 2013
Ce tutoriel est sponsorisé par T3 Moyen-Orient
Et il a été entièrement enregistré par Menaveristy Vidéos à venir.
-
SPORTLINK Socket Wall Mount Stand Hanger for Google Home Mini/Google Nest Mini (2nd Gen), Compact Holder Case Plug in Kitchen Bathroom Bedroom, Hides The Google Mini Cord (Noir)
-
Baaletc Outlet Mural Hanger pour Google Home Mini/Google Nest Mini (2nd Gen) Voice Assistants, Prise Wall Mount Stand Holder pour Home Voice Assistants, Cache la Câble de Home Mini








