Рубрики
Без рубрики

Учебник: построить свой собственный смарт-телевизор, используя RaspberryPi, Nodejs и Socket.io

В этом руководстве мы пройдем по установке программного обеспечения и пакетов, базовый шеллкод, скрипты на стороне серверов и сценариев на стороне клиента.

Автор оригинала: Donald Derek.

Кодаментатор Дональд Дерек Является ли докладчик конференции, сторонником с открытым исходным кодом, создателем и активистом. Он организует, облегчает и наставников стартапов событий, а также лично выиграл несколько наград за его проекты, в том числе N! MP. , SoundCloud + Music-плеер Jamendo с дистанционным приложением для мобильного телефона веб-мобильного телефона и менеме , игра Тамагочи, основанная на ваших регистрациях Foursquare. В настоящее время он исследователь на MIT Media Lab. – Отзывчивая среда.

Дональд также создал Raspberrypi-tv. , в котором он делится с нами учебником о том, как создать свой собственный телевизор Google с ним. Эта статья была первоначально опубликована в его блоге .

Аппаратное обеспечение:

  • RaspberryPi (Проверено на модели Raspberry PI I-B, I-B + и II-B )
  • USB Wi-Fi Dongle или кабель Ethernet (проверено на Edimax WiFi Coundle )
  • SD/MicroSD Card (8 ГБ +) (проверьте Noobs )

Стек программного обеспечения:

  • Распабиан – Вилка Debian, предназначенная для Raspberry Pi
  • Node.js.
    • Socket.io – Чтобы обрабатывать соединение между нашим удаленным и нашим телевизором через WebSockets
    • Экспресс – Чтобы обработать некоторые основные HTTP-запросы
    • OMXCONTROL – простой модуль для управления OMXPLAYER, который является лучшим видеоплеерским на RPI
  • Хромиум Браузер
  • Omxplayer.
  • YouTube-DL – скрипт, который позволил вам загрузить видео YouTube
  • Quo.js – обрабатывать жесткие жесты на мобильном веб-приложении
  • HTML5, CSS3 переходы, JavaScript и Усы как шаблон двигатель
  • API YouTube

Конечный результат

Raspberry Pi TV со своим специальным пультом дистанционного управления

Контур

  • Установка программного обеспечения и пакетов.
  • Базовый шеллкод
  • Скрипты на стороне сервера: Node.js, Express.js и socket.io
  • Сценарии на стороне клиента: приборная панель и удаленное мобильное приложение

1. Установка программного обеспечения и пакетов

Установка Raspbian и Node.js

Следуйте этим Учебное пособие Чтобы установить Raspbian и Node.js на вашу Raspberry Pi

Установка браузера Chromium и YouTube-DL

Построить с Источник или использовать APT-Get

sudo apt-get install chromium-browser

Чтобы иметь лучшее отображение, вы также можете установить шрифты Core MC, используя

sudo apt-get install ttf-mscorefonts-installer

Установите и обновите сценарий YouTube-DL

sudo apt-get install youtube-dl 

sudo youtube-dl -U

Chromium на RaspberryPI не ускоряется аппаратным обеспечением, поэтому потоковое видео в браузер – это плохое представление. YouTube-DL поставляется в качестве быстрой альтернативы, видео загружается и/или передается в OMX-плеере, который является аппаратным обеспечением, ускоряется на RPI!

OMX-Player устанавливается по умолчанию Raspbian OS.

2. Базовый шеллкод

Если вы подключаетесь к RPI через SSH, вам нужно будет обновить переменные среды дисплея, выпуская

export DISPLAY=:0.0

Графический вывод этого сеанса теперь указывает на первый дисплей, подключенный к RPI. Чтобы проверить всю вашу настройку среды.

env

Тестовый хромиум в режиме киоска:

chromium --kiosk http://www.google.com

Тест YouTube-DL

youtube-dl youtube_video_url

