magnify
Home arrow Рубрика "Администрирование"
formats

Организация видеотрансляции на сайте. VLC+Erlyvideo+HLS+nginx.

Опубликовано: 07.09.2012 Автор: в

Сегодняшний пост будет посвящен достаточно стабильному способу организации видеотрансляции на сайте. Для транскодирования и записи в очередной раз будем использовать VLC. В качестве RTMP-сервера задействуем Erlyvideo, ядро которого распространяется под лицензией GPL. В одной из предыдущих записей я уже описывал возможное решение с использованием Red5. Запись оказалась довольно интересной, поэтому теперь предложу еще одно решение с учетов современных тенденций и инструментов.

Приведу общую схему, где в качестве примеры указаны IP-камеры c видеопотоками в MPEG-4 и H264:

Схема трансляции

Как видно на диаграмме, для транскодирования используется VLC, а H264-поток забирается Erlyvideo напрямую, благо это он умеет. Для организации HTTP Live Streaming также используется VLC, настройки которого мы увидим ниже.

По традиции, детали установки приведу для Debian Squeeze 6.0 amd64, поскольку для этой архитектуры существует репозиторий Erlyvideo. Сразу оговорюсь, трансляция в примерах ведется без звука.

1. Подготовка
Добавляем репозитории для Debian Multimedia, nginx и Erlyvideo:
/etc/apt/sources.list.d/debian-multimedia.list

deb http://www.deb-multimedia.org squeeze main non-free
deb-src http://www.debian-multimedia.org squeeze main non-free

/etc/apt/sources.list.d/erlyvideo.list

deb http://debian.erlyvideo.org binary/

/etc/apt/sources.list.d/nginx.list

deb http://nginx.org/packages/debian/ squeeze nginx
deb-src http://nginx.org/packages/debian/ squeeze nginx

Обновляем репозитории

apt-get update

Обращаю ваше внимание, что репозиторий Erlyvideo добавлен для будущего обновления Debian до Wheezy, т.к. последняя версия Erlyvideo из пакетов ставится только на эту версию дистрибутива.

2. Установка ffmpeg, libvpx, fdk-aac, x264, openssl

apt-get install make automake g++ gcc autoconf lua5.1 liblua5.1-0-dev libtag1-dev \
libdvbpsi-dev libcdio-dev libvcdinfo-dev libcddb2-dev libmad0-dev libfaad-dev liba52-0.7.4-dev \
libmpeg2-4-dev libzvbi-dev libflac-dev libdca-dev libdirac-dev libdvdnav-dev libdvdread-dev libfaac-dev \
libgcrypt11-dev libgnutls-dev libgpac-dev libiso9660-dev libjpeg62 libltdl-dev libmp3lame-dev \
libmodplug-dev libpng12-dev libraw1394-dev libschroedinger-dev libspeex-dev libtag1-dev \
libtasn1-3-dev libtheora-dev libtwolame-dev libvcdinfo-dev libvorbis-dev build-essential \
librtmp-dev checkinstall git libopencore-amrnb-dev libopencore-amrwb-dev pkg-config yasm zlib1g-dev

# x264
cd /usr/local/src
git clone --depth 1 git://git.videolan.org/x264
cd x264
./configure --enable-pic --enable-shared
make
sudo checkinstall --pkgname=x264 --pkgversion="3:$(./version.sh | \
awk -F'[" ]' '/POINT/{print $4"+git"$5}')" --backup=no --deldoc=yes \
--fstrans=no --default

# fdk-aac
cd /usr/local/src
git clone --depth 1 git://github.com/mstorsjo/fdk-aac.git
cd fdk-aac
autoreconf -fiv
./configure --with-pic --enable-shared
make
sudo checkinstall --pkgname=fdk-aac --pkgversion="$(date +%Y%m%d%H%M)-git" --backup=no \
--deldoc=yes --fstrans=no --default

# libvpx
cd /usr/local/src
git clone --depth 1 http://git.chromium.org/webm/libvpx.git
cd libvpx
./configure --enable-pic --enable-shared --disable-unit-tests
make
sudo checkinstall --pkgname=libvpx --pkgversion="1:$(date +%Y%m%d%H%M)-git" --backup=no \
--deldoc=yes --fstrans=no --default

# ffmpeg
cd /usr/local/src
git clone --depth 1 git://source.ffmpeg.org/ffmpeg
cd ffmpeg
./configure --enable-gpl --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb \
--enable-libopencore-amrwb --enable-librtmp --enable-libtheora --enable-libvorbis \
--enable-libvpx --enable-libx264 --enable-nonfree --enable-version3 --enable-pic --enable-shared
make
sudo checkinstall --pkgname=ffmpeg --pkgversion="5:$(date +%Y%m%d%H%M)-git" --backup=no \
--deldoc=yes --fstrans=no --default

# openssl
# !!!ДЛЯ КОРРЕКТНОЙ РАБОТЫ ERLYVIDEO на Debian Squeeze!!!
# !!! Для Debian Wheezy можно apt-get install libssl1.0.0 !!!
cd /usr/local/src
wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz
tar -xvzf openssl-1.0.1c.tar.gz
cd openssl-1.0.1c
./config --prefix=/usr zlib-dynamic --openssldir=/etc/ssl shared
make
sudo checkinstall --pkgname=openssl --pkgversion="5:$(date +%Y%m%d%H%M)-git" --backup=no \
--deldoc=yes --fstrans=no --default

