IceCast настройка - сетевое вещание

Материал из rrv-wiki
Перейти к навигации Перейти к поиску

Появилась задача воспроизводить в локальной сети аудио поток местной радиостанции, а так же осуществлять ее запись. Для этоно на сервер FreeBSD была установлена звуковая карта и IceCast и все заработало через 30 мин. Как я это делал:

Описание из ru.wikipedia.org

Icecast — свободное ПО для организации потокового цифрового аудиовещания. Его поддержкой занимается Xiph.org Foundation.

Технические детали

Icecast является серверной программой, которая может осуществлять раздачу цифровых потоков различных форматов, таких как Ogg Vorbis, MPEG Audio Layer III (MP3), Theora, Advanced Audio Coding(AAC), AACplus и Nullsoft Streaming Video.

Собственно передача данных осуществляется по стандартному протоколу HTTP, либо по протоколу SHOUTcast.

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

Внешние ссылки

Официальный сайт Icecast’а

Установка

Настраиваем звуковую карту

Выполним:

# kldload snd_driver

Для закрепления эффекта, добавим в файл /boot/loader.conf

#Если карточка USB то добавить следующую строчку
snd_uaudio_load="YES"
sound_load="YES"
# Здесь можно заменить на соответствующий драйвер
snd_driver_load="YES"

Подробности здесь.

Создаем файл автозагрузки для настройки микшера (Если кто знает способ лучше пишите)

# ls -la /usr/local/etc/rc.d/000.mixer.sh

-rwxr--r--  1 root  wheel  174 Apr 24 10:08 /usr/local/etc/rc.d/000.mixer.sh
#cat /usr/local/etc/rc.d/000.mixer.sh

#!/bin/sh
su root -c '/usr/sbin/mixer rec 75 1>/dev/null 2>&1'
su root -c '/usr/sbin/mixer igain 75 1>/dev/null 2>&1'
su root -c '/usr/sbin/mixer =rec line 1>/dev/null 2>&1'
# если нужен еще одно устройство записи то добавляем строчку:
cat /usr/local/etc/rc.d/000.mixer.sh > /dev/dsp0.1
# и так далее, почему то sysctl hw.snd.pcm0.vchans=4 не работает, видимо в 7 фряхе как то по другому, если знаете поправьте

Устанавливаем IceCast

Найдем в портах:

# cd /usr/ports/ && make search name=^icecast2

установим:

# cd /usr/ports/audio/icecast2
# make install clean

Настраиваем IceCast

Для начала:

# cd /usr/local/etc && cp icecast.xml.sample icecast.xml

Весь конфигурационный файл приводить не буду, ограничусь нужными нам выдержками файла icecast.xml.
Секция ограничений:

   <limits>
       <clients>100</clients> <!-- Кол-во клиентов -->
       <sources>4</sources> <!-- Кол-во источников, то есть максимальное кол-во максимальное кол-во потоков -->
       <threadpool>5</threadpool> 
       <queue-size>524288</queue-size> 
       <client-timeout>30</client-timeout> 
       <header-timeout>15</header-timeout> 
       <source-timeout>10</source-timeout> 
       <!-- If enabled, this will provide a burst of data when a client
            first connects, thereby significantly reducing the startup
            time for listeners that do substantial buffering. However,
            it also significantly increases latency between the source
            client and listening client.  For low-latency setups, you
            might want to disable this. Эта опция значительно сокращает 
            время первого подключения клиентов, но требует качественного 
            подключения, в пративном случае, опцию лучше отключить -->
       <burst-on-connect>1</burst-on-connect>
       <!-- same as burst-on-connect, but this allows for being more
            specific on how much to burst. Most people won't need to
            change from the default 64k. Applies to all mountpoints  -->
       <burst-size>65535</burst-size>
   </limits>

Секция авторизации, пароли меняем по вкусу:

    <authentication>
       <!-- Sources log in with username 'source' (пароль на исходный поток)-->
       <source-password>hackme</source-password>
       <!-- Relays log in username 'relay' (пароль на relay)-->
       <relay-password>hackme</relay-password>

       <!-- Admin logs in with the username given below  (имя пользователя и пароль админа)-->
       <admin-user>admin</admin-user>
       <admin-password>hackme</admin-password>
   </authentication>

