Смена битрейта: почему в Icecast это ад, а у нас — одна строчка в конфиге

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

В интернет-радио битрейт — это не просто цифра. Это компромисс между качеством звука и доступностью. Для домашних слушателей на широком канале вы хотите отдавать кристально чистый 320 kbps. Для тех, кто слушает в метро или на даче с мобильным интернетом — 64 kbps или даже 48 kbps, чтобы поток не прерывался.

Казалось бы, логичная потребность: дать слушателям выбор. Но в классическом стеке Icecast реализация этой «простой» идеи превращается в архитектурный кошмар. Давайте разберемся, почему Icecast заставляет вас плодить потоки и как в нашем решении смена битрейта — это просто параметр в конфиге.

Как Icecast "решает" проблему битрейта

Icecast — это ретранслятор. Он отдает слушателям ровно тот поток, который получает от источника. Если источник гонит 320 kbps, Icecast будет раздавать 320 kbps. Если источник гонит 64 kbps — будет 64 kbps. Сам Icecast не умеет транскодировать.

Поэтому для создания нескольких битрейтов обычно используют:

Все эти варианты требуют либо умножения процессов, либо сложных конфигов. Icecast просто раздает то, что получает.

Поэтому, если вы хотите дать слушателям выбор между разными битрейтами, вам нужно:

  1. Создать несколько источников: Один источник гонит поток в высоком битрейте, другой — в низком. Для каждого битрейта — свой экземпляр Liquidsoap (или другого софта), свой конфиг, свой процесс.
  2. Настроить разные маунты в Icecast: /stream для 320 kbps, /stream/low для 64 kbps, /stream/mobile для 48 kbps. Три маунта — три точки монтирования.
  3. Научить плеер выбирать нужный поток: Плеер должен определять скорость интернета у слушателя и автоматически подставлять нужный маунт. Или давать кнопки ручного выбора качества.
  4. Умножать всё на количество жанров: Если у вас мультимаунт (рок, поп, джаз) и для каждого нужно 3 битрейта — получается 9 источников и 9 маунтов. Каждый со своим конфигом Liquidsoap, своим потреблением памяти, своими точками отказа.
«Icecast не просто не умеет менять битрейт — он архитектурно заставляет вас создавать отдельный поток для каждого качества. Три битрейта = три источника = трижды больше конфигов, памяти и головной боли. А если у вас 5 жанров и 3 битрейта — привет, 15 процессов и 15 маунтов.»

Почему это плохо на практике

Допустим, вы хотите добавить мобильную версию потока. В классической схеме:

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

Наш подход: битрейт — это просто настройка маунта

В нашем 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

Что здесь происходит?

Одна музыкальная библиотека — сколько угодно битрейтов

Ключевое отличие от Icecast: вам не нужно копировать файлы или создавать отдельные плейлисты для каждого битрейта. Все маунты используют одну и ту же директорию с треками.

  • Добавили новый трек в /data/rock/tracks/? Он автоматически появится во всех битрейтах этого жанра.
  • Изменили плейлист? Все маунты получат обновление одновременно.
  • Не нужно синхронизировать 3 разных источника — они работают от одного источника данных.

Что происходит под капотом

Технически это выглядит так. Когда слушатель подключается к маунту с битрейтом 64 kbps, Go-приложение:

  1. Читает исходный аудиофайл (например, FLAC или MP3 в высоком качестве).
  2. Декодирует его в PCM (несжатый звук).
  3. Сжимает обратно с нужным битрейтом (64 kbps) с помощью встроенного кодера (LAME для MP3, libvorbis для OGG).
  4. Отдает готовые пакеты слушателю.

Всё это происходит в реальном времени, с минимальной задержкой. При этом приложение эффективно использует горутины, так что даже 3-4 битрейта на один жанр не создают заметной нагрузки на сервер.

Сравнение подходов

Параметр Icecast + Liquidsoap Наше Go-решение
Количество процессов N (жанров) × M (битрейтов) + Icecast 1 (один бинарник)
Конфигурация N × M конфигов Liquidsoap Один конфиг с секциями mount
Дублирование библиотеки Нужно поддерживать синхронизацию плейлистов Общая папка для всех битрейтов
Добавление битрейта Создать новый конфиг + systemd-юнит Добавить строку в конфиг

Low-битрейт: экономия трафика без потери слушателей

Особенно актуальна эта функция для экономных или у тех у кого проблемы со скоростью (хотя в мире ютуб и 4к слабо верится :) ). Если вы будете отдавать только 320 kbps, значительная часть слушателей будет испытывать буферизацию, разрывы и в итоге уйдет к конкурентам.

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

[mount /rock_low]
tracks_dir = ./data/rock/tracks
bitrate = 48

И дать слушателям ссылку https://radio.example.com/rock_low для мобильных приложений.

Гибкость без сложности

Вы не ограничены жесткими правилами. Можно настроить:

И всё это — из одного набора файлов. Нет нужды создавать отдельные копии музыки в разном качестве, нет нужды держать в голове, какой плейлист для какого битрейта обновлен.

Итог: качество — это выбор, а не наказание

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

В классическом стеке Icecast реализация этой простой идеи требует умножения сущностей. Каждый битрейт — это отдельный источник, отдельный конфиг, отдельный процесс. В нашем решении:

Хотите дать слушателям выбор между 320, 128 и 64 kbps? Добавьте три маунта в конфиг. Хотите убрать низкое качество? Удалите строку. Всё остальное сделает Go.

Вы контролируете качество, а не плодите процессы.

Дайте слушателям выбор

320 kbps для домашнего Wi-Fi, 64 kbps для мобильных. Одна библиотека — все битрейты. Без дублирования конфигов и процессов.

Попробовать DIY Радио с умным транскодингом