Интернет-радиостанция на Liquidsoap + IceCast

liquidsoapДовольно много на хабре сказано про интернет-радиовещание изнутри. Есть даже хорошо написанные теоретические основы интернет-радиовещания, с которыми советую ознакомиться. В данной статье я бы хотел рассказать об организации ещё одной любительской интернет-радиостанции, построенной на связке незаслуженно малоизвестного Liquidsoap 1.0.1 и вездесущего IceCast 2.3.2. Статья расчитана на тех, кто хотя бы приблизительно знает, что такое аудиопоток, IceCast, линуксовская консоль и таки что он вообще хочет получить. Однако она и написана начинающим пользователем, поэтому моё решение даже не зарекается на звание оптимального.

Требуемый итоговый функционал


  1. Возможность назначения своего плейлиста для произвольного временного отрезка
  2. Поддержка подхвата OGG, MP3, FLAC в качестве источника для аудиопотока
  3. Динамичность конфигурирования
  4. Простота редактирования контента для радиоэфира
  5. Работа под Linux
  6. Возможность начинающему Linux-пользователю установить и настроить всё это

После довольно долгих проб различных способов получения данного функционала, я остановился именно на Liquidsoap + IceCast. Последний был взят за соответствие требованиям и широкую распространённость (в принципе, аналоги я даже не искал), а Liquidsoap за воистину потрясающие возможности, доступные посредством его функционального языка скриптования. До него я рассматривал ices, ices + ardj, AirTime, что-то ещё, что даже и не упомнить, но все они так или иначе мне не подходили. В общем, я решил воспользоваться Liquidsoap. Из недочетов я заметил только выдачу пустого потока при неизвестных обстоятельствах (после перезапуска) — решается перезагрузкой. К сожалению, всей мощи его я не смогу ощутить — вся документация написана на английском, а с ним у меня не всё гладко — однако что-то я усвоил и постараюсь описать всё, чем могу оперировать.

Установка


Не долго думая я решил всё это чудо поднять на своём ноутбуке под openSUSE 12.2 x64, дабы было удобно изучать функционал Liquidsoap, а уже потом перенести на рабочую машину. В репозиториях присутствовал лишь IceCast, Liquidsoap же пришлось собирать. Пользователи Debian/Ubuntu, Windows, Mac OS X, FreeBSD и ArchLinux могут взять готовые пакеты на официальном сайте.

IceCast

Установку IceCast я выполнил из стандартных репозиториев:
# zypper in icecast

Подробно описывать конфигурацию IceCast я не буду, лишь приведу рабочий пример того, что крутится у меня:

/etc/icecast.xml
<icecast>
    <limits>
        <clients>100</clients>
        <sources>2</sources>
        <threadpool>5</threadpool>
        <queue-size>524288</queue-size>
        <client-timeout>30</client-timeout>
        <header-timeout>15</header-timeout>
        <source-timeout>10</source-timeout>
        <burst-on-connect>1</burst-on-connect>
        <burst-size>65535</burst-size>
    </limits>

    <authentication>
	<source-password>mypass</source-password>
        <relay-password>mysecondpass</relay-password>
        <admin-user>adminuser</admin-user>
        <admin-password>mythirdpass</admin-password>
    </authentication>
    <hostname>localhost</hostname>
    <listen-socket>
        <port>8000</port>
    </listen-socket>
    <fileserve>1</fileserve>
    
#_____________________________________________________________
# Наш запасной источник. В статье о нём не упоминается, ибо и у меня пока что он не сделан так, чтобы людям не стыдно было показать. А вообще к нему цепляется ices с музыкой из папки secure.

    <mount>
      <mount-name>/secure</mount-name>
      <hidden>1</hidden> # Делаем невидимым - пользователи не смогут им воспользоваться
      <charset>UTF8</charset> # Кодировка
    </mount>

# Описываем соответствующие mount'ы
    <mount>
      <fallback-mount>/secure</fallback-mount> # Какой источник подхватывать, если текущий упал
      <fallback-override>1</fallback-override> # Позволяет перебрасывать текущих клиентов на запасной источник без потери связи
      <fallback-when-full>1</fallback-when-full> # При достижении максимума слушателей, новому клиенту будет представлен запасной источник
      <mount-name>/HabraRadio_192</mount-name> # Название mount'а.
      <charset>UTF8</charset> # Кодировка
    </mount>
    
    <mount>
      <fallback-mount>/secure</fallback-mount>
      <fallback-override>1</fallback-override>
      <fallback-when-full>1</fallback-when-full>
      <mount-name>/HabraRadio_320</mount-name>
      <charset>UTF8</charset>
    </mount>
    
    <mount>
      <fallback-mount>/secure</fallback-mount>
      <fallback-override>1</fallback-override>
      <fallback-when-full>1</fallback-when-full>
      <mount-name>/HabraRadio_vorbis_avg_128</mount-name>
      <charset>UTF8</charset>
    </mount>
    
