Вещание в Icecast2 из Linux

2011.09.16

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

Это руководство ориентировано на пользователей, знакомых с консолью и не боящихся редактировать текстовые файлы.  Варианты для пользователей, предпочитающих кликать мышкой, будут приведены в конце статьи.  Руководство будет дорабатываться.

Принципы маршрутизации и коммутации звука

Выдавать готовый MP3 поток в эфир — не сложно, для этого есть много специализированных утилит: ices, ezstream, oggfwd, mpd и другие.  С их настройкой справится любой.  Сложность вызывает смешивание в один поток голоса, музыки и Скайпа, чтобы затем этот поток выдать в эфир станции.

Для смешивания потоков нужна система коммутации звука.  Это программа, которая сможет выход одного приложения направить на вход другого, а то и нескольких.  Сами приложения обычно не предполагают такого использования и вещать умеют только в один приёмник: в звуковую карту.  Системы коммутации звука, по сути, создают для каждого приложения отдельную виртуальную звуковую карту и позволяют их коммутировать виртуальными кабелями.  Для полноценного эфира нужно получить такую схему:

Routing

(Вывод микрофона в наушники я не нарисовал, т.к. у меня этим — мониторингом — занимается звуковая карта, а любая попытка сделать это программно приведёт к такой задержке, при которой разговаривать невозможно.)

Для Linux есть три системы коммутации звука: ALSA, RoarAudio и JACKКоммутацию средствами ALSA осилит только ниндзя, которым я пока не являюсь, хотя этот вариант был бы наиболее эффективен в плане системных ресурсов.  Второй вариант практически никем не поддерживается, а третий является фактическим стандартом.

Не все программы поддерживают JACK напрямую.  Skype и Flash, например, не поддерживают.  Для них придётся подружить JACK и PulseAudio — стандартную звуковую систему в свежих версиях Ubuntu.  Они неплохо уживаются вместе.

Используемые компоненты

Вот полный список ПО, которое я использую на своём нетбуке:

  • JACK
  • PulseAudio
  • MPlayer
  • Skype
  • darkice

Именно в этом порядке я опишу их настройку.

Предварительная настройка JACK

Главная проблема при работе с JACK — неумение работать с несколькими звуковыми устройствами и неумение работать с устройствами, которые могут исчезать.  Например, если вы подключаете внешнюю звуковую карту через USB, запускаете JACK и отсоединяете карту, JACK виснет.  Я пока не придумал хорошего решения этой проблемы; опишу когда придумаю.

JACK — сервер, понимающий конфигурационные файлы и консольные команды.  Для его настройки и управления им понадобится графическая консоль QjackCtl.  Она выглядит так:

QjackCtl main window

В этом окне надо нажать на кнопку «Setup» и в появившемся окне выбрать желаемую звуковую карту:

QjackCtl setup window

По умолчанию используется встроенная звуковая карта.  Если это устраивает — можно ничего не настраивать.  Если вы используете внешнюю звуковую карту — выберите её из списка (стрелка вправо рядом с полем «Interface»).  Другие параметры трогать не надо.

Коммутация звуковых каналов описана дальше, после настройки всех остальных компонентов.

Настройка PulseAudio

PulseAudio использует все имеющиеся звуковые карты с помощью механизма ALSA в эксклюзивном режиме.  Одновременно карту может использовать либо JACK, либо PulseAudio.  Для вещания нужно чтобы система PulseAudio выдавала звук в JACK и только туда (чего, кстати, она по умолчанию вообще не делает).  Для этого нужно создать конфигурационный файл ~/.pulse/default.pa со следующим содержимым:

.fail
load-module module-jack-source
load-module module-jack-sink
.ifexists module-esound-protocol-unix.so
load-module module-esound-protocol-unix
.endif
load-module module-native-protocol-unix
load-module module-rescue-streams
load-module module-always-sink
load-module module-intended-roles
load-module module-suspend-on-idle
load-module module-console-kit

Теперь нужно установить пакет pulseaudio-module-jack, затем перезапустить PulseAudio такой последовательностью команд:

$ pulseaudio -k
$ pulseaudio --start

Теперь PulseAudio выдаёт весь звук в JACK и только туда.  Теперь Skype, Flash, музыкальный проигрыватель и всё остальное, что не поддерживает JACK напрямую, видно в нём как «PulseAudio Sink».

Ещё один вариант настройки можно найти в вики на jackaudio.org.

Настройка MPlayer

В общем случае достаточно, чтобы проигрыватель использовал PulseAudio.  Коммутируется он так же, как и Skype, поэтому можно ничего вообще не настраивать, всё должно работать как есть.

Я для проигрывания музыки использую mplayer.  Его настройка заключается в том, чтобы он по умолчанию использовал JACK когда это возможно, чтобы его можно было комутировать отдельно.  Для этого нужно в файл ~/.mplayer/config добавить такие строки:

[default]
ao=jack,pulse,alsa

Теперь mplayer будет пытаться использовать JACK, если он не запущен — будет использовать PulseAudio, если и этого нет — ALSA.  Если вам не нужна отдельная коммутация проигрывателя, можно просто пустить mplayer в PulseAudio

Настройка DarkIce

Утилита DarkIce умеет брать звук из внешнего источника, сжимать его в MP3/OGG и отправлять на потоковый сервер, сохраняя при этом локальную копию всгео эфира.  Она поддерживает JACK напрямую.  Конфигурационный файл выглядит так:

[general]
duration=0
bufferSecs=10
realtime=yes

[input]
device=jack
sampleRate=44100
bitsPerSample=16
channel=2
jackClientName=darkice

[icecast2-0]
format=mp3
bitrateMode=cbr
bitrate=128
server=stream.example.com
port=8180

mountPoint=test.mp3
password=test

name=Bob's Radio
description=This is my station where I do what I want.
url=http://example.com/
genre=Talk
public=yes
localDumpFile=dump/test.mp3
fileAddDate=yes

Почти все параметры говорят сами за себя.  Запускается вещание так:

darkice -c test.cfg

Записи эфира будут складываться в папку dump в виде файлов с расширением .mp3 и датой начала эфира в качестве имени.

Настройка коммутации в QjackCtl

Теперь все компоненты в принципе работают, но надо заставить их разговаривать друг с другом.  Для этого используется функция «Patchbay».  В главном окне QjackCtl есть одноимённая кнопка.  При нажатии на эту кнопку выводится такое окно:

QjackCtl Patchbay

Здесь можно настроить правила, по которым программы связываются между собой.  Левый список — «Output Sockets» — это источники звука, который программы используют как колонки, выдавая туда звук.  Правый список — «Input Sockets» — это приёмники звука, который программы используют как микрофон, получая из них звук.

Для добавления приложения следует нажать на кнопку «Add» рядом с нужным списком, ввести понятное вам описание приложения (например, «Микрофон») и выбрать приложение в выпадающем списке «Client».  Приложения появляются в нём только когда они используют звуковую систему, поэтому надо запустить проигрыватель, устроить в Скайпе тестовый звонок итп.  Окно добавления нового сокета выглядит так:

QjackCtl Socket

Клиент «system» — это звуковая карта, которую использует JACK, все остальные клиенты соответствуют приложениям.

После добавления всех нужных приложений их можно начать коммутировать.  Для этого нужно выбрать в левом и правом списках нужные сокеты и нажать на кнопку «Connect».  Вот используемая мной схема:

QjackCtl Graph

Что к чему:

  • PulseAudio вещает в колонки (наушники), чтобы звук слышал я, и в darkice, чтобы звук уходил в эфир.  PulseAudio — это Skype, Flash и большинство музыкальных проигрывателей.
  • MPlayer вещает в колонки, чтобы его слышал я, в darkice, чтобы звук уходил в эфир, и в PulseAudio, чтобы звук уходил в Skype.  В противном случае собеседник не будет слышать музыку, начнёт говорить невпопад и портить эфир.
  • Звук микрофона передаётся в darkice, чтобы попасть в эфир, и в PulseAudio, чтобы его слышал собеседник, ведь через PulseAudio работает Skype.

