В интернет-радио битрейт — это не просто цифра. Это компромисс между качеством звука и доступностью. Для домашних слушателей на широком канале вы хотите отдавать кристально чистый 320 kbps. Для тех, кто слушает в метро или на даче с мобильным интернетом — 64 kbps или даже 48 kbps, чтобы поток не прерывался.
Казалось бы, логичная потребность: дать слушателям выбор. Но в классическом стеке Icecast реализация этой «простой» идеи превращается в архитектурный кошмар. Давайте разберемся, почему Icecast заставляет вас плодить потоки и как в нашем решении смена битрейта — это просто параметр в конфиге.
Как Icecast "решает" проблему битрейта
Icecast — это ретранслятор. Он отдает слушателям ровно тот поток, который получает от источника. Если источник гонит 320 kbps, Icecast будет раздавать 320 kbps. Если источник гонит 64 kbps — будет 64 kbps. Сам Icecast не умеет транскодировать.
Поэтому для создания нескольких битрейтов обычно используют:
- Несколько экземпляров Liquidsoap — каждый гонит свой битрейт на отдельный маунт.
- Один Liquidsoap с несколькими выходами — в одном скрипте прописывают output.icecast для разных битрейтов.
- FFmpeg или ezstream — как прослойка, которая перекодирует поток на лету.
Все эти варианты требуют либо умножения процессов, либо сложных конфигов. Icecast просто раздает то, что получает.
Поэтому, если вы хотите дать слушателям выбор между разными битрейтами, вам нужно:
- Создать несколько источников: Один источник гонит поток в высоком битрейте, другой — в низком. Для каждого битрейта — свой экземпляр Liquidsoap (или другого софта), свой конфиг, свой процесс.
-
Настроить разные маунты в Icecast:
/streamдля 320 kbps,/stream/lowдля 64 kbps,/stream/mobileдля 48 kbps. Три маунта — три точки монтирования. - Научить плеер выбирать нужный поток: Плеер должен определять скорость интернета у слушателя и автоматически подставлять нужный маунт. Или давать кнопки ручного выбора качества.
- Умножать всё на количество жанров: Если у вас мультимаунт (рок, поп, джаз) и для каждого нужно 3 битрейта — получается 9 источников и 9 маунтов. Каждый со своим конфигом Liquidsoap, своим потреблением памяти, своими точками отказа.
Почему это плохо на практике
Допустим, вы хотите добавить мобильную версию потока. В классической схеме:
- Вы копируете конфиг Liquidsoap для высокого битрейта.
- Меняете в нем параметры
output.icecast(порт, маунт, битрейт). - Правите пути к плейлистам (если они отличаются).
- Создаете новый systemd-юнит.
- Запускаете и молитесь, чтобы не сломать что-то в существующих.
И это если у вас один жанр. Если жанров несколько — умножьте на количество жанров. В итоге вы получаете не радиостанцию, а ферму из десятка процессов, каждый из которых нужно мониторить, обновлять и перезапускать.
Наш подход: битрейт — это просто настройка маунта
В нашем DIY Радио транскодинг встроен в ядро. Один процесс читает файлы из папки, декодирует их и может отдавать слушателям поток в любом битрейте, который вы укажете. Вам не нужно запускать отдельный источник для 64 kbps и отдельный для 320 kbps.
Как это работает
В конфигурационном файле вы описываете маунты. У каждого маунта есть параметр bitrate:
[mount /rock] tracks_dir = ./data/rock/tracks bitrate = 320 [mount /rock_mobile] tracks_dir = ./data/rock/tracks bitrate = 64 [mount /jazz] tracks_dir = ./data/jazz/tracks bitrate = 192 [mount /jazz_low] tracks_dir = ./data/jazz/tracks bitrate = 48
Что здесь происходит?
- Маунт
/rockотдает рок в высоком качестве (320 kbps). - Маунт
/rock_mobileберет те же самые файлы из той же папки, но транскодирует их в 64 kbps на лету. - Всё это делает один процесс. Никаких дополнительных Liquidsoap, никаких дублирующихся конфигов.
Одна музыкальная библиотека — сколько угодно битрейтов
Ключевое отличие от Icecast: вам не нужно копировать файлы или создавать отдельные плейлисты для каждого битрейта. Все маунты используют одну и ту же директорию с треками.
- Добавили новый трек в
/data/rock/tracks/? Он автоматически появится во всех битрейтах этого жанра. - Изменили плейлист? Все маунты получат обновление одновременно.
- Не нужно синхронизировать 3 разных источника — они работают от одного источника данных.
Что происходит под капотом
Технически это выглядит так. Когда слушатель подключается к маунту с битрейтом 64 kbps, Go-приложение:
- Читает исходный аудиофайл (например, FLAC или MP3 в высоком качестве).
- Декодирует его в PCM (несжатый звук).
- Сжимает обратно с нужным битрейтом (64 kbps) с помощью встроенного кодера (LAME для MP3, libvorbis для OGG).
- Отдает готовые пакеты слушателю.
Всё это происходит в реальном времени, с минимальной задержкой. При этом приложение эффективно использует горутины, так что даже 3-4 битрейта на один жанр не создают заметной нагрузки на сервер.
Сравнение подходов
Low-битрейт: экономия трафика без потери слушателей
Особенно актуальна эта функция для экономных или у тех у кого проблемы со скоростью (хотя в мире ютуб и 4к слабо верится :) ). Если вы будете отдавать только 320 kbps, значительная часть слушателей будет испытывать буферизацию, разрывы и в итоге уйдет к конкурентам.
В нашем решении вы можете создать маунт для мобильных устройств буквально одной строкой:
[mount /rock_low] tracks_dir = ./data/rock/tracks bitrate = 48
И дать слушателям ссылку https://radio.example.com/rock_low для мобильных приложений.
Гибкость без сложности
Вы не ограничены жесткими правилами. Можно настроить:
- Для десктопа: 320 kbps (максимальное качество).
- Для планшетов: 128 kbps (баланс качества и трафика).
- Для смартфонов 4G: 64 kbps (стабильность).
- Для 3G/EDGE: 48 kbps или 32 kbps (доступность).
И всё это — из одного набора файлов. Нет нужды создавать отдельные копии музыки в разном качестве, нет нужды держать в голове, какой плейлист для какого битрейта обновлен.
Итог: качество — это выбор, а не наказание
Смена битрейта в интернет-радио — это не просто техническая деталь. Это вопрос доступности вашего контента. Слушатель с плохим интернетом не должен страдать из-за того, что вы транслируете в высоком качестве. И наоборот — слушатель с хорошим каналом не должен слушать сжатый звук.
В классическом стеке Icecast реализация этой простой идеи требует умножения сущностей. Каждый битрейт — это отдельный источник, отдельный конфиг, отдельный процесс. В нашем решении:
- Один процесс обрабатывает все битрейты.
- Одна музыкальная библиотека для всех качеств.
- Одна строка в конфиге — новый битрейт.
Хотите дать слушателям выбор между 320, 128 и 64 kbps? Добавьте три маунта в конфиг. Хотите убрать низкое качество? Удалите строку. Всё остальное сделает Go.
Вы контролируете качество, а не плодите процессы.