Как собрать радио для коллег без единого разрыва

Привет, Хабр! Вот уже почти 5 из 10 лет я совмещаю работу сетевиком с любимым хобби — подкастом про ИТ. За это время наш сервер для аудиотрансляций развивался, менялся и оказался полезен не только нам, но и коллегам. Недавно я правильно клонировал нашу сборку на базе Linux для радио ЦОД.fm в DataLine и решил поделиться своими наработками со всем сообществом.

Сегодня покажу, из чего я собирал новогоднее радио для создания праздничного настроения перед онлайн-корпоративом.

Для начала определимся с задачами

Чтобы радио радовало коллег качеством звука, стоит учесть несколько компонентов для разных задач:  

  • сам сервер трансляции, с которого будем раздавать аудиопоток;

  • интерфейс для ведущих и гостей: распределенное вещание сегодня новая норма, участники шоу должны подключаться из разных мест без лагов и бубна;

  • инструменты для обработки звука: выравнивания громкости из разных источников, удаления шумов и наложения фоновой музыки на финальный трек;

  • служебный канал для бесшумной синхронизации действий во время эфира;

  • клиентская часть для подключения слушателей с любого устройства;

  • опционально можно добавить доп. фичи для общения со слушателями (чат в Телеграмме).

Кроме того, если вы такой же энтузиаст и собираете радио как pet-project в свободное время, скорее всего, ваш бюджет ограничен. Так что я не буду останавливаться на дорогих проприетарных продуктах для этих задач, а покажу решения на свободно распространяемом и условно-бесплатном ПО.

Сервер трансляции с TeamSpeak«oм и постобработкой

Свой сервер я собирал на базе Xubuntu 20.04 с lowlatency-ядром. Расскажу, какие компоненты на нем установлены, а потом покажу, как выставляю для них приоритеты.

OBS для обработки на лету. Под капотом сервера у меня Open Broadcaster Software (OBS). С помощью этого софта можно моментально обрабатывать аудио: поднимать громкость до нужного уровня, добавить компрессию, убрать пики, добавить джинглы и фоновую музыку:

Во время эфира я запускаю джинглы, музыку и голос на микшере в OBS.Во время эфира я запускаю джинглы, музыку и голос на микшере в OBS.

У OBS есть фильтры, которые можно навесить на каждую аудиодорожку перед ее отправкой в эфир. У меня настроены 5 фильтров в таком порядке:  

  1. Limiter срезает все пиковые частоты звука, предотвращает клиппинг и перегрузки.

    1bpge3cvrjnvht8xmcfv-ijqiuy.png
  2. Noise Suppression удаляет с дорожки фоновый шум, так как шипящие дорожки нам ни к чему.

    zaigslj60qyhujhukuoszgeadro.png
  3. Усилитель Gain повышает громкость звука до заданного значения.

    n7qemsikd2hrdjqfih3xrastplu.png
  4. Compressor сглаживает перепады громкости звука, например, если кто-то начинает очень бурную дискуссию или, наоборот, начинает шептать на ушко.

    dh2ahmahav9bmaex2tr6q94aiws.png
  5. В конце еще раз использую Limiter, чтобы убрать возможные пики от фильтра Compressor.

    wj7x4ehvk_x1slgz3z_eikfzh1e.png

С помощью OBS мы запускаем и тестовые трансляции: стримим все по локальной ссылке, проверяем настройки, —, а потом настроенный стрим отправляется по боевому урлу. 

Tigervnc-standalone-server для управления сервером. Мы подключаемся к серверу любым SSH-клиентом, не забывая про туннелирование порта 5901. Получаем стандартную связку SSH +VNC. Кто не хочет туннелировать SSH, может воспользоваться любым VPN на свой выбор: его можно терминировать непосредственно с сервера или с роутера.

Virtual Audio Cable (и никакой магии), чтобы забирать звук с клиента TeamSpeak в OBS.

Icecast в связке с nginx и OBS для раздачи. OBS позволяет одновременно стримить радио в несколько мест, например, наш подкаст параллельно идет на Youtube. 

Для раздачи по протоколу https на сервере установлен Icecast: он принимает потоки голосовых данных от OBS и раздает потоки исходящего трафика на слушателей. 

