Автор: Николай Хабаров
Одним прекрасным пятничным вечером я решил посмотреть дома фильм: включил ноутбук, подключил HDMI-кабель через переходник с DisplayPort, взял пульт, включил телевизор, запустил воспроизведение на ноутбуке. И понял, что громкость на телевизоре недостаточна — пришлось снова искать пульт, чтобы ее увеличить… Тут я подумал «А можно ли этот процесс как-то упростить?»
Субботнее утро выдалось крайне плодотворным. Я решил сделать собственный сетевой мультимедиа-проигрыватель, причем такой, каким его представляю я. Почти все детали были взяты из кладовки, сердце плеера — Raspberry Pi. Подробнее, что у него внутри, и как собрать аналогичное устройство, смотрите под катом.
Как можно понять из описания, мои требования к проигрывателю крайне просты: способность воспроизводить контент из сети, хранилище на несколько сотен гигабайт, возможность управления тем же пультом, что и телевизор; наличие USB-порта желательно, но не обязательно. Покупные проигрыватели на Android отпали сразу, т. к. подобные устройства — в основном чистый Китай, в худшем смысле слова, а воевать с багами внутри них у меня желания не было. Кроме того, непонятно, как реализовать управление таким устройством с телевизионного пульта, тем более, графический интерфейс Android явно не предназначен для управления с пульта в принципе. Поэтому и начались поиски барахла, из которого можно сделать вещь.
Подбираем детали
Прежде всего хотелось бы просто попробовать и понять целесообразность изготовления конечного устройства. Поэтому для начала мы возьмем минимум деталей и испытаем потенциальный медиаплеер в работе. Идем в кладовку и буквально откапываем нужные нам детали:
1. Компьютер с HDMI-выходом. Старенький Raspberry Pi 1 вполне подходит для наших целей, также можно использовать Raspberry Pi 2.
2. Блок питания для платы — подойдет microUSB-зарядка от старого телефона. «На попробовать» можно взять любую, но желательно взять источник обеспечивающий выходной ток 1А (одного ампера за глаза хватит и для Pi 2, см. требования);
3. microSD-карточка на 4 ГБ или более.
4. USB-мышка и/или клавиатура (можно беспроводные) и, опционально, приемник инфракрасного сигнала TSOP4836 или аналогичный.
5. USB Wi-Fi-адаптер или возможность подключить Ethernet-кабель с интернетом в плату.
Ставим OpenElec, пробуем
На этом этапе мы запустим OpenElec в минимально возможном в виде. Едва подумав о ПО для своего мультимедиа-проигрывателя, я вспомнил XBMC, позже переименованный в Kodi . Но желания ставить какую-то операционку, а потом настраивать Kodi не было. Поэтому я решил погуглить и нашел эту сборку операционной системы GNU/Linux, поверх которой Kodi уже установлен. Называется эта сборка OpenElec, это проект с открытыми исходными кодами. Его официальный сайт — openelec.tv
Итак, качаем установочный образ с официального сайта. Выбираем желательную версию и платформу, на которой будем ее запускать (в моем случае stable релиз для Rasberry Pi), и качаем 'Diskimage' (файл с расширением .img.gz).
Распаковываем образ:
$ gunzip -d <имя файла>.img.gz
И записываем на карту памяти:
$ sudo dd if= <имя файла>.img of=/dev/mmblck0 bs=4M
Поправьте /dev/mmblck0 — если карточка памяти у вас в системе не одна.
Внимание! Содержимое карты памяти будет полностью затерто.
Пользователи ОС Windows могут использовать бесплатную утилиту Win32 Disk Imager. Утилита имеет графический интерфейс — выбираете файл, карточку памяти и нажимаете 'Write'.
Теперь убеждаемся что все записано на карточку командой
$ sync
Или просто извлекаем карточку через безопасное извлечение устройства в графическом интерфейсе ОС. Достаем ее физически и ставим в Raspberry Pi. Далее подключаем Ethernet-кабель с интернетом или вставляем USB Wi-Fi-адаптер, подключаем мышку, HDMI-кабель к телевизору. При желании использовать инфракрасный пульт нужно подключить ИК-приемник к GPIO18 и питанию процессора(3.3В). Итоговая схема подключения выглядит следующим образом:
Если вы решили использовать инфракрасный приемник, будьте аккуратны с ним
— убедитесь в правильности расположения выводов у вашего приемника.
Все, теперь можно посмотреть на саму среду. Запитываем плату от источника питания. После загрузки на экране появится мастер первоначальной настройки:
Во время настройки рекомендую сразу включить SSH-доступ. Все остальные вопросы тривиальны.
Теперь можете поиграть с самой средой будущего плеера при помощи мышки и/или клавиатуры. Можете попробовать воспроизвести видео в различных форматах (можно подключить USB-флешку к свободным портам) и вообще понять, что к чему. Существуют различные корпуса для самой платы Raspberry Pi, возможно, кого-то все устроит в таком минималистичном виде, можно например подключить беспроводную USB-мышку и пользоваться устройством. Мы же продолжим его совершенствовать.
Подключаем ИК-пульт
Если вы решили не подключить ИК-приемник, можете просто пропустить этот раздел.
Чтобы использовать пульт, нам необходимо настроить LIRC. Для начала давайте включим модуль, который непосредственно работает с приемником через GPIO-порт. Для этого нужно добавить строчку в файл конфига DeviceTree. Логинимся через SSH на ваше устройство (вы же включили SSH при первоначальной настройке? Если нет, это можно сделать в графическом интерфейсе самой системы).
$ ssh root@ip_address
Пароль по умолчанию — openelec. Добавляем нужную нам строку в файл:
# mount -o remount,rw /flash
# nano /flash/config.txt
в самый конец добавляем строку и затем перезагружаем:
dtoverlay=lirc-rpi
Теперь нам нужно убедиться, что все работает и LIRC сможет получать команды с пульта, для этого останавливаем LIRC и пытаемся получить данные с пульта:
# killall lircd
# mode2 -d /dev/lirc0
Нажимаем на любую кнопку пульта и светим на приемник — в консоли должен побежать текст, описывающий приходящие импульсы. Теперь мы убедились, что все работает и можем обучить LIRC использовать именно ваш пульт. Обращаю внимание, что lircd во время процесса настройки должен быть остановлен, мы это сделали ранее с помощью команды kill. Для обучения существует специальная утилита irrecord, для её запуска выполняем команды:
# cd /storage/.config
# irrecord -d /dev/lirc0 lircd.conf
Далее следуем инструкциям на экране. В начале утилита попросит понажимать различные кнопки на пульте пока не заполнятся точки на экране, чтобы обучиться паттерну вашего пульта. Затем нужно будет текстом указывать, использованию какой кнопки вы хотите обучить LIRC, и посветить на приемник.
Я рекомендую обучить как минимум следующим кнопкам:
KEY_UP
KEY_DOWN
KEY_LEFT
KEY_RIGHT
KEY_OK
KEY_PLAY
KEY_EXIT
KEY_STOP
KEY_INFO
KEY_EPG
Весь список доступных в системе кнопок можно получить по команде:
# irrecord -list namespace
На пульте вы можете выбирать любые удобные для вас кнопки. У большинства телевизоров в режиме HDMI большая часть кнопок не делают ничего, что нам, конечно, на руку. В результате у нас должен получится файл lircd.conf с параметрами вашего пульта — перезагружаем плату и пробуем использовать пульт.
Так же можно реализовать включение/выключение проигрывателя. Для это нужно соединить приемник со вторым выводом Raspberry PI GPIO1 для Raspberry PI 1 или GPIO3 для Raspberry PI 2 — на обоих платах эти выводы расположены в одном и том же месте разъема платы:
Соединив этот вывод с землей, можно разбудить плату, находящуюся в выключенном состоянии. При таком подключении можно запрограммировать кнопку KEY_POWER, и плеер будет выключаться при нажатии на нее, а его включение будет осуществляться по любому сигналу от любого пульта.
Собираем девайс посерьезнее
Мне захотелось сделать более основательный девайс с внешностью заводского устройства и добавить в него жесткий диск. Я заглянул в кладовку и нашел старенький спутниковый ресивер. Внутри уже имеется БП достаточной для всех компонентов мощности, имеется приемник ИК-сигнала, тумблер выключения питания на задней стенке. Есть и возможность сделать часы на передней панели за счет уже установленного семисегментного индикатора. И конечно же, сам корпус отлично подходит для наших целей. Спутниковый приемник можно заменить старым DVD или VHS-проигрывателем даже в нерабочем состоянии.
Внимание, при разборке устройства будьте аккуратны с блоком питания — он содержит конденсаторы, которые могут быть все еще заряжены от сети. И при последующей сборке/наладке будьте аккуратны при включении — на плате БП имеют компоненты, на которых во включенном состоянии присутствует 220 В.
Вскрываем корпус ресивера/видеомагнитофона. Для начала нам нужно убедиться, что у блока питания есть 5В выход, который может выдать необходимую мощность. Для этого с помощью мультиметра проверяем наличие 5В питания и затем прослеживаем, через какие компоненты получаются эти 5В. Если элементная база выпрямителя и диаметр обмотки трансформатора блока питания способны выдержать 2-3 ампера, нам повезло — источник есть, в противном случае придется менять источник в корпусе на более мощный. Затем вынимаем основную плату/лентопротяжный механизм/оптический привод и отправляем его обратно в кладовку — он еще пригодится. Внутри оставляем лишь плату БП и плату с лицевой панелью, на которой есть ИК-приемник.
Теперь выбираем, куда установить саму Raspberry Pi. Выбор тут довольно прост — сторона платы с HDMI должна выходить наружу корпуса, сторона с USB-портами должна быть смонтирована внутри для подключения внутренних компонентов, кроме того, нам нужен хоть какой-нибудь доступ к microSD-карточке на случай смены прошивки. На корпусе ресивера имеются отверстия для RCA-разъемов, поставим плату так, чтобы HDMI-разъем был максимально доступен снаружи. С этой же стороны имеются выходы звуковой платы и microUSB, работающего в режиме периферийного устройства. Эти разъемы нам не интересны, питание мы заведем снаружи через основной GPIO-разъем платы.
Размечаем, где нужно немножко подрезать, чтобы HDMI-разъем свободно вставлялся в плату снаружи корпуса и намечаем четыре отверстия для установки платы. Я использовал такие стойки:
Стойки родной платы мешали, и я удалил их при помощи пассатижей. Манипуляции нужно проводить аккуратно, неловким движением можно легко погнуть сам корпус. Сверлим, пилим, прикручиваем подходящими болтиками стойки и к ним саму плату.
Теперь нужно найти место для HDD. Здесь требование довольно простое — нужно оставить несколько свободных сантиметров внутри корпуса со стороны SATA-разъема, т. к. туда будет вставлен переходник. На жестком диске есть резьба на нижней поверхности и по бокам HDD. Винчестер нужно чуть приподнять, чтобы он не лежал на металле. Я решил проблему очень просто — взял подходящие под нижнюю резьбу болты, но чуть более длинные чем нужно, и проложил расстояние между корпусом и HDD гайками большего размера.
Теперь нам понадобиться найти SATA USB-преобразователь или старый контейнер для HDD, откуда такой преобразователь можно вытащить. У меня был контейнер, но он, к сожалению, оказался нерабочим. Пришлось за SATA USB-преобразователем бежать в магазин. USB-разъем мы вставим в Raspberry PI, но, чтобы не нагружать довольно серьезными токами плату, которых требует HDD, особенно при раскручивании шпинделя, нужно провести дополнительное питание напрямую от БП. В моем случае у переходника был кабель с двумя USB-разъемами, один из них я и подключил напрямую к блоку питания, распаяв ответный USB-разъем рядом с БП.
Еще две вещи, о которых стоило бы сразу подумать. Первое — где и как будет расположен внешний USB-порт. Второе — куда ставить Wi-Fi-адаптер, или если вы планируете реализовать только подключение по Ethernet, как вынести Ethernet-разъем на стенку корпуса (если расположить плату краем с этим разъемом к корпусу, USB-устройства изнутри вы подключить не сможете). Удлинить Ethernet можно, поставив внутри корпуса обычную настенную розетку и обжав короткий провод с коннектором.
Сейчас продаются совсем крошечные USB Wi-Fi-донглы, но ставить такой внутрь металлического корпуса не стоит — может плохо проходить сигнал. Можно взять короткий USB-удлинитель, вывести USB-разъем на заднюю часть корпуса и вставить его туда. Также бывают USB-адаптеры со съемными антеннами, можно удлинить RMA-разъём до задней стенки корпуса и там прикрутить антенну. У меня был довольно старый и, как следствие, довольно большой USB Wi-Fi-адаптер с накручивающейся антенной и miniUSB-входом. Девать его из-за размеров мне было некуда, и я решил применить его в дело. Снял корпус — его форма не давала прикрепить снаружи антенну. Плата была довольно большая, и мне пришлось хорошенько подумать над ее размещением. К счастью, она оказалась очень тонкой, и я решил поставить ее над USB-разъёмами от Raspberry Pi. RMA-разъем вывел наружу, закрутил на гайку и внутри корпуса поставил одну высокую стойку для платы. Доступ к USB остался, а антенна оказалась поднята над корпусом. Отлично!
Теперь надо как-то закрепить USB-удлинитель на лицевой панели, убедившись, что он ничему не помешает внутри корпуса. В моем случае на ресивере имелась дверца для карточек доступа, и я решил поставить разъём за нее — чтобы не пылился! Поэтому слишком аккуратно я его вырезать не стал, а сзади залил термоклеем.
С платой лицевой панели ситуация более интересная — вариантов того, из чего она состоит, множество. Мне пришлось реализовывать динамическую индикацию семисигментных индикаторов с помощью DMA (Direct Memory Access, прямая реализация динамической индикации через GPIO-порты потребляла бы слишком много ресурсов CPU, и яркость свечения сегментов была бы неравномерной из-за активностей операционной системы). Но это уже тема для отдельной статьи, да и к тому же подобные платы могут кардинально отличаться, поэтому здесь предоставим право проявить свой творческий потенциал читателю. Можете изучить исходные коды реализации для моей платы. В простейшем случаем можно просто перерезать дорожки, идущие к ИК-приемнику, и припаяться к нему напрямую тремя проводами. Отмечу лишь, что для подключения к GPIO-разъему платы я использовал IDE-шлейф, он прекрасно надевается на разъем Raspberry Pi, и провода можно легко распаять с другими компонентами.
В конечном итоге, у меня получилось вот такое устройство:
Настраиваем
Если при включении вы увидите цветной квадрат в верхнем правом углу экрана, это означает, что питания для Raspberry Pi недостаточно — либо слабый блок питания, либо слишком тонкие провода, либо USB-периферия отбирает слишком много. В первом случае поможет только замена БП на более мощный. Во втором — проблему легко решить заменой проводов на более толстые или параллельным использованием нескольких жил, в третьем — проблема решается путем запитывания USB-устройств напрямую от БП, или, например, установкой USB-хаба с возможностью подключить внешний источник питания.
Также вы наверняка увидите, что ваш HDD подключился к системе как внешняя флешка. Давайте сделаем его основным хранилищем в операционной системе. При первом запуске OpenElec автоматически начинает использовать все свободное пространство на microSD-карточке под раздел с данными, который затем монтируется как /storage. Наиболее удачным мне кажется решение использовать в качестве /storage жесткий диск целиком. Для этого отформатируйте жесткий диск и создайте на нем раздел с файловой системой ext3/4. Это можно сделать прямо на плеере, используя утилиты parted и mkfs, команды ниже затрут все содержимое диска и создадут один ext4 раздел:
# umount /dev/sda1
# parted /dev/sda
GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel GPT
mklabel GPT
Warning: The existing disk label on /dev/sda will be destroyed and all data on
this disk will be lost. Do you want to continue?
Yes/No? yes
yes
(parted) mkpart primary 2048s 100%
mkpart primary 2048s 100%
(parted) q
q
Information: You may need to update /etc/fstab.
# mkfs.ext4 /dev/sda1
Для это нужно будет зайти по SSH на проигрыватель. Затем примонтируйте новый раздел куда-нибудь:
# mkdir /tmp/hdd
# mount /dev/sda1 /tmp/hdd
Cкопируйте все содержимое /storage в новый раздел, чтобы сохранить текущее состояние:
# cp -rf /storage/. /tmp/hdd
Отмонтируйте раздел и при желании удалите папку:
# umount /dev/sda1
# rmdir /tmp/hdd
Теперь надо указать, какой именно диск мы должны монтировать при загрузке. Сделать это можно, поправив командую строку параметров ядра, но для начала узнаем UUID раздела нашего винчестера:
# blkid /dev/sda1
Скопируйте в буфер обмена UUID раздела. Теперь перемонтируем файловую систему с конфигом ядра на запись и поправим его:
# mount -o rw,remount /flash
# nano /flash/cmdline.txt
В файле заменим параметр disk на UUID нашего диска. Содержимое файла должно получится примерно такое:
boot=/dev/mmcblk0p1 disk=UUID=95013338-89b1-43af-8471-9b30efc85d98 quiet
После перезагрузки проигрыватель будет использовать жесткий диск как /storage, а раздел на карточке памяти можно удалить, чтобы он при загрузке не монтировался автоматически:
# parted -s /dev/mmcblk0 rm 2
Вот такие веселые у меня выдались выходные. Не забывайте, что на борту этого медиаплеера находится операционная система GNU/Linux, и вы можете самостоятельно модифицировать/дополнять ее как вам угодно. Также можно решать какие-то задачи домашней автоматизации, использую все то же устройство.
И напоследок видео выступления автора статьи, рассказывающего об устройстве.
Всем приятного просмотра!
Автор: DataArt