Thursday, February 21, 2013

LiveStreaming для тех, кого там нет

Возникла немного нетипичная задачка - устроить людям вещание в интернете. Для этого можно использовать много средств, но мы будем использовать Flussonic - в бесплатной версии он умеет все, что нам надо. Запись - это дело десятое.
После долгих мучений и репозиториев был выбран дистрибутив Ubuntu Server 12.04.2 LTS.

Устанавливается крайне просто:

echo "deb http://binaries.erlang-solutions.com/debian precise contrib"  >> /etc/apt/sources.list
echo "deb http://debian.erlyvideo.org binary/" >> /etc/apt/sources.list
wget -O - http://binaries.erlang-solutions.com/debian/erlang_solutions.asc | sudo apt-key add -
wget -q -O - http://debian.erlyvideo.org/binary/gpg.key | apt-key add -
apt-get update
apt-get -y install esl-erlang flussonic

Итак, источников вещания у нас 2.

1. IP-камера Axis 210 (Такое себе старье без H.264).

 Будем вещать через RTSP. Ее надо перекодировать. Для этого будем использовать VLC

apt-get install vlc x264

VLC выкладывает http поток на свой порт 9090, оттуда  его забирает Flussonic и отдает JwPlayer'у RTSP поток.

файл startvlc.sh

#!/bin/sh

TR='transcode{venc=x264{cabac=yes,bframes=0,keyint=125,qpmin=20,qpmax=50,ref=5,merange=24,mixed-refs=yes,direct=auto,me=umh,subme=7,trellis=2,weightb=yes,partitions=all,vbv-maxrate=920,vbv-bufsize=9000,ratetol=100.0,scenecut=60},vb=820,,width=720,height=576,hurry-up,audio-sync,deinterlace=yes,acodec=aac,aenc=avcodec{strict=-2},ab=64,channels=2,samplerate=48000}'

OUT="std{access=http,mux=ts{use-key-frames=1},dst=:9090}"

cvlc -vvvv rtsp://root:passw@CAMERA-IP/mpeg4/media.amp --intf dummy --sout '#'${TR}:${OUT}


echo "{stream, "vlc.ts", "tshttp://VLC-IP:9090/"}."  >> /etc/flussonic/flussonic.conf
/etc/init.d/flussonic start

После этого в панели по адресу FLUSSONIC-IP:8080 убедимся, что поток виден и его можно посмотреть.

Примерный код для index.html

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
  </script>
  <script type="text/javascript">
  var flashvars = {
    file : "vlc.ts",
    streamer:'rtmp://FLUSSONIC-IP:1935',
    'rtmp.tunneling':false,
    autostart: true
  };
  var paramObj = {allowScriptAccess : "always", allowFullScreen : "true", allowNetworking : "all"};
  swfobject.embedSWF("http://FLUSSONIC-IP:8080/flu/jwplayer.swf", "video", 720, 576,
    "10.3", "/flu/expressInstall.swf",
    flashvars, paramObj, {name: "jwplayer"});
  </script>

 2. Adobe FLME.

Будем забирать по HDS (что бы это ни значило :) )
Тут немного проще, указываем FMLE в адресе сервера наш flussonic в виде
Адрес: rtmp://FLUSSONIC-IP/live
Поток: livestream

AFLME выкладывает RTMP поток на Flussonic, оттуда он рестримит по HDS плееру.

В панели по адресу FLUSSONIC-IP:8080 убедимся, что поток виден и его можно посмотреть.

 Примерный код для index.html

 <div id="video"></div>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
  </script>
  <script type="text/javascript">
  var flashvars = {
    src : "http://FLUSSONIC-IP:8080/live/livestream/manifest.f4m",
    autoPlay: true
  };
  var paramObj = {allowScriptAccess : "always", allowFullScreen : "true", allowNetworking : "all"};
  swfobject.embedSWF("http://FLUSSONIC-IP:8080/flu/StrobeMediaPlayback.swf", "video", 720, 576,
    "10.3", "/flu/expressInstall.swf",
    flashvars, paramObj, {name: "StrobeMediaPlayback"});
</script>


 Вообще, советую приобщиться к инструкциям на сервере проекта :) Для знающих людей они будут полезнее моих :)

Wednesday, February 20, 2013

Экзотика с кодеками или silk+amrnb в Asterisk

Возникла задачка гонять голос по 3G сетям. После долгих и не особенно продуктивных мучений были выбраны кодеки speex и g729, как кандидаты на релиз. amr-nb патч существовал для версии 1.8, у меня же по разным причинам используется 10ка.
Но выбравшись из консоли и взглянув на мир, выяснилось, что для 10ки можно использовать кодек silk, он же используется для Skype и с недавнего времени стал open-source. Плюс, добрый человек в Одессе сделал патч для поддержки amrnb в 10й версии Астериска.

Все собиралось и тестировалось на Asterisk 10.12.1, Debian 6.0 x64 (OpenVZ)

1. SILK
Собирался по мотивам https://github.com/mordak/codec_silk
К стандартному набору для компилирования необходимо добавить curl. Это для работы скрипта, но никто не мешает скачать все руками.

Из отличий - в install_silk.sh заменил 


ln -sf "SILK_SDK_SRC_FIX_v$SKYPE_SILK_VER" silk
на  ln -sf "SILK_SDK_SRC_FLP_v$SKYPE_SILK_VER" silk Почему-то версия с фиксированной точкой у меня собираться отказывалась.
Также в astdir/codecs/silk/Makefile заменить
CFLAGS  += -Wall -enable-threads -O3
на
CFLAGS  += -Wall -enable-threads -O3 -fPIC
После этого все как обычно собирается.
После инсталляции в файл /etc/asterisk/codecs.conf добавить

[silk8]
type=silk
samprate=8000
fec=true
packetloss_percentage=10
maxbitrate=20000
dtx=false

[silk12]
type=silk
samprate=12000
fec=true
packetloss_percentage=10
maxbitrate=25000
dtx=false

[silk16]
type=silk
samprate=16000
fec=true
packetloss_percentage=10
maxbitrate=30000
dtx=false

[silk24]
type=silk
samprate=24000
fec=true
packetloss_percentage=10
maxbitrate=40000
dtx=false

Ну и в консоли.: asterisk -rx "core restart now"
И да, я знаю o бинарниках от Digium, но это не путь истинного джедая. Плюс, тот же добрый человек из Одессы упрекает их в глючности и не верить ему у меня оснований нет.

2. AMR-NB
Качаем патч с этой странички. Единственное что, если silk не компилируется вручную, то падает 2й hunk при патче. Просто в /codecs/Makefile необходимо добавить строчку
$(if $(filter codec_amr,$(EMBEDDED_MODS)),modules.link,codec_amr.so): $(LIBAMR)
После этого разархивируем в папку /codecs/amr содержимое следующего архива.
Переходим в папку /codecs/amr

./configure CFLAGS = "-g -O2 -fPIC"
make

После этого все как обычно собирается.
После инсталляции в файл /etc/asterisk/codecs.conf добавить

[amr]
octet-aligned=0
;codec_amr: Must be one of MR475, MR515, MR59, MR67, MR74, MR795, MR102, MR122
mode = MR475
dtx=0
cng = 1
vad = 0

octet-aligned=0 - Это следствие того, что CSipSimple (точнее, pjsip) умеет  AMR только в Bandwidth-Efficient режиме. Что это такое, можно почитать в RFC.
Ну и в консоли.: asterisk -rx "core restart now"
Теперь по core show translation  можно увидеть, что у нас появился целый набор silk'ов и amr.