TeamSpeak для синхронизации действий и записи. В нашем подкасте мы используем TeamSpeak для боевого канала и записи эфира. На сервере установлен TeamSpeak Server и TeamSpeak Client. Ведущие подключаются к TeamSpeak Server с помощью своих клиентов. К серверу через локального клиента  подключен podbot — некая немая сущность, которая всегда живет в канале и только слушает. Она нужна, чтобы на сервер приходил стрим от всех остальных, который можно перенаправить в Virtual Audio Cable.

Так выглядит рабочее окружение для ведущего. Справа боевой канал в TeamSpeak, который потом уходит в OBS (слева):

46fe0ea643deb16673c5a17948d6cc21.png

На тестовой трансляции мы используем TeamSpeak как микшер, чтобы выровнять всех гостей:

ed692ce6d3594e7f64b7b7f02674c5c3.png

Во время боевой трансляции звук в служебном канале уже настроенный и ровный, можно записать стрим и потом выложить запись с минимальным редактированием:

Записываем дорожки всех участников. Полезно, когда через TeamSpeak идет продовая трансляция, как это сделано у меня в linkmeup.Записываем дорожки всех участников. Полезно, когда через TeamSpeak идет продовая трансляция, как это сделано у меня в linkmeup.

Чтобы бесшумно синхронизироваться друг с другом по организационным моментам, мы используем чат в TeamSpeak. Создали систему специальных сигналов, наподобие этого:

b2ada35c98012cb0af61c75021360668.png

Также пробовали для этого Zoom, где можно видеть друг друга и обмениваться жестами. 

Для ЦОД.fm я организовал на базе TeamSpeak служебный аудиоканал, где все слышат комментарии друг друга, но не выводят их в эфир. Получилась такая виртуальная студия, в которой редактор эфира решал технические и организационные вопросы с ведущими.

Настройка nice-приоритетов на сервере. Я отдаю высший приоритет системным вызовам, затем обрабатываю звук, все остальное потом.

Видим правильные nice-приоритеты — уже половина успеха:

f498559e8b0967604b83d952052dae3f.png

Настраиваем правильные лимиты, чтобы не получить лаги в эфире:

sudo vi /etc/security/limits.conf
@audio           -       rtprio          99
@audio           -       memlock         unlimited
@audio           -       nice            -19
sudo usermod -a -G audio user
ceb20f792c2252f465875d237e4db7a6.png

Отсыплем демону, отвечающему за звук, нужных значений приоритетов:

sudo vi /etc/pulse/daemon.conf
high-priority = yes
nice-level = -11
realtime-priority = 9
d28c8bdd676230ae505c731de4b9a8af.png

Создадим виртуальные аудиокабели:

sudo vi /etc/pulse/default.pa
load-module module-jack-sink sink_name=vlink1 sink_properties=device.description=vlink1
load-module module-jack-sink sink_name=vlink2 sink_properties=device.description=vlink2
load-module module-jack-sink sink_name=vlink3 sink_properties=device.description=vlink3
29c6fc1857f7c1d7f2ea7991293b8c8d.png

Важные мелочи для пользователей

Для радио ЦОД.fm я завел отдельное доменное имя, настроил nginx, разобрался с шифрованием трафика и сертификатами. Даже любительскую радиостанцию лучше стримить по защищенному соединению, да и слушатели не будут ругаться на отсутствующий https. Позаботился о проксировании, чтобы сотрудник мог открывать стрим с любого удобного устройства с любым плеером. Но, если что, можно организовать стрим с этими инструментами и в локальной сети. 

Для внешнего домена, само собой, стоит настроить фаервол и защиту от DDoS. На каждый глобальный IP-адрес я ограничивал количество TCP-соединений до 10. Перед запуском всей системы провел нагрузочное тестирование.

Для наших партнеров и ведущих подготовил инструкцию по запуску сервера и клиентской части: как включать фоновую музыку на OBS и выводить участника в эфир:

Еще можно создать чат радиостанции в вашем любимом мессенджере и принимать там сообщения в эфир, приветы, заявки на музыку и т. д. Тут уже кто как любит. 

Будем использовать этот сервер для онлайн-трансляций дружественных подкастов «Поддатой», «Разговоры из-под фальшпола» и «Немного об оружии». Через некоторое время планирую выложить нашу сборку и все подробности по настройке на github для других таких же энтузиастов. Улучшим сервер аудиотрансляций вместе, буду ждать ваших PR =) 

Кому нужно прямо сейчас, например, в формате OVA\OVF, пишите в личку или в телегу NAT_GTX.

© Habrahabr.ru