Видеонаблюдение через интернет в веб-браузере

AVReg 5: захват и запись звука с микрофонов и USB-камер.

Устарело.

Преамбула.

Ниже описывается решение, позволяющее обеспечить захват и запись аналогового аудио:

  • с линейных и микрофонных входов звуковых плат,
  • аудиовходов плат видеозахвата (alsa-совмесимых),
  • микрофонов USB-камер.

Несмотря на то что это решение по сути „костыль”, оно достаточно надёжное и очень гибкое, т.к. позволяет записывать аудио с микрофона физически подключенного не только к локальному, но и к любому компьютеру или Wi-Fi роутеру в сети, а также программно обрабатывать звук (громкость, нормализация и т.п.).

Суть решения

AVReg 5 (демон avregd_5.x) не умеет напрямую работать с локальными аудио-устройствами (= ALSA-устройствами, в linux), но он может принимать по http/tcp аудиопотоки в форматах pcm, g.726 и AAC(rtp внутри http).

Поэтому, нужно просто найти набор програм, которые обеспечат захват аудио с ALSA-аудиоустройств и трансляцию аудиопотока в понятном avregd формату по протоколу tcp.

Записывающие ALSA-устройства.

Первая ваша задача - определить alsa-имя для ссылки на микрофон или линейный вход, которое (имя) представляет собой строку «hw:{CARD},{DEVICE}», где {CARD} и {DEVICE} нужно заменить на цифры (см. ниже) или симвлольные идентификаторы (не рассматривал).

Универсальных советов не бывает, поэтому приведём конкретный пример, чтобы была понятна логика действий.

Для этого мы будем использовать информацию из /proc/asound/, как наиболее достоверную, т.к. она формируется непосредственно alsa-драйверами.

$ cat /proc/asound/cards
 0 [Intel          ]: HDA-Intel - HDA Intel
                      HDA Intel at 0xf9ff8000 irq 22
 1 [U0x46d0x8d7    ]: USB-Audio - USB Device 0x46d:0x8d7
                      USB Device 0x46d:0x8d7 at usb-0000:00:1d.1-2, full speed

Отсюда ясно что можно подставлять в значение {CARD}:

  • 0 (hw:0,*) - это встроенная HDA Intel (на чипе ALC1200),
  • 1 (hw:1,*) - аудиоустройство USB-камеры (Logitech).

Теперь осталось определится с {DEVICE}.

$ cat /proc/asound/devices | grep capture
  4: [ 0- 2]: digital audio capture
  6: [ 0- 1]: digital audio capture
  8: [ 0- 0]: digital audio capture
 11: [ 1- 0]: digital audio capture

Абсолютно ясно стало только с USB-камерой, т.к. у неё только один микрофон, и alsa-имя однозначно получается как «hw:1,0».

Со встроенной ALC1200 сложнее, у неё аз 3 порта ввода (записи): 2,1 и 0 (вторая колонка цифр внутри квадратных скобок).

$ cat /proc/asound/pcm 
00-00: ALC1200 Analog : ALC1200 Analog : playback 1 : capture 1
00-01: ALC1200 Digital : ALC1200 Digital : playback 1 : capture 1
00-02: ALC1200 Analog : ALC1200 Analog : capture 1
01-00: USB Audio : USB Audio : capture 1

Анализируем вторую колонку цифр. Сразу отбросим порт 01 т.к. он цифровой «ALC1200 Digital» (к нему микрофон не прицепишь), а нам нужен аналоговый вход. Остались 02 (hw:0,2) и 00 (hw:0,0). Соответствие физическим разъёмам и наименованием регулятором громкости в alsamixer мы определили уже опытным путём.

Итого, получилось:

  • «hw:0,2» - микрофон со разъёмом на передней панели системного блока;
  • «hw:1,0» - микрофон USB-камеры.

Проверяем, сначала записываем а затем проигрываем звук с USB-камеры:

$ arecord -D hw:1,0 -f S16_LE /tmp/usb.ogg
CTRL-C
$ aplay /tmp/usb.ogg

, а теперь с микрофона, подключенного к звуковой плате:

$ arecord -D hw:0,2 -c 2 -f S16_LE /tmp/hda.ogg
CTRL-C
$ aplay /tmp/hda.ogg

Настраивайте громкость тем чем привыкли или alsamixer (запускать в терминале).

Захват аудио и трансляция по сети.

Ниже будет рассмотрен случай localhost↔localhost, если компьютер источник аудио и сервер AVReg - разные хосты, вместо localhost нужно подставлять IP-шники соответствующих компьютеров.