hash x264 ffmpeg ffplay ffprobe
ldconfig

3. Установка VLC

cd /usr/local/src
wget http://download.videolan.org/pub/videolan/vlc/2.0.3/vlc-2.0.3.tar.xz
tar -xvJf vlc-2.0.3.tar.xz
cd vlc-2.0.3/contrib
mkdir native
cd native
../bootstrap
make .live555
cd /usr/local/src/vlc-2.0.3
./configure --enable-faad --disable-pulse --disable-alsa --disable-qt4 --disable-skins2 --disable-v4l2 \
--disable-xvideo --disable-glx --disable-visual --enable-realrtsp --enable-flac --disable-dbus \
--disable-xcb > /tmp/1 2> /tmp/2
# В файле /tmp/2 можно будет смотреть ошибки и предупреждения процесса конфигурирования
# Если будет какая-нибудь ошибка, то необходимо установить соответствующий пакет Debian и
# запустить configure еще раз
make
adduser ipcam
cp -r /usr/local/src/vlc-2.0.3 /home/ipcam/vlc
chown -R ipcam:ipcam /home/ipcam/vlc
#!Запускать vlc от пользователя ipcam!

4. Установка nginx

apt-get install nginx

5. Установка Erlyvideo

#!!! Если установлен Debian Wheezy, то apt-get install erlyvideo должно сработать
cd /usr/local/src/
wget http://debian.erlyvideo.org/binary/erlyvideo_2.10.18_amd64.deb
dpkg -i --force-depends erlyvideo_2.10.18_amd64.deb

6. Конфигурация VLC
Создаем скрипт /home/ipcam/start_vlc.sh (не забудьте поменять CONTROLPASSWORD):

#!/bin/sh
/home/ipcam/vlc/vlc -vv --sout-keep -I telnet --telnet-host=127.0.0.1 -R \
--udp-caching=1000 --http-caching=1000 --telnet-password=CONTROLPASSWORD \
--vlm-conf /home/ipcam/config --repeat --no-ffmpeg-hurry-up --no-sout-transcode-hurry-up \
--rt-priority --http-reconnect --sout-transcode-high-priority --loop --no-play-and-stop \
--extraintf logger --logfile=/var/log/vlc/vlc.log --no-sout-audio \
--network-caching=3000 --sout-mux-caching=1000

Для простоты и удобства запуска будем использовать VLM. Файл /home/ipcam/config:

# MPEG-4 IP-камера
new mpeg4mux broadcast enabled
# H264 IP-камера
new h264mux broadcast enabled

setup mpeg4mux input "URL видеопотока камеры, например, rtsp://x.x.x.x/mpeg4/media.amp"
setup h264mux input "URL видеопотока камеры, например, rtsp://x.x.x.x/live/ch00_0"

# !!!Замените, где нужно СЕРВЕР!!!
# Пример транскодирования MPEG-4 в AVC + HLS
# Вероятнее всего, что параметры, наподобие vb, width, height, fps необходимо будет поднастроить.
setup mpeg4mux output '#transcode{vcodec=h264,venc=x264{cabac=yes,nf=yes,chroma-me=yes,partitions=-parti8x8-parti4x4-partp8x8-partb8x8,me=dia,keyint=15,min-keyint=8,scenecut=0,ipratio=0.71,bframes=0,qcomp=0.6,qpmin=10,qpmax=51,qpstep=4,ref=1,direct=auto,trellis=0,bpyramid=no,mixed-refs=no,weightb=no,8x8dct=no,fast-pskip=yes,mbtree=no,weightp=0,aq-mode=0,lookahead=0},vb=800,width=480,height=360,acodec=none,fps=15}:duplicate{dst="std{access=http,mux=ts,dst=:9090}",dst="std{access=livehttp{seglen=15,delsegs=true,numsegs=5,index=/usr/share/nginx/html/mpeg4mux/video.m3u8,index-url=http://СЕРВЕР/mpeg4mux/video-######.ts},mux=ts{use-key-frames},dst=/usr/share/nginx/html/mpeg4mux/video-######.ts}"}'

# Пример HLS + запись трансляции в файл
setup h264mux output '#duplicate{dst=std{access=file{append},mux=ts,dst=/home/record/record.mp4},dst=std{access=livehttp{seglen=10,delsegs=true,numsegs=5,index=/usr/share/nginx/html/h264mux/video.m3u8,index-url=http://СЕРВЕР/h264mux/video-######.ts},mux=ts,dst=/usr/share/nginx/html/h264mux/video-######.ts}}'

сontrol mpeg4mux play
сontrol h264mux play

Создаем директории для записи логов VLC и устанавливаем права:

mkdir /var/log/vlc
chown ipcam /var/log/vlc

