Распределенный музыкальный плейер на Raspberry Pi


    Давно собирался написать этот пост, но прогресс шел медленно. К ускорению темпа подтолкнул этот вопрос, где я имел неосторожность обмолвиться, что пишу такой пост, в результате чего он вызвал живой интерес, поэтому мне ничего не оставалось делать, как выполнять данное обещание, за что выражаю отдельную благодарность автору вопроса M03G, с чьей подачи и был получен мной этот ускоряющий пендель. А так как пост, похоже, увидит свет в пятницу, я позволил себе довольно вольный (извините, вышел каламбур невольный) стиль изложения. Надеюсь, все останутся довольны.

    (Да, пост во многом пересекается с постом Распределенный аудиоплеер на Odroid U2, но чуть проще в настройке)


    Пролог


    Я начал мечтать о подобной системе году в 2003-м, как только начал жить в квартире с количеством комнат >1, и вопрос музыки на кухне (да и вообще по всей квартире) встал во весь рост. Ситуация усугублялась тем, что квартира была построена согласно архитектурному гению Никиты Сергеевича Хрущева, а компьютер помещался в “дальней” комнате, так что на кухне слышно было чуть более, чем совсем никак.



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

    image


    Предыстория


    К тому моменту, как в широком доступе оказались замечательные одноплатные компьютеры Raspberry Pi, я сменил 3 места проживания, такое же количество работ, а также страну проживания, поэтому из-за обилия происходящего мечта не подала голоса даже слабого голоса, давно уснув летаргическим сном в пыльном чулане на задворках памяти. Малинку я, однако, все равно заказал. Зачем – еще сам не понимал, но устоять не смог: соотношение цена/потенциальные возможности все решило. “Это же в перспективе и NAS, и веб-сервер для экспериментов, и куча всего остального”, — думал я (ну, на NAS, как выясняется, она не тянет, но даже если бы я это тогда знал, меня бы все равно это не остановило).



    Однако после того, как “малинка” таки попала ко мне в руки, у меня как раз организовался завал и на работе, и с личными проектами, поэтому “ягодка” легла на полку и пролежала несколько месяцев, так и не вкусив электричества.

    image


    Но однажды все изменилось.

    Завязка


    Теплым летним вечером делать было нечего, чего со мной не случалось уже несколько лет, и я решил не упускать такую возможность и хоть немного разобрать хлам в шкафу. Там я и наткнулся на черную коробочку, грустно смотревшую на меня прорезями пустых слотов.
    “Оба на, да у меня же вот чего есть!”
    — подумал я и тут же полез в интернет за образом системы для нее. Так случилось, что на стол она легла таким образом, что прямо в левый глаз мне уставился аудиовыход, задавая немой вопрос
    “Ну что, будем что-нибудь делать или как?”
    План созрел быстро: в usb-порт втыкаем внешний винт с музыкой, к аудиовыходу подключаем колонки, на малину ставим MPD и получаем отличный музыкальный плейер, доступный для контроля с любого компьютера в доме (благо клиентов полно под любую ОС). Итак, малинке наконец-то нашлось применение, она весело замигала разноцветными светодиодами, и это было хорошо.

    Хорошо, но мало.
    “Хе, есть же такая замечательная вещь, как Icecast2, который превосходно ладит с MPD и стримит музыку в сеть!”
    — пронеслось у меня в голове. И тогда можно будет слушать на любом устройстве любым плейером, умеющим хватать аудиопоток из сети. Мысль эти грянула настолько громко (я бы даже сказал оглушительно), что грозные раскаты докатились до забытого пыльного чулана и разбудили безнадежно уснувшую мечту, которая тут же принялась долбить жестяной кружкой в стену:
    “А кто тебе мешает взять еще пару-тройку малинок, написать простейшую софтину, которая по команде из сети включает/выключает тот же mplayer на проигрывание заданного URL (того самого, куда вещает Icecast2 с первой малины), и выпустить уже меня отсюда в конце концов??”
    Но тут меня (и ее) поджидал первый облом (как оказалось впоследствии – к лучшему): мощности малины не хватало на то, чтобы на лету пережимать поток и стримить его – звук заикался. Я полез искать, можно ли “уговорить” Icecast2 не пережимать, а напрямую стримить то, что ему скармливают. И пока курил конфиг MPD, наткнулся на знакомое слово “pulseaudio”.
    “Так, стоп, да это же вроде та самая хреновина, которая потенциально умеет воспроизводить по сети? А может мне и не нужно городить огород с Icecast2 и самописной включалкой/выключалкой?”
    Так и вышло… А шкаф так и остался неразобранным.

    Поехали!



    image


    Итак, поехали. Исходный материал: две или больше Raspberry Pi (одна будет сервером, на котором крутится MPD, остальные клиентами), такое же количество колонок для воспроизведения звука, чуть-чуть знания Linux, и вечер свободного времени. Ну и, разумеется, музыкальная коллекция с правильно прописанными тегами, т.к. MPD оперирует именно ими. Все это у меня в наличии было, поэтому я заранее известил жену о том, что ближайшим вечером меня нет, я заболел, изчез из дома, уехал в Ванкувер, и вообще эмигрировал нафиг с этой планеты, и что вернусь завтра к обеду, и с головой погрузился в гугл. Гугл не подвел.

    Подготовительный этап (одинаковый для сервера и клиентов)


    Я не буду детально описывать процесс установки системы на Raspberry Pi, инструкций в интернете полно. Оговорюсь лишь, что я, как любитель Debian с 8-летним стажем, использовал Raspbian, поэтому все инструкции будут даны для него. В общем, качаем образ, прошиваем, втыкаем карту, грузимся. Первоначальная настройка тоже стандартна, перечислю то, что сделал я:

    • задал пароль (разумеется)
    • активировал ssh-сервер
    • задал таймзону
    • убрал загрузку иксов
    • выставил объем видеопамяти на минимум (16 мегабайт), ибо незачем ее зря расходовать за неимением иксов.

    Если вы не очень уверенно чувствуете себя в консоли, то можете два последних пункта пропустить, и настраивать прямо из “малинового” гуя, я же все делал залогинившись по ssh.

    Обязательный пункт: назначьте каждой “малинке” статический адрес в настройках вашего роутера (или в ее собственных сетевых настройках, без разницы) – впоследствии очень пригодится.

    Ну что ж, приступим:

    1. Первым делом обновим систему до свежего состояния и установим PulseAudio. Вообще, мы сейчас много чего будем делать от рута, поэтому перейдите под его учетку любимым вами способом (выбирайте на свой вкус):

    $ sudo -i
    # aptitude update && aptitude upgrade && aptitude install pulseaudio


    2. Т.к. предполагается, что работать все будет сразу же после загрузки, в идеале – без иксов и логина юзера, нам нужно, чтобы PulseAudio работал в общесистемном режиме. Для этого отредактируем файл /etc/default/pulseaudio следующим образом:

    ...
    PULSEAUDIO_SYSTEM_START=1
    ...


    3. Далее, чтобы все работало, нужно добавить юзера pi в группу pulse-access:

    # usermod -a -G pulse-access pi


    4. Теперь разрешим прием звука по сети. Для этого в файл /etc/pulse/system.pa добавим строку

    ...
    load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.1.0/24
    ...

    Здесь мы авторизуем как “самого себя”, так и все устройства из локальной сети с адресами 192.168.1.* (если у вас диапазон адресов другой, поправьте соответствующим образом). В принципе, первая часть нужна только для сервера (чтобы играть на самом себе), а вторая — для клиентов (чтобы принимать из сети), но мы сделаем и то, и другое, чтобы в случае чего малинки были взаимозаменяемы с минимальными телодвижениями.

    4. Собственно, запускаем сервис pulseaudio

    # service pulseaudio start


    На этом общая часть заканчивается. Перейдем к настройкам клиентов и сервера.

    Клиент


    Возможно, кому-то это покажется странным, но “клиент уже готов”, и дополнительной настройки не требуется, поэтому далее двигаемся строго на сервер порядка 50 метров займемся сервером.

    Сервер


    В первую очередь на сервер нужно установить MPD, и заодно консольный клиент (для первоначальной настройки):

    # aptitude install mpd mpc


    Теперь редактируем конфиг /etc/mpd.conf. Он, как и многие другие конфиги в линуксе, отлично прокомментирован, поэтому я обозначу лишь основные необходимые правки:

    Указываем путь к коллекции
    music_directory         "/mnt/disk1/music/mp3/sorted"


    Биндим на любой сетевой интерфейс:
    bind_to_address         "any"


    На стандартный порт:
    port                            "6600"


    Авто-апдейтить коллекцию при изменении файлов:
    auto_update    "yes"


    И самое главное – конфигурируем аудиовыходы. Здесь мы создаем по одному выходу на каждую из клиентских “малин”, плюс один для самого сервера – он тоже будет выступать в роли равноправного клиента. Вот тут-то и пригодятся нам статические IP-адреса, которые мы назначили каждой из малин.

    audio_output {
            type            "pulse"
            name            "Office"
            server          "localhost" # server
    }
    
    audio_output {
            type            "pulse"
            name            "Living Room"
            server          "192.168.1.4" # client #1
    }

    (и так далее, по количеству имеющихся клиентов)

    Ну что ж, перезапустим MPD. Рутовую сессию на этом можно закончить.

    # service mpd restart
    # exit


    Просканируем коллекцию для создании базы данных (это займет некоторое время, в зависимости от размера коллекции):
    $ mpc -w update


    Собственно, на этом — все.

    Рулим!


    Осталось всего ничего: как всем этим делом управлять. Тут ничего сложного, в нашем распоряжении вагон и маленькая тележка клиентов под всевозможные ОС. При выборе обязательно обращайте внимание на то, умеет ли клиент переключать выходные каналы (или, как они еще называются, Output Devices) – собственно, это именно та фича, которая позволяет включать/выключать того или иного клиента. Под Маком я остановился на Theremin, под Линуксом – на Gmpc, клиентами под Windows пользоваться не приходилось, поэтому ничего посоветовать не могу.

    image


    Кульминация


    Легкими и плавными движениями пальцев, нежно касаясь тачпада, я запустил Theremin, добавил первый попавшийся трек в плейлист и нажал Play. Через секунду из колонок в зале донеслись нежные переливы старой доброй композиции “Master of Puppets” вокально-инструментального ансамбля “Metallica”. Ребенок, сидящий внутри меня, возликовал —
    “Ура!!! Вот то, о чем я мечтал 10 лет!!!”
    Дополнительные градусы душевного тепла генерировались от осознания факта, что никакой «rocket science» задействовано не было, и все было собрано буквально за вечер из «подручных материалов», и даже без единого куска синей изоленты. Я прислушался — из офиса наверху тоже доносился звук! Я залез в меню и снял галку с «Living Room» — звук из колонок в зале пропал, и остался только в офисе.



    Победа!

    image


    Эпилог


    Уже через несколько минут внутренний перфекционист потребовал унификации интерфейса между девайсами и ОСями, и поэтому в голове тут же мелькнула безумная мысль “А вот хочу веб-интерфейс, да чтобы со всеми необходимыми функциями!” Беглый осмотр интернета оставил печальное ощущение: “Этот вроде ничего, но куцый. Этот вроде фичастый, но ставится через опу. Этот вообще заброшен.” Ну и так далее. Не говоря уже о том, что все они обладали одним фатальным недостатком. В общем, самые догадливые читатели уже все поняли: я решил написать свой, “с нотными партиями и пианистками”. Тем более, что веб-разработкой я никогда толком не занимался, но всегда хотелось попробовать страшного зверя jQuery, да и вообще оценить, насколько далеко ушли веб-технологии с тех пор, как я последний раз написал и забросил свой “хомяк” на narod.ru, с джаваскриптами и крутящимися менюшками. Поэтому за три будних вечера и один выходной день на свет родилось вот такое чудо:

    image

    (скриншот снят с экрана BlackBerry PlayBook)

    Но об этом – в следующий раз.

    UPD: ссылка на веб-интерфейс: github.com/Mezomish/WebMPC
    Share post

    Comments 52

      +2
      Блин, как все просто. А я по своему дремучему незнанию все складываю в закладки статьи про Одроиды…
      Пошел заказывать вторую малинку :)
      Спасибо!
        +1
        На Одроиде должно делаться полностью аналогично. Да и вообще на любом Linux-девайсе. Я ради теста одним из клиентов сделал ноут жены :)

        «Но есть нет разницы — зачем платить больше?»
          0
          И я о том же, к тому же одна малинка у мя уже есть
          –1
          Повешу повыше. На Амазоне теперь можно купить за $70.96 (включая доставку) Raspberry Pi Model B Revision 2.0 (512MB) с прозрачным корпусом
          habrahabr.ru/post/196484/
            +1
            Зачем так дорого? На РСКомпонентс — 31 у.е. малинка и 6-8 у.е. корпус, и это с учетом доставки. Мне оттуда в Украину камера за 6 дней пришла.
              –1
              Для меня это «как рога и копыта» фирма звучит. Кому гарантию предъявлять? Пересылать обратно тоже за свой счет?
                0
                Стесняюсь спросить, а на Амазон за чей счет Вы отсылать в случае чего будете? Та же официальная гарантия, никаких проблем не вижу. Серьезная международная компания, между прочим.
                  0
                  За счет Амазона естественно. Тем же самым UPSом. Доставка за 3-4 дня. Возврата ждать не нужно деньги сразу вернут на счет после отправки посылки. Сомневаюсь, что кто то еще на это же способен.

                  31 у.е. малинка
                  модель какая?
                  У производителя модель В стоит 35 баксов.
                    0
                    31 у.е. — это модель А. Модель В — 41 у.е.
                    За оплату обратной доставки в Амазоне — каюсь, не знал.
          +1
          Прошу прощения за глупый, но логичный вопрос.
          А насколько реально сделать несколько независимых потоков? Чтобы в одной комнате играло одно, а в другой комнате другое.
            +1
            Чисто теоретически ничто не противоречит тому, чтобы поднять и второй сервер с теми же самыми клиентами, и перетасовывать их по мере необходимости. Ну и 2 разных гуй-клиента понадобятся, цепляющихся каждый к своему mpd.
              +1
              Отдельные gui не надо. Все виденные мной gui имели удобную переключалку между серверами в пару кликов.
                0
                Должно получиться и с одного сервера несколько потоков вещать. PulseAudio так умеет.
                  +1
                  Пульсаудио-то умеет, а mpd? Я этот вопрос не изучал.
                0
                Я думаю подключение, добавлением строк:
                audio_output {
                type «pulse»
                name «Bathroom»
                server «192.168.1.5» # client #1
                }

                А гуй немного поправить и можно сделать прямо выбор с какой комнаты играть
                +10
                Понравились ваши иллюстрации!
                Приподнимает с утра настроение :)
                  +3
                  Спасибо. Не знаю, что на меня нашло, особых художественных талантов за мной никогда не числилось, а тут вдруг что-то ударило в голову :)
                  0
                  А как с переходом между комнатами, задержками звука и наложениям звуков из разных комнат друг на друга? В первую очередь интересует чисто субъективное впечатление.

                  Второй вопрос следует из первого — можно ли настроить чтобы малинка в дальней комнате воспроизводила звук с задержкой N миллисекунд например?
                    +1
                    А мне кажется, что задержка не нужна, потому как это сделано чтобы слушать в конкретной комнате в данный момент, и слышать мы будем только одну комнату.

                    Задержка нужна будет тогда, когда мы из одной точки захотим слушать сразу все комнаты.
                      0
                      Задержку можно устроить средствами pulse audio, но это не важно т.к. синхронизации потоков все равно нет. Они будут воспроизводиться с разными скоростями и будет наблюдаться эхо.
                        0
                        Ответил чуть ниже: habrahabr.ru/post/195458/#comment_6782746
                        +2
                        Есть одна проблема. Этот способ не обеспечивает синхронное воспроизведение. mpd не умеет оценивать задержку воспроизведения звука через разные выходы.
                        Поэтому в статье про odroid я так извращался с pulseaudio и фейковыми выходами в mpd.
                          0
                          Для синхронизации потоков подойдет как раз-таки пресловутый AirPlay(к которому, афаик, есть И клиенты, И серверы под ЛЮБУЮ ось).
                          Либо, опять же, мультикаст. Правда по вайфаю это с большой долей вероятности плохо заработает. Но синхронизация тоже будет близка к идеальной.
                          Так же можно посмотреть в сторону gstreamer, он тоже умеет вещать в сеть и синхронизироваться по своему протоколу через отдельный udp-порт.
                            +1
                            Синхронность, конечно, хромает. Причем если сразу после включения еще куда ни шло, но при включении/выключении каналов во время проигрывания лаг становится очень заметным.

                            Но у меня комнаты очень сильно разнесены (по этажам), и если в офисе слушать с умеренной громкостью, то снизу вообще не слышно, играет там музыка или нет, поэтому вопрос синхронизации у меня на повестке дня даже не стоял.
                            0
                            А почему нельзя сделать стриминг с ноута. Насколько я помню, в цшт7 есть такая функция, когда воспроизведение вещается.
                            Тогда вообще просто — с ноута открываешь любое медиа, и оно вещается или не вещается на колонки. Необходимсть в отдельном сервере отпадает, да и не удобно — он нужен всегда быть включенным, и жестки диск, и коллекцию пополнять.
                            А с ноута можно включить например онлайн радио
                              +1
                              Наиболее частый сценарий: прихожу домой и включаю музыку. В случае стриминга с ноута мне нужно разбудить ноут и включить на нем музыку. А ноут иногда наверху, поэтому предварительно нужно подняться туда.
                              В моем случае достаточно планшета с веб-гуем, и музыка включается в 2-3 тапа.
                              –1
                              Рискую нарваться на минусы, но FM-трансмиттер же! У китайцев есть модели ~0.1 Вт, дальность метров 50-100 уверенного приема, квартиру покроет, затраты минимальны, синхронизация полная…
                                +7
                                И качество звука — тоже полная…
                                  0
                                  Я как-то еще задолго до появления данной статьи делал аналогичное на Raspberry Pi — тогда качество звука через встроенный аналоговый аудиовыход мне показалось полной… и я решил, что если RPi и годится для вывода звука, то только через HDMI. Возможно, у Odroid дела с этим лучше — у меня он тоже есть, надо попробовать
                                    0
                                    В odroid я воткнул внешнюю usb звуковую карту.
                                0
                                А как качество звука внутреннего DSP у RasoberryPI? А то для аудиофилов есть целый дистрибутив www.raspyfi.com/project/
                                  0
                                  аудиофилам никто не мешает взять какойто адский USB ЦАП :)
                                    +2
                                    Думаю, аудиофилам вся эта система изначально — как серпом по бубенцам. Начиная от воспроизведения mp3 (ну хорошо, mpd может и flac жевать) и заканчивая передачей по богопротивному Ethernet, в котором электроны закручиваются, и звук от этого портится :)
                                    0
                                    Мне больше нравится AirPlay + shairport. рекомендую.
                                      0
                                      Через wifi, к сожалению, очень плохо работает, хотя возможно, это проблема слабого wifi-свистка на малинке.
                                        0
                                        Я тоже пока использую этот вариант, но тут есть несколько моментов. В Foobar, itunes, Tuneblade лаг между локальным звуком и на колонках около 1-2 секунд, поэтому фильмы не посмотришь.
                                        0
                                        Почему плейер, а не плеер?
                                          0
                                          Свою мечту вы могли воплотить еще много лет назад, если бы воспользовались apple airport express :)
                                          Ой, это автору поста было…
                                          0
                                          И ведь реально лет 10 назад я пытался делать такое с помощью сервера на SuSe 9.1 и кпк на WinMobile :)
                                            0
                                            Мда… Моя схема с Audio разветвителями и удлинителем на кухню и рядом не стояла. Хотя в моем случае задержек нет)
                                              0
                                              делал такую же радость пару месяцев назад, только выяснилось, что при стриминге с ноута через wifi звук заикался и прерывался через 10..30 секунд
                                              пульса начинает валить ошибки
                                              в итоге после недели экспериментов я решил, что проще поставить mplayer и через андроид управлять им
                                                +1
                                                В качестве альтернативы малины присмотритесь к китаистикой аднроид тв приставке MK808 или MK809. После перепрошившки ее на линуксы уже около полугода использую MK808 в качестве домашнего сервера, файловой помойки, сидбокса и ДЛНА сервера. Скажу что скорости хватает для всего, вполне конформно смотрю рипы 1080p,10-18 gb по длна на телевизоре при этом может не мешаю работать торрент качая и раздавая на больших скоростях. Зверек довольно мощный и не голодный, работает от блока питания 1Ax5V и при этом имеет 2 ядерный проц 1.2 гхз и 1 гб рам. Цена сравнима с малиной около 40$ при этом есть встроенный вифи что в таких задачах как у вас будет очень кстати. Сейчас уже есть более мощный вариант MK809 с 4 ядерным процессором 1.8 GHZ и 2 гбайт рам.
                                                  +1
                                                  Это что-то вроде такого, что ли? Есть такое, тоже без дела валяется :)
                                                  Я и не знал, что туда можно обычный линукс прошить.

                                                    +1
                                                    Да именно он, можно прошить как Ubuntu 12.10 и сейчас насколько помню уже портирован 13.04, удалось завести графику (4 ядерный mali 400) так и вифи модуль. Также ели добавить радиатор можно спокойно разогнать цпу до 1.6 гхз. Советую вам поэкспериментировать этот вариант намного мощнее малины.У меня докуплен usb ethernet адаптер(http://www.tinydeal.com/usb-20-to-ethernet-rj45-network-adapter-dongle-p-22974.html) и 2 тб usb жесткий диск, сам сервер прилеплен двухсторонним скотчам сзади стола ближе к роутеру. В таком виде он абсолютно не греется а слышен разве что только жесткий диск.
                                                  0
                                                  а можно ли запустить несколько mpd сервисов на одном хосте?
                                                    +2
                                                    Думаю, проблем не будет, нужно лишь скормить второму другой конфиг файл (в котором, разумеется, прописан другой порт). Из мана:
                                                    mpd(1) — Linux man page

                                                    Name

                                                    MPD — A daemon for playing music

                                                    Synopsis

                                                    mpd [options] [CONF_FILE]

                                                    Description

                                                    MPD is a daemon for playing music. Music is played through the configured audio output(s) (which are generally local, but can be remote). The daemon stores info about all available music, and this info can be easily searched and retrieved. Player control, info retrieval, and playlist management can all be managed remotely.
                                                    MPD searches for a config file in ~/.mpdconf then /etc/mpd.conf or uses CONF_FILE.
                                                    linux.die.net/man/1/mpd
                                                    0
                                                    Автору спасибо большое. Сегодня уже реализовал на убунту сервачке и pcduino. Теперь загорелся веб интерфейсом так как сам написать не в состоянии не поделитесь ссылками на те варианты что вы нашли и которые оказались удачными.
                                                      0
                                                      Наиболее удачным из всех мне показался вот этот: github.com/sn0opy/MPD-Webinterface, но и он далек от идеала, поэтому я и начал писать свой. Как будет что реально показать — выложу на гитхаб и дам ссылку тут.
                                                      0
                                                      огромное спасибо
                                                        +1
                                                        Ссылка на веб-интерфейс: github.com/Mezomish/WebMPC
                                                        Пока что очень базовый и далеко не полноценный по фичам (нет работы с коллекцией и плейлистом), работа в процессе.
                                                          0
                                                          А я вместо mpd+pulsaudio использовал Logitech Media Server на NAS'e (CentOS) + squeezelite на клиентах (raspberry pi и cubox). Управление всеми клиентами через веб-интерфейс, iPhone/Android приложения или плагин для XBMC, можно как свой плейлист каждому, так и один общий, с синхронным проигрыванием на всех или нескольких клиентах. На Cubox стоит дистрибутив GeexBox с XBMC для кино + squeezelite для музыки. На малине — piCorePlayer.
                                                            0
                                                            Не пробовали управлять каналами pulseaudio через командную строку на raspberry по принципу сделанному в статье про odroid u2?

                                                            Only users with full accounts can post comments. Log in, please.