Настраиваем сетевые параметры:

   <!-- This is the hostname other people will use to connect to your server.
   It affects mainly the urls generated by Icecast for playlists and yp
    listings. (имя нашего хоста, порт и привязка к адресу если нужна) -->
   <hostname>localhost</hostname>
   <!-- You may have multiple <listener> elements -->
   <listen-socket>
       <port>8000</port>
       <!-- <bind-address>127.0.0.1</bind-address> -->
       <!-- <shoutcast-mount>/stream</shoutcast-mount> -->
   </listen-socket>
   <!--
   <listen-socket>
       <port>8001</port>
   </listen-socket>
   -->

В секции путей меняем только путь к логам :

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

И создадим папку логов:

# mkdir -p /var/log/icecast && chown -R nobody:nobody /var/log/icecast

Cекции логов:

   <logging>
       <accesslog>access.log</accesslog>
       <errorlog>error.log</errorlog>
       <!-- <playlistlog>playlist.log</playlistlog> -->
       <loglevel>2</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
       <logsize>10000</logsize> <!-- Max size of a logfile -->
       <!-- If logarchive is enabled (1), then when logsize is reached
            the logfile will be moved to [error|access|playlist].log.DATESTAMP,
            otherwise it will be moved to [error|access|playlist].log.old.
            Default is non-archive mode (i.e. overwrite)
       -->
       <!-- <logarchive>1</logarchive> -->
   </logging>

И запускать сервер будем от пользователя nobody:

   <security>
       <chroot>0</chroot>
       <changeowner>
           <user>nobody</user>
           <group>nogroup</group>
       </changeowner>
   </security>

С настройкой сервера IceCast закончили.
Осталось только настроить автозапуск сервера IceCast, добавим в файл /etc/rc.conf:

icecast_enable="YES"

И запустим сервер:

# /usr/local/etc/rc.d/icecast2 start

Проверяем файл /var/log/icecast/error.log на предмет сообщений об ошибках. Затем проверяем, стартовал ли сервер:

# ps waux | grep icecast
nobody 67309  0.0  0.4  8740  3972  p9  S    11:37AM   0:00.06 /usr/local/bin/icecast -c /usr/local/etc/icecast.xml -b
# netstat -na | grep -i listen | grep 8000
tcp46      0      0  *.8000                 *.*                    LISTEN

Как видим, что процесс висит и порт слушает :)

Устанавливаем Darkice

Для создания аудио потока со звуковой карты на сервер IceCast воспользуемся программой Darkice.

# cd /usr/ports/ && make search name=darkice
# cd /usr/ports/audio/darkice && make install clean

Выбираем параметры установки, нас пока интересует mp3 для высоких скоростей и низких скоростей рекомендую использовать FAAC, что бы использовать протокол aacp :

  ┌────────────────────────────────────────────────────────────────────┐
  │                     Options for darkice 0.19                       │
  │ ┌────────────────────────────────────────────────────────────────┐ │
  │ │              [ ] VORBIS   Ogg Vorbis support                   │ │
  │ │              [X] LAME     LAME support for MP3                 │ │
  │ │              [ ] TWOLAME  TwoLAME support for MP2              │ │
  │ │              [X] FAAC     FAAC support for AAC                 │ │
  │ │              [ ] JACK     Jack support                         │ │

Копируем пример конфигурационного файла:

# cd /usr/local/etc/ && cp darkice.cfg darkice.cfg.orig

И правим darkice.cfg:

# this section describes general aspects of the live streaming session
[general]
duration        = 0        # (Время проигрывания 0-не ограничено) duration of encoding, in seconds. 0 means forever
bufferSecs      = 2         # (Буфер в секундах) size of internal slip buffer, in seconds
reconnect       = yes       # (Автоматическое переподключение)reconnect to the server(s) if disconnected 

 # this section describes the audio input that will be streamed
[input]
device          = /dev/dsp0.0  # (Звуковая карта)OSS DSP soundcard device for the audio input
sampleRate      = 44100     # (Частота дискретизации) sample rate in Hz. try 11025, 22050 or 44100
bitsPerSample   = 16        # (Динамический диапазон 16 бит) bits per sample. try 16
channel         = 2         # (2 -стерео) channels. 1 = mono, 2 = stereo 
# this section describes a streaming connection to an IceCast2 server
# there may be up to 8 of these sections, named [icecast2-0] ... [icecast2-7]
# these can be mixed with [icecast-x] and [shoutcast-x] sections
[icecast2-0]
bitrateMode     = abr       # (abr-Переменный битрейт, для постоянного битрейта cbr)average bit rate
format          = mp3    # (Формат потока)format of the stream: ogg vorbis
bitrate         = 128        # (Битрейт посылаемого на сервер IceCast потока)bitrate of the stream sent to the server
server          = localhost 
                            # (Имя сервера)host name of the server