Поясню некоторые детали. Удобство запуска через VLM заключается в том, что при этом поднимается telnet-интерфейс управления потоками, который можно использовать как для вручную, так и, например, различными скриптами. Запуск самого VLC идет от пользователя ipcam, поскольку от root’а его запускать нежелательно. HTTP Live Streaming обеспечивается с помощью модуля livehttp. Что касается транскодирования, то тут полет фантазии среди параметров x264 практически безграничен, но скажу сразу, что пока данный набор параметров себя оправдывает. К сожалению, рекомендуемое разработчиками кодирование CRF+VBV c Erlyvideo у меня нормально не заработало. В остальном, сильно рекомендую ознакомиться с конфигурацией VLM и x264.

7. Конфигурация Erlyvideo
Правим секцию rewrite в файле /etc/erlyvideo/erlyvideo.conf:

...
{rewrite, [
% Пример для транскодированного потока
{"video1", mpegts, "http://localhost:9090"},
% Пример для H264-потока с IP-камеры AirCam Ubiquiti
{"video2", rtsp, "rtsp://x.x.x.x/live/ch01_0",[{timeout,5000}]}
]}
...

8. Конфигурация nginx
Для корректной работы HLS добавляем в /etc/nginx/mime.types:

...
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}

Создаем директории для файлов HLS:

mkdir /usr/share/nginx/html/mpeg4mux
mkdir /usr/share/nginx/html/h264mux
chown ipcam /usr/share/nginx/html/mpeg4mux /usr/share/nginx/html/h264mux

9. Запуск сервисов

su - ipcam -c "/home/ipcam/start_vlc.sh &"
/etc/init.d/nginx start
/etc/init.d/erlyvideo start

Смотрим логи и проверяем, что все запустилось нормально.

10. Вывод на HTML-страницу

# Скачиваем flash-плеер, я рекомендую JW FLV Media Player, но можно попробовать и другой
wget http://www.longtailvideo.com/jw/upload/mediaplayer.zip
# Распаковываем и кладем файлы player.swf, swfobject.js и jwplayer.js в один каталог с предполагаемой
# HTML-страницей, где будем показывать видео

HTML-код:

...
<div id="mplayer">This will be replaced by the SWF.</div>
<script type="text/javascript">// <![CDATA[
   jwplayer('mplayer').setup({
     width: 640,
     height: 480,
     bufferlength: 1,
     autostart: true,
     mute: true,
     controlbar: 'none',
     provider: 'rtmp',
     streamer: 'rtmp://<СЕРВЕР>',
     file: 'video1',
     <!-- или file: 'video2' -->
     modes: [
         {type: 'flash', src: 'player.swf'},
         {type: 'html5',
            config: {
               file: 'http://СЕРВЕР/mpeg4mux/video',
               <!-- или file: 'http://CЕРВЕР/h264mux/video' -->
               provider: 'http'
          }
       }
      ]
   });
// ]]></script>

...

11. TODO
Перечислю возможные улучшения, которые не будут лишними:

  1. Watchdog для проверки работспособности VLC, который будет перезапускать необходимые сервисы в случае потери потоков с камер
  2. Создание плейлиста для JW Player
  3. Logrotate для логов VLC
  4. Скрипт для организации архивов записей, реализуется через telnet-интерфейс VLC, задача не ахти простая, но интересная ;)

12. На будущее
На данный момент основными технологиями стриминга видео являются HTTP Live Streaming, вообще говоря, предназначенная для использования на устройствах Apple, вполне применимая в теории и на других устройствах, а также HTTP Dynamic Streaming от Adobe (в некотором смысле преемник RTMP).

Кроме того, сейчас активно развивается JW Player Adaptive Provider. К большому разочарованию, разработчики JW Player включили поддержку HLS для Flash в платные версии плеера. Что ж, будем ждать появления поддержки HLS на non-Apple устройствах, что позволит отказаться от RTMP. Для использования HDS, можно воспользоваться 3-ей версией Erlyvideo — Flussonic и его поддержкой HDS. Насколько я понял, в его ядро поддержка HLS не включена. Ну а наличие Open Source Media Framework позволяет создавать свои плееры для RTMP и HTTP-стриминга.

Ссылки:

  1. http://www.videolan.org
  2. http://erlyvideo.org/
  3. http://www.longtailvideo.com/players/jw-flv-player
  4. http://www.videolan.org/developers/x264.html
  5. http://deb-multimedia.org/
  6. http://www.debian.org/index.ru.html
  7. https://ffmpeg.org/trac/ffmpeg/wiki/UbuntuCompilationGuide
  8. https://developer.apple.com/resources/http-streaming/
  9. http://www.adobe.com/products/hds-dynamic-streaming.html
  10. http://nginx.org/ru/
 
Просмотров: 23 964 | 15 комментариев  comments 
formats

Почтовая система на Postfix с виртуальными доменами

Опубликовано: 04.08.2011 Автор: в

Недавно пришлось настраивать почтовую систему начального уровня, поэтому решил написать небольшое HOWTO, чтобы самому не забыть, и предоставить информацию для тех, у кого возникают проблемы.

