Привет, Хабр! Вот уже почти 5 из 10 лет я совмещаю работу сетевиком с любимым хобби — подкастом про ИТ. За это время наш сервер для аудиотрансляций развивался, менялся и оказался полезен не только нам, но и коллегам. Недавно я правильно клонировал нашу сборку на базе Linux для радио ЦОД.fm в DataLine и решил поделиться своими наработками со всем сообществом.
Сегодня покажу, из чего я собирал новогоднее радио для создания праздничного настроения перед онлайн-корпоративом.
Для начала определимся с задачами
Чтобы радио радовало коллег качеством звука, стоит учесть несколько компонентов для разных задач:
сам сервер трансляции, с которого будем раздавать аудиопоток;
интерфейс для ведущих и гостей: распределенное вещание сегодня новая норма, участники шоу должны подключаться из разных мест без лагов и бубна;
инструменты для обработки звука: выравнивания громкости из разных источников, удаления шумов и наложения фоновой музыки на финальный трек;
служебный канал для бесшумной синхронизации действий во время эфира;
клиентская часть для подключения слушателей с любого устройства;
опционально можно добавить доп. фичи для общения со слушателями (чат в Телеграмме).
Кроме того, если вы такой же энтузиаст и собираете радио как pet-project в свободное время, скорее всего, ваш бюджет ограничен. Так что я не буду останавливаться на дорогих проприетарных продуктах для этих задач, а покажу решения на свободно распространяемом и условно-бесплатном ПО.
Сервер трансляции с TeamSpeak’oм и постобработкой
Свой сервер я собирал на базе Xubuntu 20.04 с lowlatency-ядром. Расскажу, какие компоненты на нем установлены, а потом покажу, как выставляю для них приоритеты.
OBS для обработки на лету. Под капотом сервера у меня Open Broadcaster Software (OBS). С помощью этого софта можно моментально обрабатывать аудио: поднимать громкость до нужного уровня, добавить компрессию, убрать пики, добавить джинглы и фоновую музыку:
![Во время эфира я запускаю джинглы, музыку и голос на микшере в OBS. Во время эфира я запускаю джинглы, музыку и голос на микшере в OBS.](https://habrastorage.org/getpro/habr/upload_files/ee9/3f1/7d2/ee93f17d2b5077722fdf5a38ad3c3a39.png)
У OBS есть фильтры, которые можно навесить на каждую аудиодорожку перед ее отправкой в эфир. У меня настроены 5 фильтров в таком порядке:
Limiter срезает все пиковые частоты звука, предотвращает клиппинг и перегрузки.
Noise Suppression удаляет с дорожки фоновый шум, так как шипящие дорожки нам ни к чему.
Усилитель Gain повышает громкость звука до заданного значения.
Compressor сглаживает перепады громкости звука, например, если кто-то начинает очень бурную дискуссию или, наоборот, начинает шептать на ушко.
В конце еще раз использую Limiter, чтобы убрать возможные пики от фильтра Compressor.
С помощью 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 (слева):
![](https://habrastorage.org/getpro/habr/upload_files/46f/e0e/a64/46fe0ea643deb16673c5a17948d6cc21.png)
На тестовой трансляции мы используем TeamSpeak как микшер, чтобы выровнять всех гостей:
![](https://habrastorage.org/getpro/habr/upload_files/ed6/92c/e6d/ed692ce6d3594e7f64b7b7f02674c5c3.png)
Во время боевой трансляции звук в служебном канале уже настроенный и ровный, можно записать стрим и потом выложить запись с минимальным редактированием:
![Записываем дорожки всех участников. Полезно, когда через TeamSpeak идет продовая трансляция, как это сделано у меня в linkmeup. Записываем дорожки всех участников. Полезно, когда через TeamSpeak идет продовая трансляция, как это сделано у меня в linkmeup.](https://habrastorage.org/getpro/habr/upload_files/f5c/2b0/1b1/f5c2b01b1e07a3a154d698b86ae259bb.png)
Чтобы бесшумно синхронизироваться друг с другом по организационным моментам, есть несколько способов. Мы в linkmeup используем чат в TeamSpeak. Создали систему специальных сигналов, наподобие этого:
![](https://habrastorage.org/getpro/habr/upload_files/b2a/da3/5c9/b2ada35c98012cb0af61c75021360668.png)
Также пробовали Zoom, где можно видеть друг друга и обмениваться жестами.
Еще один способ посинкаться — это «шептать» друг другу в служебном канале (за наводку спасибо @KorDen32).
Для этого запрещаем podbot'у слышать «шепот», чтобы в эфир не летело ничего лишнего. Для ведущих делаем небольшую настройку: задаем количество лиц для «перешептывания» и горячие клавиши. Лучше использовать именно сочетание клавиш, чтобы во время печати не нажимать команду в эфире случайно и не «шептать» почем зря.
![«Шепот» слышат все пользователи канала Alpha, кроме podbot'a. «Шепот» слышат все пользователи канала Alpha, кроме podbot'a.](https://habrastorage.org/getpro/habr/upload_files/c59/400/96e/c5940096e7e66e434074cad6ed2f5833.png)
Для ЦОД.fm я организовал на базе TeamSpeak служебный аудиоканал, где все слышат комментарии друг друга, но не выводят их в эфир. Получилась такая виртуальная студия, в которой редактор эфира решал технические и организационные вопросы с ведущими.
Настройка nice-приоритетов на сервере. Я отдаю высший приоритет системным вызовам, затем обрабатываю звук, все остальное потом.
Видим правильные nice-приоритеты — уже половина успеха:
![](https://habrastorage.org/getpro/habr/upload_files/f49/855/9e8/f498559e8b0967604b83d952052dae3f.png)
Настраиваем правильные лимиты, чтобы не получить лаги в эфире:
sudo vi /etc/security/limits.conf
@audio - rtprio 99
@audio - memlock unlimited
@audio - nice -19
sudo usermod -a -G audio user
![](https://habrastorage.org/getpro/habr/upload_files/ceb/20f/792/ceb20f792c2252f465875d237e4db7a6.png)
Отсыплем демону, отвечающему за звук, нужных значений приоритетов:
sudo vi /etc/pulse/daemon.conf
high-priority = yes
nice-level = -11
realtime-priority = 9
![](https://habrastorage.org/getpro/habr/upload_files/d28/c8b/dd6/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
![](https://habrastorage.org/getpro/habr/upload_files/29c/6fc/185/29c6fc1857f7c1d7f2ea7991293b8c8d.png)
Важные мелочи для пользователей
Для радио ЦОД.fm я завел отдельное доменное имя, настроил nginx, разобрался с шифрованием трафика и сертификатами. Даже любительскую радиостанцию лучше стримить по защищенному соединению, да и слушатели не будут ругаться на отсутствующий https. Позаботился о проксировании, чтобы сотрудник мог открывать стрим с любого удобного устройства с любым плеером. Но, если что, можно организовать стрим с этими инструментами и в локальной сети.
Для внешнего домена, само собой, стоит настроить фаервол и защиту от DDoS. На каждый глобальный IP-адрес я ограничивал количество TCP-соединений до 10. Перед запуском всей системы провел нагрузочное тестирование.
Для наших партнеров и ведущих подготовил инструкцию по запуску сервера и клиентской части: как включать фоновую музыку на OBS и выводить участника в эфир:
![](https://habrastorage.org/getpro/habr/upload_files/2a5/59d/cb5/2a559dcb51205fa729b1dbad4c56ad03.png)
Еще можно создать чат радиостанции в вашем любимом мессенджере и принимать там сообщения в эфир, приветы, заявки на музыку и т. д. Тут уже кто как любит.
Будем использовать этот сервер для онлайн-трансляций дружественных подкастов «Поддатой», «Разговоры из-под фальшпола» и «Немного об оружии».