Вот и вся коммутация.  Для проверки всех настроек можно позвонить кому-нибудь по скайпу и включить музыку в проигрывателе.  Если собеседник слышит ваш голос и музыку, значит всё настроено правильно.

Чтобы использовать эти настройки коммутации всегда, сохраните их (кнопка «Save»), затем во вкладке «Options» основных настроек программы (кнопка «Setup» в главном окне QjackCtl) укажите этот файл в поле «Activate Patchbay persistence» и установите рядом галку:

QjackCtl Patchbay Persistence

Теперь можно перезапускать JACK не боясь потерять настройки.

Настройка коммутации в консоли

Вместо QjackCtl можно использовать консольный коммутатор jack.plumbing из пакета jack-tools.  Вместо связывания устройств мышкой придётся использовать текстовый файл с регулярными выражениями, примерно такого вида:

(connect "system:capture_1" "darkice:left")
(connect "system:capture_2" "darkice:right")
(connect "MPlayer \[\d+\]:out_0" "darkice:left")"
(connect "MPlayer \[\d+\]:out_1" "darkice:right")"

И далее в таком духе.  Преимущество этого подхода по сравнению с использованием QjackCtl в возможности быстро переключаться между заготовленными наборами правил и делать это скриптами.  Например, при запуске проигрывателя можно отключать от эфира Скайп, чтобы можно было пообщаться за кадром.

Ведение эфира из консоли

Прямой эфир начинается запуском darkice.  Если у вас есть какая-то интра или фоновая музыка, её можно запускать автоматически.  Я делаю это таким скриптом:

#!/bin/sh
mkdir -p dump
darkice -c test.cfg &
sleep 1
mplayer intro1.mp3
mplayer intro2.mp3
mc ~/music ~/music

При запуске скрипта выполняется подключение к серверу, через секунду начинает играть первое вступление.  Когда я сказал всё, что нужно, я нажимаю ESC, mplayer закрывается и запускается второй звуковой файл, который завершает приветствие.  Затем запускается файловый менеджер, с помощью которого я проигрываю музыку по ходу эфира.

Для того, чтобы во время музыкальной паузы можно было пообщаться с собеседниками по Скайпу, можно разорвать некоторые установленные соединения, затем восстановить их.  Для этого можно использовать утилиты jack_connect и jack_disconnect.

Ведение эфира без консоли

Для любителей графических интерфейсов есть специальный кухонный комбайн, который называется Internet DJ Console.  Он содержит в себе проигрыватель музыки и джинглов, умеет вещать в сервер Icecast2 (darkice не нужен), позволяет на ходу включать и отключать от эфира микрофон и Скайп (чтобы можно было обсудить дальнейший план по Скайпу, пока в эфире звучит музыка).

Принципиальных сложностей настройка этого комбайна не вызывает, поэтому описывать её не буду.  Коммутируется примерно так же, как darkice, только звук проигрывателей надо подавать на входы «aux_in_l» и «aux_in_r».

Я не использую IDJC потому, что она (консоль) заметно грузит процессор и его перестаёт хватать при конференции с двумя удалёнными собеседниками.

Вопросы, на которые у меня пока нет ответов

Буду признателен, если кто-нибудь подкинет ссылок на следующие темы:

  • Как научить JACK переключаться на встроенную звуковую карту при отключении внешней, которую он использовал?  Сейчас для этого надо перезапускать JACK, отчего надо перезапускать PulseAudio, отчего Flash-плагин, Skype и другие клиенты зависают.
  • Как научить JACK использовать несколько звуковых карт?  Может помочь заметка из вики.

Дополнительная информация

  • Вместо QjackCtl для коммутации можно использовать Patchage.
  • Звук можно на лету обрабатывать с помощью JACK Rack.
  • Кроме IDJC есть ещё MuSE.

Следить за развитием событий можно через RSS ленту или почтовую рассылку.