Что будет включать в себя почтовая система:

  • Почтовый сервер Postfix + виртуальные почтовые домены и пользователи
  • PostfixAdmin для управления всем хозяйством через web
  • Amavisd-new + SpamAssassin + ClamAV для борьбы со спамом и вирусами
  • Dovecot в качестве POP3(S) и IMAP(S) сервера, а также LDA
  • Механизм квотирования (Maildir++)
  • Roundcube для веб-интерфейса к почтовым ящикам

Тестовая система: Ubuntu 11.04 server. Работаю под рутом, поэтому sudo опускаем.
Доменное имя для примера: example.com

1. Установка пакетов и создание пользователя для доступа к виртуальным почтовым ящикам

apt-get install postfix postfix-mysql maildrop apache2 php5 php5-cli php5-mysql php5-imap \
php5-mcrypt php5-intl amavisd-new spamassassin clamav clamav-daemon dovecot-imapd \
dovecot-pop3d mysql-server

# Почта будет храниться здесь в виде /home/vmail/DOMAINNAME/USERNAME
# Удаленные через PostfixAdmin домены/ящики буду храниться в /home/vmail/DELETED
mkdir -p /home/vmail/DELETED

# !!! UID 111 должен быть свободен, если он занят то выбираем свободный, и везде далее не забываем его поменять !!!
useradd -r -u 111 -g mail -d /home/vmail -s /sbin/nologin -c "Virtual mailbox" vmail
chown -R vmail:mail /home/vmail
chmod 770 /home/vmail

2. Установка PostfixAdmin
PostfixAdmin — веб-интерфейс управления виртуальными почтовыми доменами и пользователями.

Скачиваем последнюю версию с http://sourceforge.net/projects/postfixadmin:

cd /var/www
wget POSTFIXADMIN_URL.tar.gz
tar -xvzf postfixadmin-2.x.x.tar.gz
mv postfixadmin-2.x.x postfixadmin
chown -R www-data:www-data postfixadmin

Создаем базу данных:

mysql -u root -p
CREATE DATABASE postfix;
GRANT ALL ON postfix.* TO postfix@localhost IDENTIFIED BY 'postfixpass';
FLUSH PRIVILEGES;

Правим /var/www/postfixadmin/config.inc.php:

...
$CONF['configured'] = true;
...
$CONF['postfix_admin_url'] = 'http://example.com/postfixadmin';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'postfixpass';
$CONF['database_name'] = 'postfix';
...
$CONF['admin_email'] = 'postmaster@example.com';
...
$CONF['default_aliases'] = array (
    'abuse' => 'abuse@example.com',
    'hostmaster' => 'hostmaster@example.com',
    'postmaster' => 'postmaster@example.com',
    'webmaster' => 'webmaster@example.com'
);
...
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
...
$CONF['fetchmail'] = 'NO';
...
$CONF['mailbox_postcreation_script']='/usr/bin/sudo -u vmail /usr/local/bin/postfixadmin-mailbox-postcreation.sh';
$CONF['mailbox_postdeletion_script']='/usr/bin/sudo -u vmail /usr/local/bin/postfixadmin-mailbox-postdeletion.sh';
$CONF['domain_postdeletion_script']='/usr/bin/sudo -u vmail /usr/local/bin/postfixadmin-domain-postdeletion.sh';
...
// Остальные параметры можно изменить по вкусу

Заходим на http://example.com/postfixadmin/setup.php:
Проверяем секцию «Checking for dependencies: «, там все должно быть «ОК».
Задаем «Setup password» и меняем $CONF[‘setup_password’] на полученный хеш.
Затем вводим новый Setup password, детали суперадмина и добавляем его.
Теперь можно зайти на http://example.com/postfixadmin, используя созданного суперадмина.

Добавляем в /etc/sudoers:

...
www-data ALL=(vmail) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postdeletion.sh
www-data ALL=(vmail) NOPASSWD: /usr/local/bin/postfixadmin-domain-postdeletion.sh
www-data ALL=(vmail) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postcreation.sh
...

Копируем скрипты, которые физически создают/удаляют домены/почтовые ящики после соответственных действий в PostfixAdmin:

cp /var/www/postfixadmin/ADDITIONS/postfixadmin-domain-postdeletion.sh /usr/local/bin
cp /var/www/postfixadmin/ADDITIONS/postfixadmin-mailbox-postcreation.sh /usr/local/bin
cp /var/www/postfixadmin/ADDITIONS/postfixadmin-mailbox-postdeletion.sh /usr/local/bin

Правим в этих скриптах параметры basedir и trashbase(где есть):

basedir=/home/vmail
...
trashbase=/home/vmail/DELETED

После этого нужно создать первый виртуальный домен example.com и хотя бы один ящик (приветственное письмо можно пока не отсылать, все равно не дойдет).

2. Настройка Postfix

Небольшое отступление. Я сознательно отказался от родного в postfix VDA и выбрал Dovecot LDA, поскольку для поддержки квот нужны патч и пересборка deb-пакета. С патчем квоты тоже работают хорошо, но обновление Postfix становится более затруднительным.

Правим /etc/postfix/main.cf:

...
myhostname = mail.example.com
myorigin = /etc/mailname
mydestination = $myhostname, localhost.example.com, localhost
...
# Таблица просмотра виртуальных доменов
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf

# Таблицы просмотра почтовых псевдонимов для виртуальных почтовых доменов/ящиков
virtual_alias_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf

# Таблицы просмотра каталогов для хранения почты
virtual_mailbox_maps =
   proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
   proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf

# !!! GID для группы mail, если он отличается, то здесь и далее меняем !!!
virtual_gid_maps = static:8

virtual_mailbox_base = /home/vmail
virtual_minimum_uid = 111
dovecot_destination_recipient_limit = 1
# Транспорт для виртуальных доменов в virtual_mailbox_domains - Dovecot LDA
virtual_transport = dovecot
virtual_uid_maps = static:111

broken_sasl_auth_clients = yes

# Небольшие ограничения для отсылки, можно добавить и DNSBL, и т.д., кому как хочется
smtpd_recipient_restrictions =
    permit_mynetworks,
    reject_non_fqdn_hostname,
    reject_non_fqdn_sender,
    reject_non_fqdn_recipient,
    reject_unauth_destination,
    reject_unauth_pipelining,
    reject_invalid_hostname

# Добавляем проверку на вирусы и спам через amavisd-new
content_filter = smtp-amavis:[127.0.0.1]:10024
receive_override_options=no_address_mappings

message_size_limit = 10485760
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
smtpd_helo_required = yes

Создаем файлы для таблиц просмотра MySQL, тем самым, связывая Postfix и базу данных для PostfixAdmin.

mkdir /etc/postfix/sql

/etc/postfix/sql/mysql_virtual_domains_maps.cf:

user = postfix
password = postfixpass
hosts = localhost
dbname = postfix
query          = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
#query          = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
#query           = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
#expansion_limit = 100

/etc/postfix/sql/mysql_virtual_alias_maps.cf:

user = postfix
password = postfixpass
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
#expansion_limit = 100

/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf:

user = postfix
password = postfixpass
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf:

user = postfix
password = postfixpass
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' AND mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'

/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf:

# handles catch-all settings of target-domain
user = postfix
password = postfixpass
hosts = localhost
dbname = postfix
query  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' AND alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

/etc/postfix/sql/mysql_virtual_mailbox_maps.cf:

user = postfix
password = postfixpass
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#expansion_limit = 100

Немного безопасности:

chmod 640 /etc/postfix/sql/*
chown -R postfix /etc/postfix/sql

Правим /etc/postfix/master.cf:

...
pickup    fifo  n       -       -       60      1       pickup
    -o content_filter=
    -o receive_override_options=no_header_body_checks
...
smtp-amavis     unix    -       -       -       -       2       smtp
    -o smtp_data_done_timeout=1200
    -o smtp_send_xforward_command=yes
    -o disable_dns_lookups=yes
    -o max_use=20

127.0.0.1:10025 inet    n       -       -       -       -       smtpd
    -o content_filter=
    -o local_recipient_maps=
    -o relay_recipient_maps=
    -o smtpd_restriction_classes=
    -o smtpd_delay_reject=no
    -o smtpd_client_restrictions=permit_mynetworks,reject
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o smtpd_data_restrictions=reject_unauth_pipelining
    -o smtpd_end_of_data_restrictions=
    -o mynetworks=127.0.0.0/8
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000
    -o smtpd_client_connection_count_limit=0
    -o smtpd_client_connection_rate_limit=0
    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

dovecot unix    -       n       n       -       -      pipe
    flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop} -n -m ${extension}

3. Настройка Amavisd-new+ClamAV+SpamAssassin

Правим /etc/amavis/conf.d/05-node_id:

...
$myhostname = "mail.example.com"
...

Правим /etc/amavis/conf.d/15-content_filter_mode (точнее раскомментируем соответствующие строчки):

...
@bypass_virus_checks_maps = (
   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
...
@bypass_spam_checks_maps = (
   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

Правим /etc/amavis/conf.d/21-ubuntu_defaults в соответствиями со своими желаниями:

...
$final_virus_destiny      = D_DISCARD;
$final_banned_destiny     = D_DISCARD;
$final_spam_destiny       = D_PASS;  # Только помечаем обнаруженный спам
$final_bad_header_destiny = D_PASS;  # Только помечаем письмо с плохими заголовками
...

Правим /etc/amavis/conf.d/50-user:

...
# Добавляем поддержку виртуальных доменов в MySQL
@lookup_sql_dsn = (
    ['DBI:mysql:database=postfix;host=127.0.0.1;port=3306',
     'postfix',
     'postfixpass']);
.....
$sql_select_policy = 'SELECT domain FROM domain WHERE CONCAT("@",domain) IN (%k)';
...

Немного безопасности:

chmod 640 /etc/amavis/conf.d/50-user

Добавляем в /etc/clamav/freshclam.conf:

...
NotifyClamd /etc/clamav/clamd.conf

Добавляем сервисных пользователей в группы:

adduser clamav amavis
adduser amavis clamav

Правим /etc/default/spamassassin:

ENABLED=1
...
CRON=1

Перезапускаем сервисы:

/etc/init.d/postfix restart
/etc/init.d/amavis restart
/etc/init.d/clamav-freshclam restart
/etc/init.d/clamav-daemon restart

4. Настройка Dovecot (IMAP,POP3,LDA)

Правим /etc/dovecot/dovecot.conf:

...
protocols = imap imaps pop3 pop3s
disable_plaintext_auth = no
...
mail_location = maildir:/home/vmail/%d/%u
...
# !!! Не забываем проверить uid для vmail и gid для mail !!!
mail_uid = 111
mail_gid = 8
...
first_valid_uid = 111
last_valid_uid = 111
first_valid_gid = 8
last_valid_gid = 8
...
protocol imap {
...
     mail_plugins = quota imap_quota
     imap_client_workarounds = delay-newmail netscape-eoh
}

protocol pop3 {
...
     mail_plugins = quota
     pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}

protocol lda {
...
     postmaster_address = postmaster@example.com
     mail_plugins = quota
}
...
auth_default_realm = example.com

auth default {
     mechanisms = plain login
     passdb sql {
       args = /etc/dovecot/dovecot-sql.conf
     }
     userdb sql {
       args = /etc/dovecot/dovecot-sql.conf
     }
...
     socket listen {
       path = /var/run/dovecot/auth-master
       mode = 0600
       user = vmail
       group = mail
     }
}
...
plugin {
   quota = maildir:User quota
   # Квота по умолчанию, затем переопределяется SQL-запросом userdb
   quota_rule = storage=50M:messages=1000
   # Дополнительная квота к корзине, чтобы можно было удалять сообщения при превышении квоты
   quota_rule2 = Trash:storage=10M
   # Сообщение об исчерпании 80% квоты
   quota_warning = storage=80%% /usr/local/bin/quota-warning.sh 80
   ...
}

Правим /etc/dovecot/dovecot-sql.conf:

...
driver = mysql
connect = host=127.0.0.1 dbname=postfix user=postfix password=postfixpass
# Не забываем про uid и gid
password_query = SELECT username as user, password, concat('/home/vmail/', maildir) as userdb_home, concat('maildir:/home/vmail/', maildir) as userdb_mail, 111 as userdb_uid, 8 as userdb_gid FROM mailbox WHERE username = '%u' AND active = '1'

user_query = SELECT concat('/home/vmail/', maildir) as home, concat('maildir:/home/vmail/', maildir) as mail, 111 AS uid, 8 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
...

Копируем dovecot.conf в dovecot-nowarning.conf и комментируем строчку:

...
# Необходимо во избежание цикла
#quota_warning = storage=80%% /usr/local/bin/quota-warning.sh 80
...

Создаем /usr/local/bin/quota-warning.sh:

#!/bin/sh

PERCENT=$1
cat << EOF | /usr/lib/dovecot/deliver -d $USER -c /etc/dovecot/dovecot-nowarning.conf
From: postmaster@example.com
Subject: quota warning

Your mailbox is now $PERCENT% full. Please delete unnecessary emails.
EOF

На всякий случай устанавливаем бит выполнения на скрипты:

chmod +x /usr/local/bin/*.sh

Перезапускаем сервис:

/etc/init.d/dovecot restart

5. Установка Roundcube

Качаем и распаковываем последнюю версию:

cd /var/www
wget ROUNDCUBE_URL
tar -xvzf roundcubemail-X.X.X.tar.gz
mv roundcubemail-X.X.X mail
chown -R www-data:www-data mail

Создаем базу данных для Roundcube:

mysql -u root -p
>CREATE DATABASE roundcubemail /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
>GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'password';
>FLUSH PRIVILEGES;

cd /var/www/mail
mysql -u root -p roundcubemail < SQL/mysql.initial.sql

Идем на http://example.com/mail/installer/ и следуем инструкциям.

Удаляем каталог installer:

rm -r /var/www/mail/installer

Правим /var/www/mail/config/main.inc.php в соответствии с нуждами, например:

...
$rcmail_config['default_host'] = 'localhost';
$rcmail_config['smtp_server'] = 'localhost';
$rcmail_config['smtp_port'] = 25;
$rcmail_config['smtp_user'] = '';
$rcmail_config['smtp_pass'] = '';
$rcmail_config['enable_caching'] = false;
$rcmail_config['login_lc'] = true;
$rcmail_config['auto_create_user'] = true;
$rcmail_config['dont_override'] = array('skin','default_imap_folders','keep_alive');
$rcmail_config['identities_level'] = 3;
$rcmail_config['create_default_folders'] = true;
$rcmail_config['protect_default_folders'] = true;
$rcmail_config['spellcheck_languages'] = array('en'=>'English');
$rcmail_config['preview_pane'] = true;
$rcmail_config['skip_deleted'] = true;
...

По умолчанию, Apache в Ubuntu не обрабатывает .htaccess в директории /var/www, поэтому правим /etc/apache2/sites-available/default:

<Directory /var/www/>
   Options Indexes FollowSymLinks MultiViews
   AllowOverride All
   Order allow,deny
   allow from all
</Directory>

Перезапускаем Apache:

/etc/init.d/apache2 restart

На этом основная настройка почтовой системы закончена, остается создавать домены, почтовые ящики, проверить отсылку/чтение почты. Важное DNS-замечание: необходимо не забыть прописать MX-запись для домена (example.com) в виде mail.example.com и A-запись для mail.example.com, чтобы почта корректно стала ходить извне.

Естественно, что эта почтовая система начального уровня для небольших нагрузок, хотя дальнейшие усовершенствования обязательно нужны, будь то SMTP-аутентификация, DNSBL, грейлистинг, проверка заголовков и др., тем более, что реализуются они сравнительно просто.

Данная запись писалась по горячим следам, вполне возможно, что некоторые детали могли быть упущены, поэтому, как говорится, /var/log/ в помощь..8)

UPDATE 06.12.2012: в Ubuntu >= 12.04 уже идет Dovecot 2.0, и там конфигурация разбита на файлы. В целом, настройка повторяется с учетом этого, также некоторые конфигурационные директивы меняются, в частности imaps и pop3s указывать не надо, есть файл ssl.conf, формат квоты в плагине также немного меняется, все это легко адаптируется по документации для Dovecot 2.x. Лично у меня эта адаптация заняла не больше 15 минут.

 
Просмотров: 16 891 | 19 комментариев  comments 
formats

Организация видеотрансляции на сайте. VLC+Red5+Xuggler+steamStream.

Опубликовано: 02.08.2010 Автор: в

В этот раз я поделюсь рабочим решением для организации видеотрансляции в основе которого лежит связка Red5 и steamStream. Red5 — это RTMP-сервер с открытым исходным кодом, а steamStream — приложение Red5, которое по сути является рестримером RTP в RTMP. В качестве вспомогательных, но не менее важных «рабочих лошадок» будут выступать VLC и Xuggler (работа с видео при помощи Java).

Этот вариант трансляции, на мой взгляд, более «правильный» по сравнению со способом трансляции через VLC, описанным ранее, поскольку использует протокол RTMP, а не гонит FLV напрямую. Недостатки тоже есть: сложное решение, необходимость компиляции steamStream, и работает с Red5 до определенной ревизии SVN (было выяснено опытным путем).

Исходная система:ОС Debian Squeeze и камера Axis с MPEG-4 видео.

1. Установка VLC

# !!! НЕ ЗАБУДЬТЕ ДОБАВИТЬ РЕПОЗИТОРИЙ DEBIAN-MULTIMEDIA В APT !!!
# Подготовка
cd /usr/local/src
apt-get install make automake g++ gcc autoconf ffmpeg lua5.1 liblua5.1-0-dev libtag1-dev \
libdvbpsi-dev libcdio-dev libvcdinfo-dev libcddb2-dev libmad0-dev libavcodec-dev libavutil-dev \
libavformat-dev  libswscale-dev libpostproc-dev libfaad-dev liba52-0.7.4-dev libmpeg2-4-dev \
libzvbi-dev libflac-dev
# Установка liveMedia
wget http://www.live555.com/liveMedia/public/live555-latest.tar.gz
tar -xvzf live555-latest.tar.gz
cd live
./genMakefiles linux
make
cd /usr/local/src
cp -r live/ vlc-1.1.0/extras/
# VLC
wget http://download.videolan.org/pub/videolan/vlc/1.1.0/vlc-1.1.0.tar.bz2
bzip2 -d vlc-1.1.0.tar.bz2
tar xvf vlc-1.1.0.tar
cd vlc-1.1.0
./configure --enable-faad --disable-remoteosd --disable-qt4 --disable-skins2 --disable-activex \
--disable-v4l2 --disable-libv4l2 --disable-xvideo --disable-glx --disable-opengl --disable-visual \
--enable-realrtsp --enable-flac --with-live555-tree=extras/live \
--disable-dbus --disable-xcb > /tmp/1 2> /tmp/2
# В файле /tmp/2 можно будет смотреть ошибки и предупреждения процесса конфигурирования
# Если будет какая-нибудь ошибка, то необходимо установить соответствующий пакет Debian и
# запустить configure еще раз
make
adduser ipcam
cp -r /usr/local/src/vlc-1.1.0 /home/ipcam/vlc
chown -R /home/ipcam/vlc ipcam:ipcam
#!Запускать vlc от пользователя ipcam!

2. Установка Red5:

# Пакет собранный из исходников Red5 ревизии 3894 из SVN. Более поздние сборки не работали.
# Не знаю, как на данный момент, но подозреваю, что ситуация осталась та же.
wget http://flance.onego.ru/files/red5/red5_0.9.0-r3894_all.deb
dpkg -i red5_0.9.0-r3894_all.deb

3. Установка Xuggler:

wget http://com.xuggle.s3.amazonaws.com/xuggler/xuggler-3.4.FINAL/xuggle-xuggler.3.4.1012-i686-pc-linux-gnu.sh
chmod +x xuggle-xuggler.3.4.1012-i686-pc-linux-gnu.sh
./xuggle-xuggler.3.4.1012-i686-pc-linux-gnu.sh

Добавить

export XUGGLE_HOME=/usr/local/xuggler
export LD_LIBRARY_PATH=$XUGGLE_HOME/lib:$LD_LIBRARY_PATH
export PATH=$XUGGLE_HOME/bin:$PATH

в начало /usr/lib/red5/red5.sh

4. Установка steamStream:

# Подгототвка
# Не забыть, что sun-java6-jdk находится в non-free пакетах
apt-get install sun-java6-jdk ant
# steamStream
wget  http://flance.onego.ru/files/steamStream/steamStream.tar.gz
tar -xvzf steamStream.tar.gz
cp -r steamStream /usr/lib/red5/webapps
chown -R ipcam:ipcam /usr/lib/red5/webapps/steamStream/sdpdescriptors
# Jetm - необходимо для запуска
wget "http://downloads.sourceforge.net/project/jetm/jetm/jetm-1.2.3/jetm-1.2.3.tar.gz?use_mirror=citylan&ts=1280727327"
tar -xvzf jetm-1.2.3.tar.gz
cp jetm-1.2.3/lib/*.jar /usr/lib/red5/lib
# Копируем необходимы библиотеки для компиляции steamStream
cp /usr/local/xuggler/share/java/jars/xuggle-xuggler.jar /usr/lib/red5/lib
wget http://xuggle.googlecode.com/svn/trunk/repo/share/java/xuggle/xuggle-xuggler-red5/3.1.875.200908131110/xuggle-xuggler-red5-3.1.875.200908131110.jar
cp xuggle-xuggler-red5-3.1.875.200908131110.jar /usr/lib/red5/lib

Корректируем некоторые файлы в /usr/lib/red5/webapps/steamStream/WEB-INF/src/steamStream:

Application.java:

smf.setVideoWidth(WIDTH);
smf.setVideoHeight(HEIGHT);

где WIDTH,HEIGHT — размер картинки с камеры

ReStreamer.java:

private final long tsInterval = TSINTERVAL;
...
private final int frNumerator = FPS;

где TSINTERVAL должно быть равным 1000000/FPS, например, если FPS = 10 кадров в сек., то TSINTERVAL = 100000. FPS — частота кадров видео с камеры.

Компилируем steamStream:

cd /usr/lib/red5/webapps/steamStream/WEB-INF
ant compile
# Должно получиться «BUILD SUCCESSFUL»

5. Запуск red5:

/etc/init.d/red5 start

Проверяем логи в /usr/lib/red5/log/ на наличие ошибок.

6. Запуск VLC:

Создаем файл /home/ipcam/config со следующим содержанием:

new teststream broadcast enabled
setup teststream input <URL видеопотока с камеры>
setup teststream output "#rtp{dst=127.0.0.1,port=10000,sdp=file:///usr/lib/red5/webapps/steamStream/sdpdescriptors/stream.sdp}"
control teststream play

Создаем скрипт запуска /home/ipcam/start_vlc.sh со следующим содержанием:

/home/ipcam/vlc/vlc -vvv --sout-keep --no-rtsp-tcp -I telnet --extraintf logger --logfile=/home/ipcam/vlc.log --telnet-host=127.0.0.1 -R --udp-caching=5000 --rtsp-caching=1000 --http-caching=1000 --telnet-password=pass --vlm-conf /home/ipcam/config --repeat --no-drop-late-frames --no-skip-frames --no-ffmpeg-hurry-up --no-sout-transcode-hurry-up --rt-priority

Запускаем и проверяем наличие файла /usr/lib/red5/webapps/steamStream/sdpdescriptors/stream.sdp

К сожалению, и VLC имеет свойство иногда вырубаться, поэтому для стабильности лучше всего написать watchdog
.
7. Интеграция в HTML:

# Скачиваем flash-плеер, я рекомендую JW FLV Media Player, но можно попробовать и другой
wget http://www.longtailvideo.com/jw/upload/mediaplayer.zip
# Распаковываем и кладем файлы  player.swf и swfobject.js в один каталог с предполагаемой
# HTML-страницей, где будем показывать видео

Добавляем следующий HTML-код в страницу:

<script src="swfobject.js" type="text/javascript"></script>
<div id="mplayer">this will be replaced by the SWF.</div>
<script type="text/javascript">// <![CDATA[
var so = new SWFObject('player.swf','player','480','360','9');
so.addParam('allowfullscreen','true');
so.addParam('flashvars','streamer=rtmp://<адрес сервера с запущенным Red5>/steamStream&amp;provider=rtmp&amp;file=stream.flv&amp;bufferlength=0&amp;autostart=true&amp;controlbar=none&amp;displayclick=fullscreen');
so.write('mplayer');
// ]]>
</script>

Открываем страничку и смотрим. Если видео не пошло — проверяем логи в /usr/lib/red5/log/.

P.S. В скором времени собираюсь также проверить вариант использования еще одного RTMP-сервера — Erlyvideo, который активно и с энтузиазмом на данный момент разрабатывается.

Ссылки:

  1. http://www.videolan.org
  2. http://code.google.com/p/red5/
  3. http://red5wiki.com/wiki/SteamStream
  4. http://www.xuggle.com/xuggler/
  5. http://erlyvideo.org/
  6. http://www.live555.com/liveMedia
  7. http://www.longtailvideo.com/players/jw-flv-player
 
Просмотров: 30 683 | 34 комментария  comments