Хочу поділитись з Вами досвідом встановлення сервера трансляції MP3 (OGG) (на кшталт shoutcast, icecast) з додатковою можливістю збереження трансльованого потоку на диск (архів радіотрансляції).
Таку задачу ми виконували для інтернет-трансляції радіо "Стрий-FM". Таку систему можна використовувати для трансляції аудіопотоку чи в Інтернеті чи в мережевого радіо в локальній мережі.
Загальна інформація
Трансляцією потоку в мережу займатиметься icecast2, джерелом потоку буде darkice, аудіо буде братись з аналогового лінійного входу звукової картки. Спрощена схема така: звукова картка -> darkice -> icecast2 ->мережеві клієнти-слухачі.
Реалізовувалось все на FreeBSD 7.1, проте, в загальному, підійде для будь-якої *nix системи, в тому числі й Linux (в принципі, самі програми доступні і для Windows).
Я буду зосереджуватись лише на найважливішому, вважаючи що базове розуміння встановлення програм та редагування конфігураційних фалів Вами освоєно. :)
Джерело потоку
Якщо Ви плануєте транслювати свою колекцію MP3-музики то можна використовувати icegenerator. Програма просканує локальні диски у пошуках музики та транслюватиме її потоковому демону. Я ж зупинюсь на отриманні звуку з звукової картки.
Налаштування звукової картки
На сервері ми використали просту вбудовану звукову картку. Її встановлення у FreeBSD не було складним.
спочатку треба динамічно підвантажити загальний модуль ядра що відповідає за звук та метадравер що підвантажить усі відомі ядру драйвери звукових карт:
kldload sound
kldload snd_driver
Після цього можна побачити яким модулем побачилась звукова картка та завантажувати лише його, вручну, через /boot/loader.conf, або вкомпілювати просто в ядро (рекомендовано):
# cat /dev/sndstat
FreeBSD Audio Driver (newpcm: 32bit 2007061600/i386)
Installed devices:
pcm0: <Intel ICH4 (82801DB)> at io 0xdffffa00, 0xdffff900 irq 17 bufsz 16384...
В директорії /dev повинно з'явитись декілька нових пристроїв (це може бути /dev/audo, /dev/mixer, /dev/dsp).
Якщо картка працює нормально, треба вибрати для неї правильний вхід для отримання аудіо (запису). Для цього можна використовувати псевдографічний регулятор рівня каналів aumix (/usr/ports/audio/aumix у FreeBSD) або консольну команду mixer. Зменшіть рівні усіх каналів на нуль, крім rec, та встановіть що записувати з лінійного входу.
У мому випадку, лінійний вхід позначався каналом line.
/usr/sbin/mixer vol 0
/usr/sbin/mixer pcm 0
/usr/sbin/mixer speaker 0
/usr/sbin/mixer line 0
/usr/sbin/mixer mic 0
/usr/sbin/mixer cd 0
/usr/sbin/mixer igain 0
/usr/sbin/mixer ogain 0
/usr/sbin/mixer line1 0
/usr/sbin/mixer phin 0
/usr/sbin/mixer phout 0
/usr/sbin/mixer video 0
/usr/sbin/mixer rec 30
/usr/sbin/mixer =rec line
Можливо прийдеться поекспериментувати з вибором каналу для запису (mixer =rec line <канал>) та рівнями каналів, для якісного звуку (mixer <канал> <рівень>).
Налаштування джерела MP3 потоку - darkice
Аудіо з звукової картки вміє забирати darkice. Після оцифрування, darkice передає потік демону icecast2, який транслює його в мережу.
У FreeBSD darkice без проблем встановлюється з потрів. Після встановлення, створюйте конфігураційний файл:
/usr/local/etc/darkice.cfg
[general]
duration = 0 # Тривалість декодування. 0 - означає назавжди
bufferSecs = 5 # розмір буферу, с
reconnect = yes # переконекчуватись до сервера, при розриві
[input]
device = /dev/dsp0.0 # пристрій для отримання аудіосигналу
sampleRate = 44100 # Частота дискретизації, Гц. 11025, 22050 чи 44100
bitsPerSample = 16 # розрядність. спробуйте 16
channel = 2 # к-сть каналів. 1 = моно, 2 = стерео
[icecast2-0]
bitrateMode = abr # усереднена якість потоку
format = mp3 # формат потоку (MP3, OGG, AAC)
bitrate = 128 # швидкість потоку (кб/с)
server = localhost #де знаходиться сервер трансляції на який передається потік
port = 8000 # порт сервера
password = HACKME # пароль для підключення до сервера
mountPoint = Stryi-FM # назва віртуальної точки монтування на сервері
name = Stryi FM # назва потоку
description = Radio tvoho mista # опис потоку
url = http://fm.stryi.com # домашня сторінка сервера (просто для інформації)
genre = Ukrainian, Pop, Rock, Hits # стиль
public = no # анонсувати в загальнодоступних радіокаталогах?
#localDumpFile = /radio_archive/a_current.mp3 # якщо плануєте створювати архів
Я прокоментував параметри файлу, тому пояснювати додатково дуже не буду, гадаю все очевидно.
Розділів [icecast2-] може бути декілька ([icecast2-0], [icecast2-1], [icecast2-2], [icecast2-X] і т.д, здається до семи), кожен з своїми налаштуваннями. Крім того є можливість створити розділи [file-0], [file-1], [file-2], [file-X] - для збереження файлів локально, без створення цифрового потоку.
Зверніть лише увагу, на пристрій (device). Насправді, в мене, /dev/dsp0.0 навіть не з'являвся, до першого запуску darkice. А після запуску створився автоматично.
mountPoint - адреса (http://сервер:порт/Адреса), під якою буде видно потік в переліку доступних трансляцій.** **
Захочете поекспериментувати з якістю чи типом потоку (MP3, OGG, AAC) - пробуйте. Я зупинився на MP3 як на найпоширенішому форматі, хоча OGG і AAC дають кращі результати, навіть за однакових параметрах.
Запуск darkice
В найпростішому випадку darkice можна запускати так:
/usr/local/bin/darkice -c /usr/local/etc/darkice.cfg
У FreeBSD, для автоматичного запуску darkice треба створити такий скрипт:
/etc/rc.d/darkice.sh
#!/bin/sh
# PROVIDE darkice
# REQUIRE icecast2
case "$1" in
start)
/usr/local/bin/darkice -c /usr/local/etc/darkice.cfg >/dev/null &
echo $! > /var/run/darkice.pid
#SYM
/usr/sbin/mixer vol 0
/usr/sbin/mixer pcm 0
/usr/sbin/mixer speaker 0
/usr/sbin/mixer line 0
/usr/sbin/mixer mic 0
/usr/sbin/mixer cd 0
/usr/sbin/mixer rec 30
/usr/sbin/mixer igain 0
/usr/sbin/mixer ogain 0
/usr/sbin/mixer line1 0
/usr/sbin/mixer phin 0
/usr/sbin/mixer phout 0
/usr/sbin/mixer video 0
/usr/sbin/mixer =rec line
;;
stop)
kill -TERM `cat /var/run/darkice.pid`
rm -f /var/run/darkice.pid
;;
*)
echo "Usage: ./darkice.sh [start,stop]" >&2
;;
esac
В скрипті, крім запуску самого darkice, створюється файл з номером його процесу (/var/run/darkice.pid), який буде потрібний для створення архіву трансляцій, та регулюються рівні каналів запису, на випадок якщо вони зміняться, після перевантаження. Отут є приклад елегантнішого скрипта (але в ньому не створюється pid-файл).
Тепер, маючи готове джерело аудіопотоку, передаємо його серверу трансляції.
Налаштування сервера трансляції icecast2
Сервіс icecast2 отримує потоки від різних джерел (інші потоки, локальні файли тощо) та дозволяє передавати їх клієнтам (медіа-програвачі тощо).
У FreeBSD від встановлюється без проблем, з портів. Підкорегуйте конфігураційний файл icecast2. Я не буду цитувати його повністю. Зверніть увагу на таке:
/usr/local/etc/icecast.xml
<authentication>\
<!-- Пароль для джерел які захочуть підключитись -->
<source-password>HACKME</source-password>
<!-- дані адміністратора сервера трансляції -->
<admin-user>admin</admin-user>
<admin-password>HACKME</admin-password>
</authentication>
<!-- DNS-ім'я сервера трансляції -->
<hostname>online.fm.stryi.com</hostname>
<listen-socket>
<!-- Порт який будемо слухати -->
<port>8000</port>
</listen-socket>
<security>
<chroot>0</chroot>
<!-- Від чийого імені виконуємо -->
<changeowner>
<user>nobody</user>
<group>nogroup</group>
</changeowner>
</security>
Скрипт для автозапуску icecast2, у FreeBSD, встановлюється автоматично, його не треба змінювати.
Тепер, icecast2 запускає веб-сервер на порті 8000 та підключає до себе усі джерела потоків (наприклад вищеналаштований darkice) і підключає їх як доступні трансляції.
Наприклад у мому випадку службова сторінка icecast відкривається як http://online.fm.stryi.com:8000, а до онлайн-трансляції, джерелом якої є darkice можна підключитись за адресою http://online.fm.stryi.com:8000/Stryi-FM.m3u (бо "Stryi-FM" - назва віртуальної точки монтування, вказана у конфігураційному файлі darkice).
Корисні можливості сервера трансляцій icecast2
-
на сторінці http://сервер:8000 можна бачити скільки людей зараз слухає потік та їх максимальну кількість (пік)
-
на сторінці http://сервер:8000/admin/listmounts.xsl можна побачити дані про клієнтів, які зараз під'єднані (List Clients)
-
а Update Metadata дозволяє вказати "поточну пісню" та "виконавця", які відображаються в програвачах слухачів (цей параметр можна передавати HTTP методом POST, для автоматичної зміни такої інформації)
Ось і все. приємного прослуховування вашим онлайн-слухачам. :)
Факультативно. Створення архіву трансляції.
Припустимо що Вам треба ще й зберігати онлайн-трансляцію у локальний файл. Для радіостанцій (не інтерне, а навіть звичайних) взагалі є така вимога. Та й деколи корисно мати такий архів, щоб при потреб прослухати що транслювалось.
Для цього, найспростіше, скористатись можливістю самого darkice. Додайте в конфігураційний файл таке:
/usr/local/etc/darkice.conf
localDumpFile = /radio_archive/a_current.mp3
Тепер, разом з кодуванням аудіопотоку darkice буде автоматично створювати файл /radio_archive/a_current.mp3 (файл буде в тому форматі, в якому задано формування потоку).
Проте цей файл буде просто постійно зростати в розмірі. Щоб використовувати його з користю треба якось, час від часу, "забирати" його та зберігати з іншою назвою.
Насправді все не так просто. Документація darkice предбачає можливість керування цим файлом, проте якось не до кінця описується принцип роботи. Я знайшов декілька посилань на неіснуючу сторінку Wiki проекту darkice де описувалось як правильно зберігати файли. але саму сторінку знайшов лише у веб-архіві 2007-го року. :)
Отже суть, виявляється, така: darkice створює файл у вказаній вами директорії. Для того щоб файл перейменувався та почав писатись новий треба надіслати процесу сигнал SIGUSR1 (signal 10).
Але (!) назву і шлях до файлу в який треба перейменувати поточний файл, darkice шукає у файлі /tmp/darkice.потік.PID, де:
-
потік - це назва розділу ([icecast2-0], [icecast2-1], [icecast2-2], [icecast2-X])
-
PID - номер запущеного процесу darkice
Приклад:
Darkice запустився процесом під номером 25600 (можна взнати командою "ps | grep darkice"). Ви хочете зберегти файл потоку icecast2-0 у файл з назвою 18.05.09.mp3.
Тоді створіть файл /tmp/darkice.icecast2-0.25600 з таким змістом: "18.05.09.mp3", та надішліть процесу darkice сигнал SIGUSR1:
kill -USR1 25600
Для Linux напевне треба писати "kill -SIGUSR1 25600" чи "kill -s 10 25600".
Тоді, файл вказаний у опції "localDumpFile" перейменується у "18.05.09.mp3" та почне писатись "з нуля".
Скрипт для автоматичної щогодинної архівації трансльованого потоку
Щоб це все трохи автоматизувати я створив простий скрипт, що створює файли з датою та годиною у назві. Якщо його запускати по крону щогодини то отримуємо архів файлів з назвами
-
2009.05.18_15-16.mp3
-
2009.05.18_16-17.mp3
-
2009.05.18_17-18.mp3
-
...
radio_archive.sh
#!/bin/sh
#SYM
#Архів радіотрансляцій
#0 * * * * root /usr/local/bin/radio_archive.sh
PID=`/bin/cat /var/run/darkice.pid`
start_date=`/bin/date -v-1H +%Y.%m.%d_%H`
cur_time=`/bin/date +%H`
#Затираємо "хвости"
/bin/rm /tmp/darkice.icecast2-0.*
#Створюємо новий файл
echo "/radio_archive/${start_date}-${cur_time}.mp3" > /tmp/darkice.icecast2-0.$PID
#Надсилаємо сигнал демону
kill -USR1 $PID
exit 0
Запускайте його сервісом cron, щогодини. Година в якій запуститься скрипт є кінцевою годиною запису. Зверніть увагу на правильний синтаксис "kill -USR1" для Вашої системи (приклади для Linux описані вище). Майте на увазі, що для створення файлу /var/run/darkice.pid треба використовувати скрипт запуску, який його створює (описано вище).
Сподіваюсь що стаття стане комусь в пригоді. Якщо маєте конкретні питання - буду радий відповісти.