Делаем медиаматрицу на коленке

Зачастую возникает необходимость принять аудиосигнал с множества несвязанных устройств и выдать полученный сигнал на множество несвязанных акустических систем. Многие делают это через медиаматрицы BiAMP, Kramer в связке с управлением через Kramer, Palantir и т.д., но это оборудование стоит денег, а деньги есть не всегда.Осмелюсь описать бюджетный вариант, который в базовом функционале не уступает вышеописанным продуктам. А с точки зрения управления может быть более гибок.В проекте используется 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)».bb14697f4e990ba27088244bcf2b2204.png

Запускаем 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 © 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.», в итоге список устройств выглядит вот так

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 Что позволяет однозначно идентифицировать карту и акустическую систему которую она обслуживает.С картами мы разобрались. Теперь очередь за вопроизведением всего этого счастья.Формируем Playlist.xspf:

AudioStreams TV 1 udp://@239.1.1.1:5001 1 input-repeat=-1 TV 2 udp://@239.1.1.2:5001 2 input-repeat=-1 TV 3 udp://@239.1.1.3:5001 3 input-repeat=-1 Копируем дерево 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, либо в сеть.

Вот как-то так. Будут вопросы — пишите.© Aborche 2014cff19a9b6d0354bbc4d1a45beda58acf.jpg

© Habrahabr.ru