Настройки аудио-трансляции (передача)

Битрейт аудио-потока будет 128kbit/sec. Фактический сетевой трафик будет несколько больше, за счёт использования TCP.

Gstreamer

Если у вас установлена графическая оболочка с Гномом (и видеопроигрывателем Totem), скорее всего все необходимые gstreamer компоненты уже установлены, если нет - выполните в терминале:

$ sudo apt-get install gstreamer-tools \
                       gstreamer0.10-alsa \
                       gstreamer0.10-plugins-base \
                       gstreamer0.10-ffmpeg \
                       gstreamer0.10-plugins-good \
                       gstreamer0.10-plugins-ugly

На компьютере, куда подключен микрофон (к звуковой плате и/или плате видеозахвата, поддерживаемая alsa) или установлена USB-камера:

$ gst-launch alsasrc device='hw:0,2' ! \
  volume volume=1.5 ! rgvolume ! audioconvert ! audioresample ! \
  audio/x-raw-int,channels=1,width=8,depth=8,rate=16000 ! level ! \
  tcpserversink host="localhost" port=12345

netcat

Ниже приводим 2 рецепта с netcat-ом, т.к. пакетов мультимедийного фреймворка Gstreamer может и не быть для маршрутизаторов на OpenWRT/DD-WRT/etc.

установка классического (не openbsd!) netcat

$ sudo apt-get install netcat-traditional

Эта командой (см. ниже) будет запущен tcp сервер на интерфейсе с адресом АДРЕС на tcp-порту ПОРТ и который будет отдавать подключившемуся клиенту stdout-вывод команды КОМАНДА.

man nc

$ nc -l АДРЕС -p ПОРТ -c 'КОМАНДА'
ffmpeg

установка ffmpeg

$ sudo apt-get install ffmpeg

Перенаправляем аудио в сеть по tcp:

man ffmpeg или ffmpeg -help

$ nc -l localhost -p 12345 \
     -c 'ffmpeg -f alsa -ac 2 -i hw:0,2 \
     -vol 384 -ac 1 -acodec pcm_s8 -ar 16000 -ab 64000 -f u8 -'
sox

установка sox

$ sudo apt-get install sox

Перенаправляем аудио в сеть по tcp:

man sox

$ nc -l localhost -p 12345 \
     -c 'sox -q -t alsa hw:0,2 -1 -c 1 -t raw - gain -1 rate -I 16000'

Настройки AVReg (приём и запись)

В веб-интерфейсе, в настройках камеры определите следующие параметры прим.: в кавычках показаны название разделов параметров):

«Захват»
   cam_type = netcam
   -> «ip-камеры»
      InetCam_IP = localhost или ip-адрес компьютера с которого вещает аудио
      -> «протокол «http://»
         InetCam_http_port = номер tcp порта, c которого раздаётся аудио, см. ниже
         -> «аудио»
            A.http_get = /
            A.force_fmt = pcm_u8  (!!! так и только так !!!)
«Запись»
   -> «аудио»
      A.save_fmt = mp2 или ogg/flac (!!! определить явно !!!)

Приём и проигрывание на клиенте в реальном времени

Если нужно прослушивать аудио с сервера (удалённого компьютера) на клиенте, то предлагаем решение на Gstreamer.

$ gst-launch tcpclientsrc host="xxx.xxx.xxx.xxx" port=N ! \
     audio/x-raw-int,channels=1,width=8,depth=8,rate=16000,signed=true ! \
     alsasink

Примечание:

  • значения параметров host и port плагина tcpclientsrc нужно указывать как имя хоста(или ip-адрес) и номер tcp-порта передатчика (сервера),
  • если передатчик и приёмник один и тот же компьютер (host=localhost) - может наблюдаться сильный эффект эха.

Скрипт в автозагрузку.

Прежде всего создайте исполняемый (права 0755) скрипт с именем «/usr/local/bin/audio2net.sh», содержимое которого скопируйте ниже.

#!/bin/sh
 
BACKEND="$1" # программа для захвата аудио, один из: Gstreamer, FFMEG или SOX
 
EXIT_FILE="/var/run/audio.stop" # файл, который нужно создать для корректного
                                # завершения скрипта командой kill
 
# на каком интерфейсе и tcp-порту слушать входящие запросы от avregd
: ${MYHOST:="localhost"}
: ${MYPORT:=12345}
 
# Alsa-имя аудио-устройства к которому подключен микрофон
: ${ALSADEV:="hw:0,2"}
 