#_____________________________________________________________

    <paths>
        <basedir>/usr/share/icecast</basedir>
        <logdir>/var/log/icecast</logdir>
        <webroot>/usr/share/icecast/web</webroot>
        <adminroot>/usr/share/icecast/admin</adminroot>
        <alias source="/" dest="/status.xsl"/>
    </paths>

    <logging>
        <accesslog>access.log</accesslog>
        <errorlog>error.log</errorlog>
      	<loglevel>3</loglevel>
      	<logsize>10000</logsize> 
    </logging>

    <security>
        <chroot>0</chroot>
        <changeowner>
            <user>icecast</user>
            <group>icecast</group>
        </changeowner>
    </security>
</icecast>


Liquidsoap

Качаем, подготавливаем:
$ git clone https://github.com/savonet/liquidsoap-full.git liquidsoap
$ cd liquidsoap
$ make init
$ cp PACKAGES.minimal PACKAGES

Для меня достаточно минимального набора, но если кому нужна поддержка ещё чего-либо, то следует отредактировать файл PACKAGES.
Для нормальной компиляции программы я устанавливал следующие пакеты:
# zypper in make autoconf automake ocaml libao-devel libmad-devel libmp3lame-devel flac-devel libgavl-devel ocaml-camomile-devel ocaml-camlimages-devel ocaml-camomile-data libtheora-devel ocaml-findlib-devel libsamplerate-devel libtag-devel libvorbis-devel gcc-c++ ocaml-pcre-devel libtiff-devel libjpeg62-devel libXpm-devel

Собираем:
$ ./bootstrap
$ ./configure --with-user=user --with-group=users
$ make
# make install

К слову, после выполнения "./configure ..." стоит проверить, весь ли функционал, нужный нам, будет доступен в собранной программе. Сделать это можно просто посмотрев на таблицу, выведенную при завершении "./configure ..."
Всё, проверить работоспособность программы можно выполнив «liquidsoap --version» — ошибок быть не должно.

Ориентируемся с расписанием эфира


Предположим, что нам необходимо получить приблизительно следующее:
  1. 02:00-06:00 — ночной плейлист
  2. 06:00-09:00 — утренний плейлист
  3. 09:00-19:00 — дневной плейлист
  4. 19:00-02:00 — вечерний плейлист
  5. пн, ср, пт — 21:00-22:00 — одна программа
  6. пн, ср, чт, пт — 18:00-19:00 — вторая программа

Расположение в файловой системе:
radio
├── collection            | Аудиофайлы
│   ├── efir              | Музыка и джинглы
│   │   ├── daytime       | Дневной плейлист
│   │   │   ├── jingles   | Джинглы, играющие днём
│   │   │   └── music     | Музыка, играющая днём
│   │   ├── evening       | Соответственно, вечер
│   │   │   ├── jingles
│   │   │   └── music
│   │   ├── morning       | Утро
│   │   │   ├── jingles
│   │   │   └── music
│   │   └── night         | И ночь
│   │       ├── jingles
│   │       └── music
│   ├── programs
│   │   ├── 1_prog        | 1 программа
│   │   ├── 2_prog        | 2 программа
│   ├── promo             | Информационные вставки
│   └── security          | Папка с запасной музыкой
├── technical             | Конфиги, логи
└── документация          | Описание всего этого

Конфигурация Liquidsoap


Сразу приведу готовую конфигурацию:

./radio/technical/start_liquidsoap
#!/usr/local/bin/liquidsoap

# создаём переменные быстрого исправления в одном месте по необходимости
# базовая информация о выводимом потоке
out = output.icecast(
# хост с icecast
host = "127.0.0.1",

# его порт
port = 8000,

# логин
user = "source",

# и пароль
password = "mypass",

# название
name = "Интернет-радио",

# жанр
genre = "Rock",

# ссылка на сайт
url = "http://habrahabr.ru",

# кодировка
encoding = "UTF-8"
)