Я добавил несколько аргументов в команду YouTube-DL

  • Изменено имя по умолчанию загруженного файла: -O YouTube ID [DOT] Расширение файла
  • Сила 720p Режим: -F/22/18
  • Проверьте полный список поддерживаемых форматов YouTube здесь
youtube-dl -o "%(id)s.%(ext)s" -f /22/18 youtube_video_url

После загрузки видео попробуйте воспроизвести его с помощью OMX-Player

omxplayer youtube_video_file

Получайте удовольствие от изучения сочетаний клавиш! Больше ярлыков можно найти здесь Или, проверяя меню справки в OMX-Player.

Изысканный! Давайте автоматизируем этот процесс с помощью Node.js

3. Скрипты на стороне сервера: Node.js, Express.js и socket.io

Исходный код предназначен для простого для семинара. Вот иерархия файлов проекта:

  • публичный
    • js.
    • CSS.
    • изображений
    • шрифты
    • index.html.
    • Remote.html.html.
  • app.js.
  • Package.json.

Package.json – файл JSON, необходимый NPM для автоматической установки зависимостей и хранить другие мета-данные о вашем проекте.

{
    "name": "RasPi.TV",
    "version": "0.0.1",
    "private": false,
    "scripts": {
        "start": "node app.js"
    },
    "dependencies": {
    "express": "3.1.1",
    "socket.io":"0.9.14",
    "omxcontrol":"*"
    }
}

В вашем терминале выпустите следующую команду для установки зависимостей:

npm install

Обратите внимание, что папка называется _ node_modules _ будет создан в вашем каталоге проекта, если вам нравится использовать Git, не забудьте создать .gitignore Файл и просто напишите в нем ” node_modules ” Это проигнорирует папку node_modules из добавления в ваш проект Git

Создайте файл App.js и начните с создания нашего базового HTTP-сервера с Express.js (v3.x.x)

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('/', 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'));
});

Это базовый экспресс-конфигурация HTTP-сервера. Чтобы проверить его, сначала должны создавать статические файлы: index.html и demote.html в публичный dir. Напишите свои любимые сообщения «Hello, World» на этих страницах, затем вернитесь к вашему терминалу и выполните

node app.js

или же

npm start

Будет работать только, если вы добавили следующий фрагмент в ваш Package.json файл

...
"scripts": {
        "start": "node app.js"
    },
...

На сервер init вы получите это на своем stdout Экспресс-сервер Прослушивание по порту 8080 Чтобы проверить ваши статические страницы, запустите это приложение на заднем плане, добавив & Отказ

node app.js &

Теперь это самый примитивный способ запустить приложение Node.js на заднем плане, в то время как изучать Node.js, вы можете нанять несколько модулей, которые могут демомотировать для вас процессы, как PM2.

Теперь у нас есть базовый веб-сервер Node.js, который может служить статическим файлам, давайте откроем режим Chromium в kiosk и тестируйте страницы.

chromium --kiosk http://localhost:8080

Интеграция Socket.IO.

Когда Ajax сначала выскочила, старые разработчики Skool почувствовали свою магию, но они столкнулись с множеством проблем из-за того, как разные браузеры образуют асинхронный JavaScript и XML-запросы. jQuery пришел с решением и предоставил минимальную и кроссплатформующую абстракцию для XHR. Socket.io делает то же самое, но для веб-розетки и может впасть в другие двунаправленные веб-протоколы, если браузер клиентов еще не поддерживают веб-сокеты.

Чтобы обеспечить подключение в реальном времени на каждом браузере, Socket.io выбирает наиболее способный транспорт во время выполнения, не влияя на API. Конечно, некоторые из этих технологий ниже сделают как вашу сеть, так и серверу, особенно падающие отбления сокета Adobe® Flash®, он должен быть отключен или обесценен.

  1. Websocket.
  2. Adobe® Flash® Socket.
  3. Ajax длинный опрос
  4. AJAX Multipart Streaming.
  5. Навсегда iframe.
  6. Опыление JSONP