port            = 8000      # (Порт)port of the IceCast2 server, usually 8000
password        = hackme    # (Пароль, который указывали в теге <source-password>hackme</source-password> для IceCast2)source password to the IceCast2 server
mountPoint      = sample128  # (точка монтировани, то что будет видно для клиента при подключении к серверу) mount point of this stream on the IceCast2 server
name            = DarkIce Trial 128 
                             #  (Имя потока) name of the stream
description     = This is only a trial
                            # (Комментарий потока) description of the stream
url             = http://www.yourserver.com
                            # URL related to the stream
genre           = my own    # (Жанр потока (pop, rock,....)) genre of the stream
public          = yes       # advertise this str

Если нам нужен поток с другими параметрами, то добавляем еще одну секцию в файл darkice.cfg:

[icecast2-1]
bitrateMode     = abr
format          = mp3
bitrate         = 256
server          = localhost 
port            = 8000 
password        = hackme
mountPoint      = sample256 
name            = DarkIce Trial 256
description     = This is only a trial
url             = http://www.yourserver.com
genre           = my own
public          = yes

Теперь скорость 32кБит/с, то добавляем еще одну секцию в файл darkice.cfg:

[icecast2-2]
bitrateMode     = abr
format          = aacp
bitrate         = 32
channel         = 2
server          = localhost 
port            = 8000 
password        = hackme
mountPoint      = sample32 
name            = DarkIce Trial 32
description     = This is only a trial
url             = http://www.yourserver.com
genre           = my own
public          = yes

Для запуска в автоматическом режиме можно воспользоваться скриптом /usr/local/etc/rc.d/darkice:

#!/bin/sh
       case $1 in
       [Ss][Tt][Oo][Pp])
               /usr/bin/killall darkice && echo "darkice stoped"
               ;;
       [Ss][Tt][Aa][Rr][Tt])
               /usr/bin/su darkice -c '/usr/local/bin/darkice -c /usr/local/etc/darkice.cfg & 1>/dev/null 2>&1' && echo "darkice startted"
               ;;
       *)
               echo "Use $0 [start|stop]"
               ;;
       esac

Теперь, если нам требуется брать аудио поток еще с нескольких звуковых карт, то необходимо создать новый конфигурационный файл darkice.cfg, например 2.darkice.cfg, изменить параметр device, например:

device          = /dev/dsp1.0

и создать еще один скрипт запуска darkice с использования нового конфигурационного файла.
Не забудьте увеличить <sources>4</sources> в icecast.xml!


ВНИМАНИЕ!!! Смена bitrate sampleRate bitsPerSample channel в выходном потоке

Актуально для Linux (alsa debian) во FreeBSD тоже работает, просто в Linux я не смог победить по быстрому создание алиасов звуковой карты, но наткнулся, что это можно поменять в выходном потоке

[icecast2-3]
bitrateMode     = abr       # average bit rate                                                                                     
format          = mp3    # format of the stream: ogg vorbis                                                                        
bitrate         = 8        # bitrate of the stream sent to the server                                                              
sampleRate      = 22050     # sample rate in Hz. try 11025, 22050 or 44100                                                         
bitsPerSample   = 16        # bits per sample. try 16                                                                              
channel         = 1         # channels. 1 = mono, 2 = stereo                                                                       
                                                                                                                                   
server          = 127.0.0.1 # host name of the server                                                                              
port            = 8000      # port of the IceCast2 server, usually 8000                                                            
password        = hackme   # source password to the IceCast2 server                                                            
mountPoint      = sample8  # mount point of this stream on the IceCast2 server                                                    
name            = DarkIce Trial 8kHz # name of the stream                                                                                   

P.S. Для создания многопоточного звука со звуковой карты (один вход карты на несколько программ) читаем про dsnoop и /etc/asound.conf

Записываем аудио mp3 поток

Устанавливаем:

# cd /usr/ports/audio/streamripper && make install clean
                              ┌────────────────────────────────────────────────────────────────────┐
                              │                 Options for streamripper 1.63.5                    │
                              │ ┌────────────────────────────────────────────────────────────────┐ │
                              │ │          [ ] FAAD    Include FAAD mpeg4 codec support          │ │
                              │ │          [ ] VORBIS  Include Ogg Vorbis codec support          │ │

Пишем скрипт rec.sh вида:

#!/bin/sh
DATE=`date +%Y-%m-%d_%H-%M`
/usr/local/bin/streamripper http://127.0.0.1:8000/sample128m3u -a /home/air/$DATE.mp3 -s -z -l 3720 -i --quiet && rm /home/air/$DATE.cue
/usr/bin/find /home/air/ -name "*.mp3" -ctime +35d -delete # Удаление файлов старше 35 дней

