[Из песочницы] WiFi колонка/плеер на базе Orange Pi Zero или история о потерянном времени

Доброго дня уважаемым хабровчанам!

Предыстория


История моя началась с того, что по просьбе одного друга нужно было сделать небольшое программируемое устройство с выводом звука и GPIO. Давно хотел поработать с каким-либо одноплатником *Pi и потому сразу решил делать на чем-то подобном (результат + опыт). Друг почти сразу отказался от предложенного проекта, ну, а я оказался с купленной платой OrangePi Zero. Некоторое время провалялась она без дела, пока не отдали мне старый МФУ Canon MX320 без поддержки сети. Мне очень не хотелось иметь лишний провод от ноутбука к принтеру, и в результате апельсинка была извлечена, настроена и работает с тех пор в качестве CUPS сервера по USB (результат, кстати, хороший, но это уже совсем другая история).

Завязка


Однажды надоело мне вечно подключать через minijack мой телефон к колонкам. Стоят они хорошо, удобно, и переносить их неохота. А телефон, вечно висящий на линейнике- это уже не мобильный телефон, а что-то похожее на старые проводные аппараты. Ноутбук у меня тоже стоит так, что подключать к нему кабель к колонкам было бы неудобно. Да и сама машинка старая (10 лет уже), лишний аудиоплеер — лишняя нагрузка.

Можно, конечно же, купить bluetooth-колонки. Или bluetooth-адаптер. Но это значит малый радиус действия и проигрывание музыки только на том устройстве, с которым по bluetooth связан телефон. Надо что-то посерьезнее. «Здорово было бы повесить такой сервер на апельсинку, который мог бы принимать аудиопоток с смартфона по WiFi, — подумал я, — ведь она постоянно подсоединена по ethernet к роутеру, малонагружена (так как стоит на ней Ubuntu Server 16.04), разместить можно удобно, электричества потребляет мало.» Сказано — сделано.

Часть 0, аппаратная


Для начала нужно было гнездо для jack соединить с апельсинкой. Брал я голую плату, поэтому все нужно было спаять самому. Сложного ничего нет, и сразу скажу: нет особого смысла делать это — проще купить готовую плату расширения. Советую этот способ, потому что у меня на самодельной плате помехи влияют на звук колонок (в частности, при передаче на принтер большого задания на печать, или же при установке больших пакетов). Причин, скорее всего, две — моя плохая работа + питание заведено сразу на плату, а не через microUSB.

Потому фото платы, пайки и руководств не будет, если понадобятся — легко находятся в сети.
Если выберете покупку платы — сэкономите время и силы, при этом сразу будет и гнездо для миниджека, еще два USB-разъема, инфракрасный датчик и микрофон. Вторую апельсинку покупал уже в наборе с корпусом и платой расширения, пожалел, что так не сделал с самого начала.

Часть 1, программная


Подключаемся по SSH (если стандартный логин-пароль не меняли, то это root orangepi).

Не забываем сделать

apt update


(все равно позже понадобится)

По умолчанию звук выключен, поэтому чтобы его включить, делаем следующее:

Запускаем alsamixer.

alsamixer


image

Включаем audio line out (нужный выключатель находится по центру), для этого стрелками переходим на пять позиций вправо и нажимаем m

image

Выходим, нажав Esc.

Сохраняем текущее состояние

alsactl store


Текущее состояние все равно сбросится после перезагрузки, потому добавляем строчки

alsactl restore


в rc.local, чтобы параметры восстанавливались автоматически:

cd /etc


nano rc.local


#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# ** Overclock to 1.728 GHz
#echo 1728000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq

echo 0 > /proc/sys/kernel/hung_task_timeout_secs

dmesg -n 1

alsactl restore

exit 0


Советую после этого проверить — выполняем сперва перезагрузку

reboot


Устанавливаем mplayer

apt install mplayer


и проверяем работоспособность

mplayer http://nashe1.hostingradio.ru/nashe-128.mp3


Если радио заиграло, значит — все в порядке.

Можно, правда, просто запустить после перезагрузки

speaker-test


, но мне больше нравится остальную настройку проводить под радио.

Часть 2. mpd


После того, как вывод звука настроен, можно приступать к установке чего-то полезного. А в моем случае, это был как раз mpd и mpc (клиент для mpc — работает в терминале). Что такое mpd? Это сетевой плеер-демон, который работает прекрасно без графического интерфейса и потому не нагружает систему. Возможностей настроек — уйма, на любой вкус. Спокойно проигрывает музыку из сети и из локальной коллекции. Есть даже статья о взаимодействии mpd с Яндекс.Музыкой и с Google Music.

Управляться может с любой ОС — клиенты есть под Windows, Linux, Android, ios, mac os, Symbian, потому очень удобен.

Устанавливаем

apt install mpd mpc


Все настройки находятся в файле /etc/mpd.conf

nano /etc/mpd.conf


Обязательно меняем следующую директиву

bind_to_address         "localhost"


на

bind_to_address         "any"


потому что именно она обеспечивает возможность управления mpd по сети.

И переходим в секцию Audio Output

Настраиваем вывод через alsa

audio_output {
        type            "alsa"
        name            "My ALSA Device"
        normalize "yes"
        device          "hw:0,0"        # optional
        mixer_type      "software"      # optional
#       mixer_device    "default"       # optional
#       mixer_control   "PCM"           # optional
#       mixer_index     "0"             # optional
}


Если не добавить директиву normalize «yes», то звук будет очень тихим. К сожалению, подробнее об этой директиве написать ничего не могу, не было времени искать информацию.

Директиву

device          "hw:0,0"        # optional


я добавил совсем недавно, без нее mpd работает прекрасно (если работает в одиночку), и потребовалась она только потому, что я ставил дополнительные компоненты, о которых ниже.