# включаем telnet-сервер
set("server.telnet.bind_addr","127.0.0.1")
set("server.telnet",true)

# _____________________________________
# Описание файловой структуры нашего радиосервера. 
# Переменные можно не использовать, а писать сразу полные пути к плейлистам, но при изменении названия одной из папок, придётся править довольно много строк в конфигурации. Как показала практика, такой подход удобнее.

# абсолютный путь к рабочей директории
wd = "/home/user/radio"

# путь к папке с аудиофайлами
pl = "#{wd}/collection"

# техническая папка
tech = "#{wd}/technical"

# логи
set("log.file.path","#{tech}/liquidsoap.log") # путь к файлу лога
set("log.level", 3) # уровень логирования

# папка с информационными вставками
promo_dir = "#{pl}/promo"

# папка с программами
progr_dir = "#{pl}/programs"

# папка с изменяющимся эфиром
ef = "#{pl}/efir"

# папки соответствующих эфиров
ni = "#{ef}/night"
mo = "#{ef}/morning"
da = "#{ef}/daytime"
ev = "#{ef}/evening"

# папки с музыкой
mus_ni_dir = "#{ni}/music"
mus_mo_dir = "#{mo}/music"
mus_da_dir = "#{da}/music"
mus_ev_dir = "#{ev}/music"

# папки с джинглами
jin_ni_dir = "#{ni}/jingles"
jin_mo_dir = "#{mo}/jingles"
jin_da_dir = "#{da}/jingles"
jin_ev_dir = "#{ev}/jingles"

# плейлисты с программами. Обратите внимание - до этого указывались пути к папкам, а здесь - к простым текстовым файлам.
1_prog_pl = "#{progr_dir}/1_prog.pl"
2_prog_pl = "#{progr_dir}/2_prog.pl"


# _____________________________________
# Создаём объекты типа "source", в нашем случае это аудиоисточники. 
# Здесь атрибут "reload" позволяет раз в 360 секунд перечитывать плейлист по пути, указанному далее.
# По умолчанию, музыка проигрывается рандомно, атрибут <code>mode = "normal"</code> указывает на проигрывание по порядку.

# загружаем плейлисты, джинглы, вставки, программы
mus_ni   = playlist (reload = 360, "#{mus_ni_dir}")
mus_mo   = playlist (reload = 360, "#{mus_mo_dir}")
mus_da   = playlist (reload = 360, "#{mus_da_dir}")
mus_ev   = playlist (reload = 360, "#{mus_ev_dir}")

jin_ni   = playlist (reload = 360, "#{jin_ni_dir}")
jin_mo   = playlist (reload = 360, "#{jin_mo_dir}")
jin_da   = playlist (reload = 360, "#{jin_da_dir}")
jin_ev   = playlist (reload = 360, "#{jin_ev_dir}")

promo    = playlist (reload = 360, "#{promo_dir}")
1_prog   = playlist (reload = 360, "#{1_prog_pl}", mode = "normal")
2_prog   = playlist (reload = 360, "#{2_prog_pl}", mode = "normal")

# _____________________________________
# строим 4 потока, сразу всё перемешивая
# смешиваем вставки
ins_ni = rotate (weights = [2, 1], [jin_ni, promo])
ins_mo = rotate (weights = [2, 1], [jin_mo, promo])
ins_da = rotate (weights = [2, 1], [jin_da, promo])
ins_ev = rotate (weights = [2, 1], [jin_ev, promo])

# смешиваем вставки и потоки
ni = rotate (weights = [3, 1], [mus_ni, ins_ni])
mo = rotate (weights = [3, 1], [mus_mo, ins_mo])
da = rotate (weights = [3, 1], [mus_da, ins_da])
ev = rotate (weights = [3, 1], [mus_ev, ins_ev])

#_______________________________________________________________________
# конфигурируем расписание эфира

radio = switch (track_sensitive = true,
[
  ({ (1w21h - 1w22h) or (3w21h - 3w22h) or (5w21h - 5w22h)}, 1_prog),
  ({ (1w18h - 1w19h) or (3w18h - 3w19h) or (4w18h - 4w19h) or (5w18h - 5w19h)}, 2_prog),
  ({  2h - 6h  }, ni),
  ({  6h - 9h  }, mo),
  ({  9h - 19h }, da),
  ({ 19h - 2h  }, ev)
])