: ${FFCHAN:=2}       # кол-во каналов для захвата ffmpeg,
                     #   для многих звукашек нужно поставить 2
                     #   для моно-микрофона USB-камеры - 1
 
# коэф-ты програмного усиления уровня для FFMPEG, SOX и GSTREAMER, соответственно:
: ${FFVOLUME:="384"} # 256=normal
: ${SOXGAIN:="+2"}   # A power gain in dB.  Zero gives no gain;
                     #  less than zero gives an attenuation.
: ${GSTVOL:="1.5"}   # [0,10], default 1.0=100%, see gst-inspect volume
 
GSTCAP="gst-launch alsasrc device=\"${ALSADEV}\" ! \
   volume volume=\"${GSTVOL}\" ! rgvolume ! audioconvert ! audioresample ! \
   audio/x-raw-int,channels=1,width=8,depth=8,rate=16000 ! level ! \
   tcpserversink host=\"${MYHOST}\" port=${MYPORT}"
 
FFCAP="ffmpeg -f alsa -i ${ALSADEV} \
   -vol ${FFVOLUME} -ac 1 -acodec pcm_s8 -ar 16000 -ab 64000 -f u8 -"
SOXCAP="sox -q -t alsa ${ALSADEV} -1 -c 1 -t raw - gain ${SOXGAIN} rate -I 16000"
 
CMD=
case "$BACKEND" in
   [Gg]*)
      if ! test -x `which gst-launch` 2>/dev/null; then
         echo "gst-launch not found" >&2
         exit 1
      fi
      CMD="$GSTCAP"
      ;;
   [Ff]*)
      if ! test -x `which nc` 2>/dev/null; then
         echo "netcat not found" >&2
         exit 1
      fi
      if ! test -x `which ffmpeg` 2>/dev/null; then
         echo "ffmpeg not found" >&2
         exit 1
      fi
      CMD="nc -l \"${MYHOST}\" -p \"${MYPORT}\" -c \"${FFCAP}\""
      ;;
   [Ss]*)
      if ! test -x `which nc` 2>/dev/null; then
         echo "netcat not found" >&2
         exit 1
      fi
      if ! test -x `which sox` 2>/dev/null; then
         echo "sox not found" >&2
         exit 1
      fi
      CMD="nc -l \"${MYHOST}\" -p \"${MYPORT}\" -c \"${SOXCAP}\""
      ;;
   *)
      echo "Usage: [MYHOST=x.x.x.x] [MYPORT=N] [ALSADEV=hw:X,Y] \\" >&2
      echo "\t[FFCHAN=n] [FFVOLUME=x] [SOXGAIN=x] [GSTVOL=x] \\" >&2
      echo "\t\t${0##*/} G[st] || F[fmpeg] || S[ox]" >&2
      exit 1
      ;;
esac
 
trap : TERM
 
while : ; do
   sh -c "$CMD"
   [ -f "${EXIT_FILE}" ] && break
   sleep 2
done
 
exit 0
Как правильно остановить скрипт audio2net.sh? Скрипт audio2net.sh содержит бесконечный цикл и для того, чтобы корректно и гарантированно остановить скрипт нужно сделать следующее:
  1. sudo touch /var/run/avreg.stop # создаём стоп-файл
  2. CTRL-С (если в терминале) или kill {pid процесса gst-launch или nc}

Определите нужные параметры окружения (как минимум ALSADEV, как - см. в самом начале статьи) и запуская скрипт в терминале

примеры запуска скрипта audio2net.sh

# переменная PATH должна включать каталог /usr/local/bin
MYHOST="192.168.0.3" ALSADEV="hw:0,0" GSTVOL="1.7" audio2net.sh gstreamer
ALSADEV="hw:0,2" FFCHAN=2 audio2net.sh ffmpeg
ALSADEV="hw:1,0" SOXGAIN="+3" audio2net.sh sox

удостоверьтесь что задача решена - AVReg захватывает аудиопоток и записывает на диск.

И, наконец, добавьте автоматический запуск этого скрипта в фоне (замыкающий &) в момент загрузки операционной системы (автозагрузка):

cat /etc/rc.local

#!/bin/sh -e
#
# rc.local
 
# удаляем стоп-файл
rm -f /var/run/audio.stop
# запускаем в фоне скрипт трансляции аудио по сети
ALSADEV="hw:1,0" /usr/local/bin/audio2net.sh gstreamer &
 
exit 0

Ссылки.

manual/applications/audio2tcp.txt · Последние изменения: 2016-09-27