Здесь записывается поток с сервера по адресу http://127.0.0.1:8000/sample128m3u в папку /home/air/ в файл с именем вида 2008-04-25_10-00 (ГОД-МЕСЯЦ-ДЕНЬ_ЧАС-МИНУТА). Записывает в течении 3720 сек, что составляет один час и две минуты (учтите что поток выдается с задержкой).

Все, запихиваем скрипт в cron на запуск раз в час и запись готова.


IceCast Currently playing (что играет)

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

Я делал на linux-е (не на FreeBSD), так на сервере стоит linux.

Нам потребуется: 1. Файл содержащий название текущей песни, у меня Djin создает файл current.xml пример содержания:
<?xml version="1.0" encoding="windows-1251" ?><ELEM_LIST><ELEM PLAYER_NAME="океиеп 3" SCH_ID="0" SCH_NAME="Default" STATUS="playing"><START_TIME>16:14:06</START_TIME><START_DATE>2016-04-08</START_DATE><BLK_TYPE>л</BLK_TYPE><TYPE></TYPE><NAME>COLDPLAY ft BEYONCE - Hymn For The Weekend</NAME><ARTIST>Coldplay Feat. Beyonce</ARTIST><AUTHOR></AUTHOR><ALBUM></ALBUM><DBID></DBID><FILE_NAME>\\Server\djinn\SND\Coldplay_Feat_Beyonce-Hymn_For_The_Weekend_256.mp3</FILE_NAME><DURATION>00:03:46</DURATION></ELEM><ELEM PLAYER_NAME="океиеп 3" SCH_ID="0" SCH_NAME="Default" STATUS="preloaded"><BLK_TYPE>п</BLK_TYPE><TYPE></TYPE><NAME>бШАНП пЕДЮЙЖХХ кюимеп</NAME><ARTIST></ARTIST><AUTHOR></AUTHOR><ALBUM></ALBUM><DBID></DBID><FILE_NAME>\\Server\djinn\SND\бШАНП пЕДЮЙЖХХ кюимеп.wav</FILE_NAME><DURATION>00:00:03</DURATION></ELEM><ELEM PLAYER_NAME="океиеп 3" SCH_ID="0" SCH_NAME="Default" STATUS="preloaded"><BLK_TYPE>п</BLK_TYPE><TYPE></TYPE><NAME>v6-2</NAME><ARTIST></ARTIST><AUTHOR></AUTHOR><ALBUM></ALBUM><DBID></DBID><FILE_NAME>\\Server\djinn\SND\v6-2.wav</FILE_NAME><DURATION>00:00:08</DURATION></ELEM></ELEM_LIST>

Нас интересует кусок: <NAME>бШАНП пЕДЮЙЖХХ кюимеп</NAME>

2. Меняем кодировку, нам нужен utf-8, затем вырезаем нужный кусок файла. Затем проверяем есть ли в файле последовательность символов пробел минус пробел " - " (так обозначены все музыкальные треки "имя - исполнитель"), если этого нет, не выводим название (это джингл, подложка или рекламный ролик), затем добавляем название радиостанции в URL Encoding (можно сделать [тут]). В конце обработки меняем все пробелы на %20 (если есть другие спецсимволы в названиях песен или кодируем или фильтруем).

3. Записываем на сервер icecast2 через wget

Итоговый скрипт IceCast Currently playing

#!/bin/sh

NAME=""
NAME=`cat /home/root/xml/current.xml | /usr/bin/iconv -c -f cp1251 -t utf-8 \
| /usr/bin/awk 'BEGIN{FS="<.?NAME>"}{print $2}' \
| /usr/bin/awk '{if ($0 ~ / - /) print $0"%20%E2%80%94%20"; }'| /bin/sed "s/ /%20/g"`
NAME=${NAME}"%D0%9A%D0%B0%D0%BA%20%D0%B1%D1%8B%20%D0%A0%D0%B0%D0%B4%D0%B8%D0%BE"
/usr/bin/wget -q -o /dev/null -O /dev/null \
http://admin:hackme@online.rrv.ru:8000/admin/metadata?mount=/kakbyradio\&mode=updinfo\&song=${NAME}

В общем идея понятна, главная часть скрипта это вызов url, тут:

  • hackme - пароль
  • online.rrv.ru - имя icecast сервера
  • /kakbyradio - Mount Point


Устал писать :)