Для интеграции Socket.io мы добавляем следующее в app.js файл:

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

И чтобы министерство журналов добавить это:

//Socket.io Config
io.set('log level', 1);

При разработке с помощью Socket.io всегда есть мышление базового приложения чата. Я добавил простое в чате веб-приложение с Node.js & socket.io на Github Reppo Ради этого урока!

Наш сервер Socket.io готов, но это еще ничего не делает. Мы реализуем, как мы обрабатываем сообщения и события, отправленные от клиента на сервер рядом.

Сервер боковой сокет. Интеграция ниже:

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);
    });
});

Теперь наш сервер испускает сообщение «сообщение» всякий раз, когда новый клиент подключен, и ждет имя события «Отправить» для обработки данных и выделять его обратно всем подключенным клиентам

В нашем случае у нас есть два типа клиентов: дисплей RPI (телевизор) и мобильное веб-приложение (удаленный)

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...");
   }
 });
)};

Реализация веб-розетки на стороне клиента

Добавьте следующее на REPORTY.HTML:



Добавьте следующее в index.html :



Выполнение ShellCode из Node.js

Node.js позволяет нам запустить системные команды в данных привилегиях дочернего процесса. Это включает в себя возможность передавать аргументы команды и даже проводить результаты одной команды на другую аналогичную UNIX.

Один из способов выполнения команд Shell из Node.js Детский процесс

spawn('echo',['foobar']);

Но если вы хотите передать ответ на другой вызов, вы должны предоставить функцию следующую функцию обратного вызова:

//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);
}

Добавление OMXControl – контроллер OMX-плеер для Node.js

Великие дела можно найти на NPM : Модуль OMXControl позволит вам контролировать OMX-Player через http. Требуется этот модуль InTP вашего основного файла проекта.

var omx = require('omxcontrol');

//use it with express
app.use(omx());

Модуль OMXControl Создайте следующие маршруты для управления воспроизведением видео:

http://localhost:8080/omx/start/:filename
http://localhost:8080/omx/pause
http://localhost:8080/omx/quit

Положить все это вместе

Наше evolved app.js файл

/**
 * 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('/', 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');
        });
    }    

 });
});

4. Клиентские сценарии: приборная панель и удаленное мобильное приложение

Raspberry Pi TV экран в интернет-конце

Описывая в деталях, как я построил интерфейс, отсутствует в этом уроке, однако я хотел бы указать на несколько советов, которые я обнаружил при выполнении этого проекта.

При проектировании для 10-футового экрана для рассмотрения некоторых дизайнерских советов, Google собрал хороший набор этих трюков на их Разработчики сайта

Raspberry Pi Remote.

Вместо того, чтобы создать классический пульт, полный кнопок, я решил дать Quo.js Попробуйте, это фантастическая перекрестная платформа для промахов Gestures JS Библиотека!

$$(".r-container").swipeLeft(function(){
socket.emit('control',{action:"swipeLeft"}); 
});

Вот пример того, как я отправляю сообщение «Управление» обратно на сервер с действием данных: проведите пальцем влево

Сервер будет обрабатывать это сообщение, отправив его на экран, клиент экрана будет обрабатывать это сообщение, перемещая выбранный квадрат в следующее приложение (смотреть, слушать, воспроизведение)

Я также скомпилировал список Meta Trick, который позволит вашему веб-приложению iPhone Mobile выглядеть как родной с красивым значком и засветным экраном. Просто добавьте следующее в свой HTML блоки






Специальная благодарность

Этот семинар был дан в Lamba Labs Beirut First Hackerspace После серии переговоров молнии проверяют презентацию здесь Если вы хотите обойти учебное пособие и прыгать в веселые вещи, вы всегда можете вилить код на Гадость

Этот семинар также работает GDG Beirut и идея была запечена во время молния говорит что я дал в Google IO Extend Beirut 2013