#_______________________________________________________________________

# добавляем crossfade
radio = crossfade(start_next=1., fade_out=1., fade_in=1., radio)

# и, наконец, запускаем вещалки с разным качеством

out(
 %vorbis.abr(samplerate = 44100, channels = 2, bitrate = 128, max_bitrate = 192, min_bitrate = 96),
 description = "Average vorbis 96-128-192 Kbps",
 mount = "HabraRadio_vorbis_avg_128",
 mksafe(radio)
)

out(
 %mp3(bitrate = 320, id3v2 = true),
 description = "MP3 320 Kbps",
 mount = "HabraRadio_320",
 mksafe(radio)
)

out(
 %mp3(bitrate = 192, id3v2 = true),
 description = "MP3 192 Kbps",
 mount = "HabraRadio_192",
 mksafe(radio)
)


Несколько комментариев:
1) Эти строки:
wd = "/home/user/radio"
pl = "#{wd}/collection"
ef = "#{pl}/efir"
ni = "#{ef}/night"
mus_ni_dir = "#{ni}/music"
mus_ni = playlist (reload = 360, "#{mus_ni_dir}")

вполне успешно можно заменить на
mus_ni = playlist (reload = 360, "/home/user/radio/collection/efir/night/music")

и ничего вам за это не будет — Liquidsoap просто вместо #{wd} подставляет значение переменной wd.

2) В месте, где мы внедряли вставки, были строки:
ins_ni = rotate (weights = [2, 1], [jin_ni, promo])
ni = rotate (weights = [3, 1], [mus_ni, ins_ni])

rotate() — позволяет регулировать очередью
weights = [2, 1], [jin_ni, promo] — указывает брать 2 трека из jin_ni, затем 1 из promo, после повторно 2 трека из jin_ni и так далее.
weights = [3, 1], [mus_ni, ins_ni] — указывает брать 3 трека из mus_ni, затем 1 трек из того уже перемешанного плейлиста, что получился строкой ранее (ins_ni).

3) При конфигурировании расписания эфира мы использовали следующие строки:
radio = switch (track_sensitive = true,
[
  ({ (1w21h - 1w22h) or (3w21h - 3w22h) or (5w21h - 5w22h)}, 1_prog),
  ({ (1w18h - 1w19h) or (3w18h - 3w19h) or (4w18h - 4w19h) or (5w18h - 5w19h)}, 2_prog),
  ({  2h - 6h  }, ni),
  ({  6h - 9h  }, mo),
  ({  9h - 19h }, da),
  ({ 19h - 2h  }, ev)
])


switch() — переключает аудиоисточники в заданное время.
track_sensitive = true — позволяет не прерывать текущий трек, даже если время активного плейлиста истекло. Т.е. если ночной трек начался в 05:59, то, пока он не закончится, в силу не вступит утренний плейлист.
({ (1w21h - 1w22h) or (3w21h - 3w22h) or (5w21h - 5w22h)}, 1_prog), — по понедельникам, средам и пятницам с 21 до 22 часов играть источник 1_prog.
Насколько я понял, те строкив списке switch(), что выше расположены, имеют высший приоритет.

Формирование плейлиста радиопрограммы


Принцип прост: в папке prog_1 лежат файлы радиопередачи вида «01_ProgName», где записаны голоса радиоведущих. Плейлист будет вида:

01_ProgName
Music152
02_ProgName
Music241
03_ProgName
Music937
...


Думаю, на bash было бы правильней писать генератор такого плейлиста, но я недавно дорвался до Python, посему на скорую руку написал на нём:

./radio/technical/generatorProg1.py
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import os
import random

finalPaylist = '/home/user/radio/collection/programs/1_prog.pl'
music = '/home/user/radio/collection/efir/evening/music/'
show = '/home/user/radio/collection/programs/1_prog/'
myShow = sorted(os.listdir(show))
myMusic = os.listdir(music)
listOfTracks = []

def getRandomTrack(list):
    i = 0
    buf = random.choice(myMusic)
    while (buf in list) & (not i == 100):
        i += 1
        buf = random.choice(myMusic)
    return buf

for i in range(60):
    if not i%2:
        try:
            listOfTracks.append(show + myShow[i/2])
        except :
            listOfTracks.append(music + getRandomTrack(listOfTracks))
    else:
        listOfTracks.append(music + getRandomTrack(listOfTracks))

