Хочу поділитись з Вами досвідом встановлення сервера трансляції 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 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
[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 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#!/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. Я не буду цитувати його повністю. Зверніть увагу на таке:
<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. Додайте в конфігураційний файл таке:
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 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/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 треба використовувати скрипт запуску, який його створює (описано вище).
Сподіваюсь що стаття стане комусь в пригоді. Якщо маєте конкретні питання – буду радий відповісти.