Перезапускаем mpd

service mpd restart


Все, можем подключаться.

Идем в любой клиент, вводим IP нашего сервера, соединяемся. Сперва, конечно же, и в плейлистах, и в файлах, и в потоках пусто. Чтобы mpd увидел ваши локальные файлы, нужно либо поменять настройки в /etc/mpd.conf, указав в секции

Files and directories

путь к вашей папке с музыкой

music_directory »/home/orangepi/Music

# Files and directories #######################################################
#
# This setting controls the top directory which MPD will search to discover the
# available audio files and add them to the daemon's online database. This
# setting defaults to the XDG directory, otherwise the music directory will be
# be disabled and audio files will only be accepted over ipc socket (using
# file:// protocol) or streaming files over an accepted protocol.
#
music_directory         "/var/lib/mpd/music"
music_directory        "/home/orangepi/Music"


Но у меня все равно локальных файлов нет, а используется жесткий диск ноутбука, подмонтированный по Samba прямо в папку /var/lib/mpd/music. В планах покупка внешнего жесткого и подключение его к апельсинке, но пока финансы не позволяют.

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

mpc update


Ждем некоторое время (больше коллекция — больше времени надо для ее сканирования).

Все, можем наслаждаться музыкой!

Меня mpd будит по утрам вместо будильника. Очень хорошо и приятно просыпаться под разную музыку/станции в разное время и дни.

Часть 3. Собственно, WiFi колонка


Итак, mpd это, конечно, хорошо, но желаемую задачу он не выполняет — нет трансляции звука с телефона при проигрывании музыки на нем. Несколько бессонных ночей — и была найдена статья о превращении *Pi в приемник аудиопотока.

Вкратце:

то, что мне нужно — очень похоже на Chromecast от Google, ведь он поддерживает передачу звука по Wi-Fi и эта передача есть во многих приложениях.

Но у меня все-таки не Chromecast, а апельсинка. Если я правильно понимаю, пока что протокол Chromecast закрыт. Но это измененный протокол DLNA, который как раз служит для передачи медиаконтента по сети.
Ага!

Сразу же находится в репозиториях пакет minidlna.

Ставим

apt install minidlna


Так, теперь есть dlna-сервер на апельсинке. Ставим dlna-плеер к себе на телефон.
Облом.

Сервер есть, видится, есть доступ к коллекции и проигрывание контента, но на телефоне. А транслировать аудиопоток пока нельзя.

Разбираемся с протоколом: оказывается, есть DLNA сервер, DLNA контроллер (для управления воспроизведением) и (!) DLNA рендерер.

Последний как раз нам и нужен.

В репозиториях его нет, потому ставим так

 wget -O - http://www.chiark.greenend.org.uk/~christi/debian/christi@coraline.org.gpg.key \
| sudo apt-key add -

echo deb http://www.chiark.greenend.org.uk/~christi/debian/ wheezy main

  > /etc/apt/sources.list.d/upnprender.list

apt-get update
apt-get install libupnp-dev libgstreamer1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-alsa

apt install git

cd
git clone https://github.com/hzeller/gmrender-resurrect.git
cd gmrender-resurrect
apt-get install autoconf
 ./autogen.sh
 ./configure
make install

cp scripts/init.d/gmediarenderer /etc/init.d

update-rc.d

update-rc.d gmediarenderer defaults


У автора gmediarenderer запускается при старте системы через init, у меня этот способ пока не работает, потому добавлена строчка в /etc/rc.local

/usr/local/bin/gmediarender -f Garden -d -u  bd1dcf3e746aa69812943cb1d00f7ebc --gstout-audiosink=alsasink --gstout-audiodevice=sysdefault --gstout-i$


#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# ** Overclock to 1.728 GHz
#echo 1728000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq

echo 0 > /proc/sys/kernel/hung_task_timeout_secs

dmesg -n 1

bash /root/sh/script0.sh

/usr/local/bin/gmediarender -f Garden -d -u  bd1dcf3e746aa69812943cb1d00f7ebc --gstout-audiosink=alsasink --gstout-audiodevice=sysdefault --gstout-i$

exit 0


Для того, чтобы можно было теперь слушать аудиопоток с смартфона на OrangePi, ставим BubbleUPnP, или же HiFi Cast, поиск в Google Play выдает много результатов по запросу DLNA. Далеко не все можно отрендерить. Ни ВК ни Яндекс.Музыка/Радио не рендерятся. Но это все равно больше, чем ничего. На текущий момент воспроизводится любая локальная музыка с телефона + SoundCloud.

К сожалению, после установки gmediarender перестал нормально работать mpd — воспроизведение есть, а звука нет. Поиск ничего не дал, решение найдено случайно — нужно в файле /etc/mpd.conf раскомментировать строку, которая находится в секции Audio Output, в блоке, описывающем вывод через alsa:

device          "hw:0,0"        # optional


После раскомментирования этой строчки звук вернулся, mpd заработал в штатном режиме.

Итоги


В целом задачу можно считать выполненной.

На текущий момент можно слушать любую музыку с планшета/телефона через WiFi на колонках, можно включать сетевой плеер, проигрывать музыку с апельсинки на телефоне/планшете.

В планах — допилить dlna-рендерер, настроить парсер для mpd (чтобы сам искал мне музыку в сети), добавить жесткий диск (скорость по Samba все-таки низкая).

Получилось достаточно удобно, функционально и просто, да и дешево (на все вместе 1900 рублей, сам OrangePi и карта microSD). Если брать комплект (OrangePi, корпус, плата и microSD), можно уложиться в ту же сумму, если постараться.

На этом все, буду рад отзывам и комментариям.

© Habrahabr.ru