Автор оригинала: 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®, он должен быть отключен или обесценен.
- Websocket.
- Adobe® Flash® Socket.
- Ajax длинный опрос
- AJAX Multipart Streaming.
- Навсегда iframe.
- Опыление 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