myFile = open(finalPaylist, 'w')
for i in range(len(listOfTracks)):
    myFile.write(listOfTracks[i]+'\n')

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

Финальные штрихи


Заносим в crontab генерирование плейлистов:

crontab -e
0 19 * * * /home/user/radio/technical/generatorProg1.py
0 16 * * * /home/user/radio/technical/generatorProg2.py

Добавляем в автозапуск KDE пару строк:

/home/user/.kde4/Autostart/start_liquidsoap.sh
#!/bin/sh
cp /home/user/radio/technical/liquidsoap.log /home/user/radio/technical/liquidsoap_backup.log
cat /dev/null > /home/user/radio/technical/liquidsoap.log
liquidsoap /home/user/radio/technical/start_liquidsoap

Автозапустить IceCast тоже не помешало бы
/etc/init.d/icecast start
chkconfig --add icecast

И, что важно, на последок стоит настроить NTP — здесь довольно много зависит от верно установленного времени. Его я настроил из-под YaST.

В заключение


Сейчас это радио успешно работает, файлы добавляются ответственным человеком удалённо из-под Windows, что стало возможным с помощью связки openVPN+Samba, программы играют, логи пишутся. На будущее задумано ещё пара фич, среди которых: проигрывание различных вставок в начале каждого часа, реализация своей рандомизации плейлистов, удалённые конференц-звонки в прямой эфир, причёсывание всего и вся, настройка пущей отказоустойчивости, а так же поиск подводных камней. Вообще разбираться с Liquidsoap — одно удовольствие. Хорошей всем музыки.

UPD: Дополнение от milar.

UPD 2: Чтобы в эфире не было тишины после crossfade, необходимо перед crossfade добавить строку:
radio = mksafe(radio)

