Зачастую возникает необходимость принять аудиосигнал с множества несвязанных устройств и выдать полученный сигнал на множество несвязанных акустических систем. Многие делают это через медиаматрицы BiAMP, Kramer в связке с управлением через Kramer, Palantir и т.д., но это оборудование стоит денег, а деньги есть не всегда.
Осмелюсь описать бюджетный вариант, который в базовом функционале не уступает вышеописанным продуктам. А с точки зрения управления может быть более гибок.
В проекте используется 15 медиасерверов (Windows 7), с каждого из которых идёт свой видеоряд отображаемый на плазмах и проекторах, а также аудиопоток, сопровождающий видеоряд. Также имеется 3 акустические системы, на которые аудиопоток можно вывести.
Немного о структуре.
Видеоряд транслируется из серверной комнаты через конверторы DVI и VGA сигналов на оборудование, вынесенное от серверной на расстояние до 50 метров. Использование встроенных или выносных динамиков для трансляции аудиосигнала привело бы в какофонии и невозможности восприятия отображаемого контента. Для воспроизведения звука было решено разделить 15 медиасерверов на 3 группы и коммутировать аудиосигнал на 3 различных акустических системы, территориально приближенных к плазмам и проекторам.
Так как переключением звука нужно управлять удалённо, значит нужно его где-то скоммутировать. Физическая коммутация вещь старая и надёжная, но мы живём в век цифровых технологий. Поэтому для коммутации звука мы будем использовать цифру, а чтобы получить цифровой поток, его нужно откуда-то взять.
Устанавливаем на компьютер драйвера виртуального аудио кабеля.
Данные драйвера представляют собой виртуальную звуковую карту в которую можно отправлять весь звук системы и снимать из неё звуковой поток в цифровом виде при помощи программ.
В нашем случае используется обычный ffmpeg.
Для получения списка аудиоустройств необходимо запустить ffmpeg со следующими ключами:
Устройством с которого мы будем снимать аудиопоток будет «CABLE Output (VB-Audio Virtual ».
В качестве устройства в которое будет выводиться весь звук системы будет «CABLE Input (Virtual Audio Cable)».

Запускаем ffmpeg и транслируем данные в сеть.
В любом месте сети Вы сможете слушать данный поток любым плеером(ffplay, vlc и т.д.). При желании можно менять кодек и битрейт.
Базовая настройка сделана, звук получили, драйвера растиражировали на 15 медиасерверов, получили 15 разных потоков, а теперь возникает вопрос «как же это слушать и коммутировать».
С точки зрения экономии железа и ресурсов можно воспользоваться единственной машиной с некоторым количеством аудиокарт выводящих звук на акустику. Сейчас в достаточной мере на рынке присутствуют различные малогабаритные USB аудиокарты. С точки зрения удобства использования дешевые карты аля CMEDIA не выгодны, потому что не имеют внутри серийных номеров, и определить какая карта после перезагрузки на какой канал стала работать невозможно. Я использовал карты «Creative SB Play!» которые дают довольно хороший звук и имеют возможность идентификации их в системе.
Т.к. при подключении USB audio картам присваиваются динамические номера, для devd был написан набор правил:
Который формирует симлинки на подключенное оборудование в виде "/dev/uaudio.serial.<SerialNumber>", в итоге список устройств выглядит вот так:
Что позволяет однозначно идентифицировать карту и акустическую систему которую она обслуживает.
В лог также заносится информация о происходящем.
С картами мы разобрались. Теперь очередь за вопроизведением всего этого счастья.
Формируем Playlist.xspf:
Копируем дерево lua vlc в /usr/local/www/vlc_http
Плейлист кладём в /usr/local/www/vlc_http/playlists/Playlist.xspf
теперь запускаем пачку cvlc в следующем конфиге:
Далее дело за малым. Взять примеры из http управлялки vlc и сделать свои страницы управления. Благо там сплошной jquery и javascript.
В основном дереве веб сервера формируем страницу где в iframe интегрируем управлялки каждым из поточных проигрывателей и открываем это дело через телефон или планшет. Вся остальная логика управления пишется на html и не представляет большой сложности.
Т.к. мы не завязаны на источники звука, это даёт огромную гибкость в управлении звуковыми потоками. Можно на всю акустику вывести один и тот же поток с любого медиасервера, можно поменять потоки местами и т.д.
Теперь вернёмся к USB аудиокартам, у нас остались микрофонные входы на которые можно подать звук с физических устройств типа проигрывателей, телефонов, микрофонов и т.д. Для подключения к микрофонному входу линейных выходов от проигрывателей необходимо собрать простейший делитель напряжения. Статья на хабре опять же имеется. Входящий сигнал с микрофонного входа так же заводится в поток и броадкастится либо на localhost, либо в сеть.
Вот как-то так. Будут вопросы — пишите.

Осмелюсь описать бюджетный вариант, который в базовом функционале не уступает вышеописанным продуктам. А с точки зрения управления может быть более гибок.
В проекте используется 15 медиасерверов (Windows 7), с каждого из которых идёт свой видеоряд отображаемый на плазмах и проекторах, а также аудиопоток, сопровождающий видеоряд. Также имеется 3 акустические системы, на которые аудиопоток можно вывести.
Немного о структуре.
Видеоряд транслируется из серверной комнаты через конверторы DVI и VGA сигналов на оборудование, вынесенное от серверной на расстояние до 50 метров. Использование встроенных или выносных динамиков для трансляции аудиосигнала привело бы в какофонии и невозможности восприятия отображаемого контента. Для воспроизведения звука было решено разделить 15 медиасерверов на 3 группы и коммутировать аудиосигнал на 3 различных акустических системы, территориально приближенных к плазмам и проекторам.
Так как переключением звука нужно управлять удалённо, значит нужно его где-то скоммутировать. Физическая коммутация вещь старая и надёжная, но мы живём в век цифровых технологий. Поэтому для коммутации звука мы будем использовать цифру, а чтобы получить цифровой поток, его нужно откуда-то взять.
Устанавливаем на компьютер драйвера виртуального аудио кабеля.
Данные драйвера представляют собой виртуальную звуковую карту в которую можно отправлять весь звук системы и снимать из неё звуковой поток в цифровом виде при помощи программ.
В нашем случае используется обычный ffmpeg.
Для получения списка аудиоустройств необходимо запустить ffmpeg со следующими ключами:
C:\Progs\ffmpeg\bin>ffmpeg -list_devices true -f dshow -i dummy [dshow @ 00000000020a77e0] DirectShow video devices [dshow @ 00000000020a77e0] "Logitech HD Webcam C310" [dshow @ 00000000020a77e0] DirectShow audio devices [dshow @ 00000000020a77e0] "Микрофон (HD Webcam C310)" [dshow @ 00000000020a77e0] "CABLE Output (VB-Audio Virtual "
Устройством с которого мы будем снимать аудиопоток будет «CABLE Output (VB-Audio Virtual ».
В качестве устройства в которое будет выводиться весь звук системы будет «CABLE Input (Virtual Audio Cable)».

Запускаем ffmpeg и транслируем данные в сеть.
C:\Progs\ffmpeg\bin>ffmpeg -re -f dshow -i audio="CABLE Output (VB-Audio Virtual " -f mp3 udp://239.1.1.1:5001
ffmpeg version N-49610-gc2dd5a1 Copyright (c) 2000-2013 the FFmpeg developers
built on Feb 5 2013 13:26:02 with gcc 4.7.2 (GCC)
libavutil 52. 17.101 / 52. 17.101
libavcodec 54. 91.100 / 54. 91.100
libavformat 54. 61.104 / 54. 61.104
libavdevice 54. 3.103 / 54. 3.103
libavfilter 3. 35.101 / 3. 35.101
libswscale 2. 2.100 / 2. 2.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 2.100 / 52. 2.100
[dshow @ 00000000024de080] Estimating duration from bitrate, this may be inaccurate
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, dshow, from 'audio=CABLE Output (VB-Audio Virtual ':
Duration: N/A, start: 270550.167000, bitrate: 1411 kb/s
Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Output #0, mp3, to 'udp://239.1.1.1:5001':
Metadata:
TSSE : Lavf54.61.104
Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le -> libmp3lame)
Press [q] to stop, [?] for help
size= 100kB time=00:00:06.37 bitrate= 128.5kbits/s
В любом месте сети Вы сможете слушать данный поток любым плеером(ffplay, vlc и т.д.). При желании можно менять кодек и битрейт.
Базовая настройка сделана, звук получили, драйвера растиражировали на 15 медиасерверов, получили 15 разных потоков, а теперь возникает вопрос «как же это слушать и коммутировать».
С точки зрения экономии железа и ресурсов можно воспользоваться единственной машиной с некоторым количеством аудиокарт выводящих звук на акустику. Сейчас в достаточной мере на рынке присутствуют различные малогабаритные USB аудиокарты. С точки зрения удобства использования дешевые карты аля CMEDIA не выгодны, потому что не имеют внутри серийных номеров, и определить какая карта после перезагрузки на какой канал стала работать невозможно. Я использовал карты «Creative SB Play!» которые дают довольно хороший звук и имеют возможность идентификации их в системе.
Т.к. при подключении USB audio картам присваиваются динамические номера, для devd был написан набор правил:
attach 50 {
match "device-name" "uaudio[0-9]+";
match "sernum" "[0-9A-Za-z]+";
match "mode" "host";
action "logger USB Audio S/N:$sernum is attached";
action "ln -fs /dev/`head -n 1 /tmp/$device-name.dsp` /dev/$device-name.dsp";
action "ln -fs /dev/$device-name.dsp /dev/uaudio.serial.$sernum";
action "rm /tmp/$device-name.dsp";
match "device-name" "uaudio[0-9]+";
match "hubaddr" "[0-9]+";
match "port" "[0-9]+";
match "devaddr" "[0-9]+";
action "echo $device-name at ugen.$port.$devaddr";
action "ln -fs /dev/$device-name.dsp /dev/uaudio.ugen.$port.$devaddr";
};
attach 50 {
match "device-name" "uaudio[0-9]+";
match "sernum" "$";
match "mode" "host";
action "logger USB Audio without serial number is attached";
action "ln -fs /dev/`head -n 1 /tmp/$device-name.dsp` /dev/$device-name.dsp";
action "rm /tmp/$device-name.dsp";
match "device-name" "uaudio[0-9]+";
match "hubaddr" "[0-9]+";
match "port" "[0-9]+";
match "devaddr" "[0-9]+";
action "echo $device-name at ugen.$port.$devaddr";
action "ln -fs /dev/$device-name.dsp /dev/uaudio.ugen.$port.$devaddr";
};
attach 40 {
match "device-name" "pcm[0-9]+";
match "bus" "uaudio[0-9]+";
action "logger Found $device-name at $bus. Saving.";
action "echo -n $device-name | sed -E 's/pcm/dsp/' >> /tmp/$bus.dsp";
};
detach 40 {
match "device-name" "uaudio[0-9]+";
match "bus" "uhub[0-9]+";
action "logger Dropping dsp symlink for $device-name";
action "find /dev/ -type l -ls | awk '$$NF ~ /$device-name\./ {print $(NF-2)}' | xargs rm";
action "rm -f /dev/$device-name.dsp";
};
notify 50 {
match "type" "DETACH";
match "mode" "host";
match "sernum" "[0-9A-Za-z]+";
action "logger USB Audio S/N:$sernum detached";
};
Который формирует симлинки на подключенное оборудование в виде "/dev/uaudio.serial.<SerialNumber>", в итоге список устройств выглядит вот так:
lrwxr-xr-x 1 root wheel 16 May 15 09:27 /dev/uaudio.serial.131014000129 -> /dev/uaudio1.dsp lrwxr-xr-x 1 root wheel 16 May 15 09:23 /dev/uaudio.serial.140210000BB2 -> /dev/uaudio0.dsp lrwxr-xr-x 1 root wheel 16 May 15 09:23 /dev/uaudio.ugen.5.6 -> /dev/uaudio0.dsp lrwxr-xr-x 1 root wheel 16 May 15 09:27 /dev/uaudio.ugen.5.7 -> /dev/uaudio1.dsp lrwxr-xr-x 1 root wheel 16 May 15 08:37 /dev/uaudio.ugen.5.8 -> /dev/uaudio2.dsp lrwxr-xr-x 1 root wheel 9 May 15 09:23 /dev/uaudio0.dsp -> /dev/dsp6 lrwxr-xr-x 1 root wheel 9 May 15 09:27 /dev/uaudio1.dsp -> /dev/dsp7 lrwxr-xr-x 1 root wheel 9 May 15 08:37 /dev/uaudio2.dsp -> /dev/dsp8
Что позволяет однозначно идентифицировать карту и акустическую систему которую она обслуживает.
В лог также заносится информация о происходящем.
May 15 08:35:31 franky zhecka: USB Audio S/N:131014000129 is attached May 15 08:35:36 franky zhecka: Found pcm8 at uaudio2. Saving. May 15 08:35:36 franky kernel: uaudio2: <vendor 0x0d8c Generic USB Audio Device, class 0/0, rev 1.10/1.00, addr 8> on usbus5 May 15 08:35:36 franky kernel: uaudio2: Play: 44100 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:35:36 franky kernel: uaudio2: Play: 48000 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:35:36 franky kernel: uaudio2: Play: 44100 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:35:36 franky kernel: uaudio2: Record: 44100 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:35:36 franky kernel: uaudio2: Record: 48000 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:35:36 franky kernel: uaudio2: Record: 44100 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:35:36 franky kernel: uaudio2: No MIDI sequencer. May 15 08:35:36 franky kernel: pcm8: <USB audio> on uaudio2 May 15 08:35:36 franky kernel: uaudio2: HID volume keys found. May 15 08:35:37 franky zhecka: USB Audio without serial number is attached May 15 08:37:11 franky zhecka: Dropping dsp symlink for uaudio2 May 15 08:37:11 franky kernel: uaudio2: at uhub6, port 3, addr 8 (disconnected) May 15 08:37:15 franky zhecka: Found pcm8 at uaudio2. Saving. May 15 08:37:15 franky kernel: uaudio2: <vendor 0x0d8c Generic USB Audio Device, class 0/0, rev 1.10/1.00, addr 8> on usbus5 May 15 08:37:15 franky kernel: uaudio2: Play: 44100 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:37:15 franky kernel: uaudio2: Play: 48000 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:37:15 franky kernel: uaudio2: Play: 44100 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:37:15 franky kernel: uaudio2: Record: 44100 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:37:15 franky kernel: uaudio2: Record: 48000 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:37:15 franky kernel: uaudio2: Record: 44100 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 08:37:15 franky kernel: uaudio2: No MIDI sequencer. May 15 08:37:15 franky kernel: pcm8: <USB audio> on uaudio2 May 15 08:37:15 franky kernel: uaudio2: HID volume keys found. May 15 08:37:15 franky zhecka: USB Audio without serial number is attached May 15 09:17:56 franky zhecka: USB Audio S/N:140210000BB2 detached May 15 09:17:56 franky kernel: uaudio0: at uhub7, port 2, addr 6 (disconnected) May 15 09:17:56 franky zhecka: USB Audio S/N:140210000BB2 detached May 15 09:17:56 franky zhecka: Dropping dsp symlink for uaudio0 May 15 09:23:36 franky zhecka: Found pcm6 at uaudio0. Saving. May 15 09:23:36 franky kernel: uaudio0: <vendor 0x041e product 0x30d3, class 0/0, rev 1.10/1.00, addr 6> on usbus5 May 15 09:23:36 franky kernel: uaudio0: Play: 44100 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 09:23:36 franky kernel: uaudio0: Play: 48000 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 09:23:36 franky kernel: uaudio0: Play: 44100 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 09:23:36 franky kernel: uaudio0: Record: 44100 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 09:23:36 franky kernel: uaudio0: Record: 48000 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 09:23:36 franky kernel: uaudio0: Record: 44100 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer. May 15 09:23:36 franky kernel: uaudio0: No MIDI sequencer. May 15 09:23:36 franky kernel: pcm6: <USB audio> on uaudio0 May 15 09:23:36 franky kernel: uaudio0: HID volume keys found. May 15 09:23:36 franky zhecka: USB Audio S/N:140210000BB2 is attached May 15 09:23:38 franky zhecka: USB Audio S/N:131014000129 detached May 15 09:23:38 franky kernel: uaudio1: at uhub7, port 4, addr 7 (disconnected) May 15 09:23:38 franky zhecka: USB Audio S/N:131014000129 detached May 15 09:23:38 franky zhecka: Dropping dsp symlink for uaudio1
С картами мы разобрались. Теперь очередь за вопроизведением всего этого счастья.
Формируем Playlist.xspf:
<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/" xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/">
<title>AudioStreams</title>
<trackList>
<track>
<title>TV 1</title>
<location>udp://@239.1.1.1:5001</location>
<extension application="http://www.videolan.org/vlc/playlist/0">
<vlc:id>1</vlc:id>
<vlc:option>input-repeat=-1</vlc:option>
</extension>
</track>
<track>
<title>TV 2</title>
<location>udp://@239.1.1.2:5001</location>
<extension application="http://www.videolan.org/vlc/playlist/0">
<vlc:id>2</vlc:id>
<vlc:option>input-repeat=-1</vlc:option>
</extension>
</track>
<track>
<title>TV 3</title>
<location>udp://@239.1.1.3:5001</location>
<extension application="http://www.videolan.org/vlc/playlist/0">
<vlc:id>3</vlc:id>
<vlc:option>input-repeat=-1</vlc:option>
</extension>
</track>
</trackList>
</playlist>
Копируем дерево lua vlc в /usr/local/www/vlc_http
Плейлист кладём в /usr/local/www/vlc_http/playlists/Playlist.xspf
теперь запускаем пачку cvlc в следующем конфиге:
vlc -vvv --sout-transcode-venc none --network-caching 50 --sout-mux-caching 50 -Aoss --oss-audio-device=/dev/uaudio.serial.131014000129 -I http --http-src=/usr/local/www/vlc_http --http-host=192.168.5.2 --http-port=8101 --http-password=mypass1 /usr/local/www/vlc_http/playlists/Playlist.xspf vlc -vvv --sout-transcode-venc none --network-caching 50 --sout-mux-caching 50 -Aoss --oss-audio-device=/dev/uaudio.serial.140210000BB2 -I http --http-src=/usr/local/www/vlc_http --http-host=192.168.5.2 --http-port=8102 --http-password=mypass1 /usr/local/www/vlc_http/playlists/Playlist.xspf
Далее дело за малым. Взять примеры из http управлялки vlc и сделать свои страницы управления. Благо там сплошной jquery и javascript.
В основном дереве веб сервера формируем страницу где в iframe интегрируем управлялки каждым из поточных проигрывателей и открываем это дело через телефон или планшет. Вся остальная логика управления пишется на html и не представляет большой сложности.
Т.к. мы не завязаны на источники звука, это даёт огромную гибкость в управлении звуковыми потоками. Можно на всю акустику вывести один и тот же поток с любого медиасервера, можно поменять потоки местами и т.д.
Теперь вернёмся к USB аудиокартам, у нас остались микрофонные входы на которые можно подать звук с физических устройств типа проигрывателей, телефонов, микрофонов и т.д. Для подключения к микрофонному входу линейных выходов от проигрывателей необходимо собрать простейший делитель напряжения. Статья на хабре опять же имеется. Входящий сигнал с микрофонного входа так же заводится в поток и броадкастится либо на localhost, либо в сеть.
Вот как-то так. Будут вопросы — пишите.