Большое спасибо kvaps за данное решение.
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 38
  • 0
    Тоже вещаем в этой связке. Можно занести в подводные камни:
    1. liquidsoap при внесении в 1 конфиг более 15 потоков начинает выдавать в эфир миллисекундные затыки звучания. Слышни, ужасны. Поэтому лучше иметь в виду, что при большой его нагрузке будет необходимо запускать несколько копий.
    2. icecast2 стандартный не держит онлайн более ~3000 соединений. У вас максимум клиентов в конфиге выставлено 100. Если упретесь во что-то неведомое — меняйте icecast2 на сборку kh. Сайт сборки — www.xiphicecast.webspace.virginmedia.com/
    3. Мыло собирали из latest stable сайта, а не из репозиториев, т.к. необходимой для нас поддержки aac+ нет в стандарте. Это для Ubuntu Server.

    Ну и для полноты статьи, мини-конфиг для upstart:
    description     "air-st"
    start on (
        net-device-up
        local-filesystems
        and runlevel [2345]
    )
    stop on runlevel [016]
    respawn
    exec su - liquidsoap -c "/usr/local/bin/liquidsoap /etc/liquidsoap/st.liq"
    

    Стандартно service air-st start/stop/restart (st — краткое название одной из станций. Удобно перезапускать их независимо).
    • 0
      Спасибо, добавил ссылку в пост.
      • 0
        Можно ссылочки на методику тестирования? Ванильный icecast у нас держал по 5к соединений. Причем тут форк от Карла Хейса я не знаю (да, это форк, а не «сборочка»)
        • 0
          Точный предел я не помню, каюсь. Как и графиков на данный момент, не сохранилось.
          Методика тестирования была следующая: новый сервер вещания был развернут в другом ДЦ (латест стэйбл убунта, icecast2 из пакетов). В конфигурации было установлено ограничение в миллион клиентов. Включили все потоки (на тот момент их было 56). Обновили ДНС-записи на новый сервер. Пошла нагрузка, мониторили онлайн плагином icecast2 к munin. Был достигнут суммарный онлайн в N-клиентов, после которого поведение стало следующим: подключиться было возможно только после 5-8 попыток. Продолжительное прослушивание «выбивало» клиента и вещание останавливалось при использовании плеера без функций переподключения (например, браузерный html5). Сразу же подумалось именно на разницу двух icecast2. Разница была найдена — именно в том, что ранее использовался форк kh. Поставили последний форк с той же конфигурацией — клиенты пошли подключаться выше предела в N-подключений.

          Для статистики:
          самый популярный маунт на текущий момент имеет рекорд в 7963 слушателей
          сумма онлайна остальных маунтов станций примерно 7-8 тысяч слушателей
          количество текущих потоков — 60 (15 станций, 4 формата), без учета служебных
      • 0
        Наконец-то годная статья про liquidsoap. Он и вправду незаслуженно непопулярен.
        • 0
          К liquidsoap есть веб-морда на Ruby. Добавьте в статью и про нее.
          • 0
            Не нашёл я в гугле информации по этому поводу.
            • 0
              Да сейчас куда-то пропал этот проект надо в svn поглядеть. Кстати вот уже писали о веб-интерфейсе Airtime — Управление радиоэфиром через браузер (Python/Django) он же упомянут вот тут savonet.sourceforge.net/tools.html
              • 0
                Airtime не совсем веб-морда, насколько я помню — это полноценный медиасервер+медиаисточник (т.е. кроме него больше ничего не надо), основанный на Liquidsoap. Я пробовал его до Liquidsoap, а в статье упомянул во втором абзаце. Хотелось остаться на нём, точно уже не помню, что не понравилось, но пришлось сменить решение.
                • 0
                  Я свой комментарий отправил до того как нашел ваши сообщения на форуме радиоталк.
                  Вообщем поспешил.
            • 0
              Жаль что Airtime нет нормального рандома.
            • 0
              Спасибо за статью и комментарии выше и ниже, как раз собирался поднимать на Shoutcast, теперь подумаю.
              • 0
                Использую liquidsoap для ретрансляции одной популярной радиостанции. Загвоздка в том, что у меня нет стабильного собственного источника, приходится использовать сторонние.
                Если кому будет полезно, так я делаю резервированный источник сигнала и допиливаю его:
                1src = input.http(force_mime=«audio/mpeg»,buffer=5.0,max=10.0,user_agent=«WinampMPEG/5.54»,«url1»)
                2src = input.http(force_mime=«audio/mpeg»,buffer=5.0,max=10.0,user_agent=«WinampMPEG/5.54»,«url2»)
                3src = input.http(force_mime=«audio/mpeg»,buffer=5.0,max=10.0,user_agent=«WinampMPEG/5.54»,«url3»)
                sat=amplify(5.,fallback(track_sensitive = true, [1src,2src,3src]))

                Вопрос, который меня до сих пор мучает — как выдавать более качественный aac+ звук, используя что-то ещё, кроме aacplusenc. Пробовал кодер от nero, но не смог понять, как вытащить aac звук из mp4 контейнера. aacplusenc по качеству несколько хромает всё же если сравнивать с nero aac+

                Ещё у меня есть скрипт — watchdog, который постоянно парсит логи, следит за наличием процесса и позволяет управлять запуском/остановкой. Завязан на cron и не использует init. Если кому нужно и имеют случае непонятного падения liquidsoap -общащайтесь.
                Использую версию 0.9.0, т.к. она для моих задач оказалась самой стабильной.

                Кстати кто-нибудь запускал rtmp/rtsp трафик на чём-нибудь опенсурсном (или не опенсурсном)? Хочу вещать aac+ в флеш-плеере. Просто aac+ поверх http флеш плеер не хавает(
                • 0
                  На radiotalk.ru пытались приделать аас+, не помню, чем дело кончилось. На Linux'е лицензия позволяет aac+ вещать максимум в 64 кбит/сек, но там кто-то сторонние библиотеки пытался пришить.
                  • 0
                    Какая лицензия? На что лицензия?
                    Пример вещания в aac+ на Icecast:
                    radio.kanaria.ru:8000/radio.aac (для кривых плееров: radio.kanaria.ru:8000/radio.aac.m3u)
                    Правда у нас сервер немного патченый
                    • 0
                      Лицензия ограничивает битрейт — максимум 64 кБит/сек. Если верить mediainfo и VLC, у вас битрейт равен 12,3 кБит/сек, да и на слух что-то около того.
                      • 0
                        еще раз: лицензия НА ЧТО?
                        еще раз: КАКАЯ лицензия?
                        я еще в первой статье писал, дабы люди не читали советских газе^w^wрадиотолк

                        Да, в настройках поставлено 12000 bit/s, небольшой оверхед допустим (как минимум из-за ADTS-заголовков), это версия для мобильных телефонов у нас.
                        • 0
                          Как-то гугл не подсказал источник информации, видимо, бред. Вам виднее.
                          • 0
                            На радиотолке таких откровений масса, а что самое неприятное — эти откровения разносятся как вирус по всему рунету (к счастью, в буржуйнете таких откровений нет), после чего становятся чуть ли не стандартом.
                    • 0
                      Есть ли смысл aac+ в более 64 кбит/с? На мой взгляд, даже 32 kbps звучит весьма комфортно.
                    • 0
                      Разве soundmanager2 не позволяет проигрывать aac+?
                      • 0
                        aac+ флеш может жрать через контейнер FLV (если с минимумом возни на клиенте, иначе надо ADTS разбирать руками)

                        засунуть его в RTMP можно опять таки через FLV, ибо внутри RTMP бегает только он. Все работает, все летает, но стримилку писал сам, ничего ШВАБОДНОГО не нашел для этого, сервер по идее может быть любым

                        c rtsp тоже множество вариантов, я частично добавил RTSP прямо в айскаст, правда только для ulaw-потоков.

                        Рекомендую зачитать ссылки из статьи
                        • 0
                          Можно написать модуль для erlyvideo, который будет делать IceCast/AAC -> RTMP/AAC. И поставить erlyvideo как прокси.
                          Я б даже оценил сложность, правда я протокол IceCast не знаю.
                          • 0
                            Держать этого монстра как прокси? Не, можно конечно и микроскопом гвозди забивать, дело хозяйское. А в качестве RTMP-серверов есть много чего, неприятнее эрли навреное только оригинальный FMS.

                            Протокол там обычный ICY, инкапсуляцию в FLV может делать сам айскаст (kh-форк), остается только в RTMP засунуть. Не знаю нафига. Это как надеть трусы на голову — оригинально конечно, но толк то какой?
                            • –1
                              >> Держать этого монстра как прокси
                              31 мб памяти на холостом ходу, копейки на коннект — не монстр. Писать ничего не надо, AAC/ShoutCast source есть из коробки — my fault. Поставил и забыл.

                              >> неприятнее эрли навреное только оригинальный FMS.
                              1. Такие сравнения обычно аргументируют.
                              2. Это мой tool of choice и если мне нужен RTMP-сервер, выбор для меня однозначен.
                              3. Вы свободный человек и свободны содомировать red5 или crtmpd.

                              >> Это как надеть трусы на голову
                              Я предложил простой и доступный путь решения, исходя из известных мне инструментов(в которых я, кстати, более чем уверен). Any problems?
                      • 0
                        Обрадовался, что в заголовке указаны ссылки на мои статьи. На вторую статью все забили, поэтому даже желания писать третью нет.

                        По поводу джинглов и расписания: разбивка по категориям «утро», «день», «вечер», «ночь» конечно очень популярна, но не гибка. Зачастую нужно приделать категорию «выходной», «праздник», в новый год (скоро он примчится) надо разбавить весь плейлист новогодней музыкой, а порой делать вообще тематические дни. Или, допустим какой-то горячий хит должен играть круглосуточно — его по всем директориям распихивать?

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

                        При генерации плейлистов используется рандом, данные которого никуда не записываются, ротацию построить не выйдет. Грубо говоря, если есть директория с полной дискографией Высоцкого, то в эфире будет только оно.

                        И да, у Liquidsoap хоть и много фич, но в данном случае ничего интересного с ним не увидел, используются штатные возможности, как у любой вещалки.
                        • 0
                          Жаль, что желания нет, я бы с радостью почитал про обеспечение возможности удалённого прямого эфира, а ещё лучше с несколькими участниками одновременно. Начал делать это, дак забрёл аж в Asterisk.

                          Категории дополняются довольно просто, как «радиопередачи» в статье. Наверняка можно сделать проверку пустоты папки силами Liquidsoap, я в функциональную часть языка пока не лез. Горячие хиты можно оформить как информационные вставки (promo) в статье через rotate(). Дело в том, что расписание и формат определяю не я, а ответственный за это человек не знает, что понадобится через какое-то время. Пока что проблем с реализацией задуманного не было. Начинали мы вообще с IDJC и одной папки на все времена.

                          Рандомность местная мне тоже не по душе — буду реализовывать сам. Ротации как таковые пока не понадобились, но, быть может, тоже найдётся решение. Не через Liquidsoap, дак через Python.

                          Сейчас в голову пришло — скрипт на Python должно получиться заменить через тот же rotate(). Почему сразу в голову не пришло — не понятно.
                          • 0
                            Астериск (а лучше фрисвитч), мамбл и просто скайп умеют делать аудиоконфочки, мы написали еще Flash-чат для общения голосом, дабы можно было прямо из браузера вещать + собирать конференцию. Лайвы — это пожалуй главная и самая интересная часть любого вещания.

                            Ротация эфира (те самые категории с разбивками по дням недели, выходным, праздникам) с выборкой треков — это пожалуй самое сложное в создании станции. Многие напихают музыки, включат волшебный рандом и ВСЕ РАБОТАЕТ КРУТА ЧО. В вашем примере хоть немного контент выбирается.

                            Еще есть такая замечательная штука как войс-треки с диджейскими стонами, контент от сторонних ресурсов с автоматической врезкой в эфир (к примеру, горячий выпуск новостей — система берет голос, добавляет к нему подложку и заставки, все это пускает в эфир) и прочие скриптотворения. У нас самодельный микшер, который позволяет выбрасывать в эфир сразу несколько треков (музыка, заставки, голоса, телефонные звонки), можно скриптовать все от часовых отбивок, заканчивая синтезированным прогнозом погоды поверх трека.

                            Надо признаться, что я сам не осилил сделать ротацию в человеческом виде, ибо идеи на бумаге одни, а в эфире звучат несколько иначе, нежели задумывались изначально. Это нетехнический момент. Как ее сделать — я не знаю.
                            • 0
                              Да, я видел сравнения производительности Asterisk и FreeSwitch, но уже начал изучать и читать книгу о Asterisk. При этом сейчас и в обозримом будущем его хватит с головой — радио только начало свою работу, до многотысячной аудитории одновременно ещё ой как далеко. Главное, что это всё интересно :) Со временем будет всё разрастаться, будут применяться знания из разных категорий, скриптования, врезки, передачи, чёрт в ступе — всё будет, если понадобится. Было бы желание.
                              • 0
                                А желаний нет? Творческая импотенция?
                                • 0
                                  Желание есть, но не вечно же будет длиться. Помимо обработки аудио, Liquidsoap ещё и видео умеет обрабатывать — сейчас параллельно и это изучаю, благо есть цель, к слову, не сложная — просто смешать картинки в слайдшоу, музыку в аудиопоток, текст из файла в бегущую строку и всё на IceCast. Искал аналоги — гугл считай не помог, на форумах ни одного поста не написали в ответ. Помимо этого, интеграция с тем же Asterisk'ом — непаханное поле уловок, нюансов, оптимизаций. Целей много, полёт творчества не скоро прервётся.
                                  • 0
                                    Я так и не смог найти хороших вещалок видео (не важно для какого протокола), дабы было все кроссплатформенно и желательно свободно.

                                    От себя могу натолкнуть вас на freej.org, может быть интересно будет, по крайней мере посмотрите. Далее, оригинальный айскаст умеет стримить только теору, которая мало кому интересна, поэтому для стриминга видео вы наверное будете искать что-то еще (у меня была идиотская мысль добавить в айскаст поддержку WMV, но я от нее отказался).

                                    Еще подскажу такую штуку как WireCast, более цельное решение, позволяет НУ ОЧЕНЬ много, чего-то больше — уже писать самим. Я вот видео не транслирую, смешивать картинки мне не надо, зато я вырезаю из видеопотока картиночки и пощщу на сайт — можно делать презентации. Но я и писал для себя серверную часть.

                                    А астериск просто гейт/микшер голоса, один из многих.
                                    • 0
                                      Спасибо, оба решения погляжу. Аудитории как таковой для этого не будет — на кучу телевизионных панелей выдавать, не более. Писать самому едва ли что серьёзное сейчас буду — ни опыта, ни знаний, потом может быть.
                        • 0
                          [удалил]
                          • 0
                            Долго пытался понять, но почему-то с crossfade в эфир шла одна только тишина.

                            Позже разобрался, если до crossfade поставить mksafe, то воспроизведение идет как и положено.
                            • 0
                              Вы знаете, эта проблема довольно большому количеству администраторов(-новичков?) портит нервы. Я с этой бедой мирился ребутом сервера в течение года (после 1ого запуска liquidsoap всё хорошо звучало, потом — тишина). Спасибо большое за решение, действительно помогло!
                            • 0
                              Я прошу прощения за идиотский вопрос, а как получить доступ к вещанию? На какой url ходить?

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.