Одновременное вещание нескольких спутниковых ТВ- и радиоканалов с одного транспондера в IP-сеть

Дали спутниковую карту SkyStar 2. К ней подключена тарелка (настроенная на спутник ExpressAM22 - кстати говоря, не самый богатый по выбору тв и радио каналов спутник :) ) Сказали - надо вещание в сеть. Я сказал - сделаю. Раз сказал - сделал. Теперь расскажу вам как (вкратце конечно, но те кому интересно - думаю будет полезно)

На самом деле это конечно только кажется, что все было так просто, так быстро, и так безпроблемно. На самом деле эта задача убила у меня три недели времени (и часть отпуска :), которую я мог целиком посвятить семье ).

Кстати как это принято в больших книгах ;) - выражаю благодарность моей жене, за ее терпение!

 

P.S. Ужас! Оказывается уже на многих форумах есть ссылки на эту статью. А ведь здесь описывается не самый лучший способ трансляции в сеть ;). Срочно сажусь писать статью, как транслировать с помощью VLC...

 

 

Итак, имеем спутниковую карту, тарелку настроенную на спутник, и поставленную задачу.

Карта вставлена в линуксовый сервер. Дистрибутив, как наверно догадался тот, кто читал другие мои статьи - Slackware, а точнее Slackware 10.1 установленная полностью с двух дисков (ленив я стал в последнее время, да и винты стали большими)

Насчет рекомендаций по железу - я пока сам не могу конкретно сказать, но у меня стоит Атлон 950, память 128 Мбайт. Вроде с отправкой 3 тв-каналов и 2 радио - сервер справлялся, но это дело такое, сами понимаете, если есть возможность - ставьте тачку помощнее :).

Итак, установили Slackware, подняли сеть, ядро по умолчанию 2.4.29 - меня на первоначальном этапе пока устраивает. rc.hotplug карту не нашел, ну так даже и лучше - я перед этим с другой картой возился - так он подбирал не те модули и систему убивал :). Смотрим что есть:

root@sky-cast:~# lspci
00:00.0 Host bridge: VIA Technologies, Inc. VT8363/8365 [KT133/KM133] (rev 03)
00:01.0 PCI bridge: VIA Technologies, Inc. VT8363/8365 [KT133/KM133 AGP]
00:07.0 ISA bridge: VIA Technologies, Inc. VT82C686 [Apollo Super South] (rev 40)
00:07.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C/VT8235 PIPC Bus Master IDE (rev 06)
00:07.4 Bridge: VIA Technologies, Inc. VT82C686 [Apollo Super ACPI] (rev 40)
00:09.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)
00:0b.0 Multimedia audio controller: C-Media Electronics Inc CM8738 (rev 10)
00:0f.0 Network controller: Techsan Electronics Co Ltd B2C2 Sky2PC PCI [SkyStar2] (rev 02)
01:00.0 VGA compatible controller: Trident Microsystems 3DImage 9750 (rev f3)

Вот она родимая. Перед дальнейшим прочтением и выполнением рекомендуется ударить в бубен три раза. Не соседа в бубен - а в бубен, типа такого.

Надо сказать, перед этим я много много читал. Нашел следующую замечательную статью href=http://www.gs.ru/info/si/ss2lin24.html
Взял snapshot дров от Nuclearcat с той ссылки - ибо кажется тоже столкнулся с тем, что дрова с linuxtv.org у меня сигнал не лочили.
На всякий случай выкладываю и на своем сайте, вот ссылка - linuxtv-dvb-1.1.1a.tar.bz2
Затем стандартно распаковываем, внимательно читаем всяки ридми, делаем
cd build-2.4
потом
make
Радуемся если все удачно скомпилировалось. Делаем ./insmod.sh load - т.е. загружаем все модули. Будете иметь примерно такую картину :)

root@sky-cast:/usr/local/src/linuxtv-dvb-1.1.1a/build-2.4# lsmod
Module                  Size  Used by    Not tainted
skystar2               17420   0
ttusb_dec              15144   0  (unused)
dvb-ttusb-budget       21236   0  (unused)
ttpci-eeprom            1312   0
saa7146_vv             34844   0
saa7146                10496   0  [saa7146_vv]
mt312                   4588   0
cx24110                 5508   0
grundig_29504-491       3236   0
grundig_29504-401       5164   0
tda1004x               11440   0
ves1820                 4608   0
stv0299                 9392   0  (unused)
alps_tdmb7              3592   0
alps_tdlb7              5272   0
ves1x93                 4976   0
dvb-core               56124   0  [skystar2 ttusb_dec dvb-ttusb-budget mt312 cx24110 
 grundig_29504-491 grundig_29504-401 tda1004x ves1820 stv0299 alps_tdmb7 alps_tdlb7 ves1x93]
video-buf              10768   0  [saa7146_vv]
v4l2-common             2880   0  [saa7146_vv]
v4l1-compat            12392   0  [saa7146_vv]
videodev                5760   0  [saa7146_vv]
evdev                   4000   0  (unused)
input                   3200   0  [evdev]
snd-pcm-oss            36704   0  (unused)
snd-mixer-oss          12152   0  [snd-pcm-oss]
usbcore                58860   1  [ttusb_dec dvb-ttusb-budget]
parport_pc             15044   0
parport                22824   0  [parport_pc]
8139too                13928   1
mii                     2272   0  [8139too]
crc32                   2880   0  [8139too]
snd-cmipci             16704   0  (unused)
gameport                1420   0  [snd-cmipci]
snd-pcm                54504   0  [snd-pcm-oss snd-cmipci]
snd-opl3-lib            5860   0  [snd-cmipci]
snd-hwdep               4352   0  [snd-opl3-lib]
snd-timer              13412   0  [snd-pcm snd-opl3-lib]
snd-mpu401-uart         3200   0  [snd-cmipci]
snd-rawmidi            12320   0  [snd-mpu401-uart]
snd-seq-device          3812   0  [snd-opl3-lib snd-rawmidi]
snd                    31268   0  [snd-pcm-oss snd-mixer-oss snd-cmipci snd-pcm snd-opl3-lib
 snd-hwdep snd-timer snd-mpu401-uart snd-rawmidi snd-seq-device]
snd-page-alloc          4712   0  [snd-mixer-oss snd-pcm snd-hwdep snd-timer snd-rawmidi snd-seq-device snd]
soundcore               3396   4  [snd]
ide-scsi                9392   0
agpgart                45092   0  (unused)
Можно аккуратно подгрузить только те что нужно, а нужны то были всего лишь
modprobe dvb-core
# Тюнер, для rev 2.6 - stv0299, для 2.3 - mt312, у меня 2.6
modprobe stv0299
modprobe skystar2
Обязательно запускаем MAKEDEV-DVB.sh, идущий с дровами, который создаст все необходимые файлы устройств для работы. Если не забыли ударить в бубен - все должно получится, в dmesg будут такие строки
skystar2.c: FlexCopIIB(rev.195) chip found
skystar2.c: the chip has 38 hardware filters
DVB: registering new adapter (Technisat SkyStar2 driver).
probe_tuner: try to attach to Technisat SkyStar2 driver
stv0299.c: setup for tuner Samsung TBMU24112IMB
DVB: registering frontend 0:0 (STV0299/TSA5059/SL1935 based)...
Затем собираем еще утилиты с ЛинуксТВ.орг, опять же на всякий случай выкладываю и на своем сайте - linuxtv-dvb-apps-1.1.0.tar.bz2
Опять же стандартно, распаковываем, внимательно читаем ридми, делаем make.
Получаем утилиту util/scan/scan. Смотрим на www.kulichki.tv настройки транcпондера нашего спутник.
Для своего ExpressAM22 я выбрал самый "жирный" и сделал:
root@sky-cast:/usr/local/src/linuxtv-dvb-apps-1.1.0/util/scan# echo "S 11044000 V 29800000 AUTO" > exam22

root@sky-cast:/usr/local/src/linuxtv-dvb-apps-1.1.0/util/scan# ./scan exam22
scanning exam22
using '/dev/dvb/adapter0/frontend0' and '/dev/dvb/adapter0/demux0'
initial transponder 11044000 V 29800000 9
>>> tune to: 11044:v:0:29800
0x0000 0x0001: pmt_pid 0x0022 RSCC -- 1-Muz BY (running)
0x0000 0x0002: pmt_pid 0x0025 RSCC -- NEO TV (running)
0x0000 0x0003: pmt_pid 0x0028 RSCC -- CTC+2 (running)
0x0000 0x0004: pmt_pid 0x002b RSCC -- CTC+0 (running)
0x0000 0x0005: pmt_pid 0x002e RSCC -- MuzTV Love RV (running)
0x0000 0x0006: pmt_pid 0x003c RSCC -- Z+0 (running)
0x0000 0x0007: pmt_pid 0x0032 RSCC -- FNS (running)
0x0000 0x0008: pmt_pid 0x0036 RSCC -- Z+2 (running)
0x0000 0x000e: pmt_pid 0x0038 RSCC -- Radio Max (running)
0x0000 0x000f: pmt_pid 0x0103 RSCC -- Love Radio (running)
0x0000 0x0062: pmt_pid 0x0063 RSCC -- DATA KP (running)
0x0000 0x0063: pmt_pid 0x0105 RSCC -- DATA  CTC (running)
Network Name 'BEAR LAKE'
>>> tune to: 3625:h:0:29799
WARNING: >>> tuning failed!!!
>>> tune to: 3625:h:0:29799 (tuning failed)
WARNING: >>> tuning failed!!!
>>> tune to: 6000:h:0:33000
WARNING: >>> tuning failed!!!
>>> tune to: 6000:h:0:33000 (tuning failed)
WARNING: >>> tuning failed!!!
dumping lists (12 services)
1-Muz BY:11044:v:0:29800:35:33:1
NEO TV:11044:v:0:29800:38:36:2
CTC+2:11044:v:0:29800:41:39:3
CTC+0:11044:v:0:29800:44:42:4
MuzTV Love RV:11044:v:0:29800:47:48:5
Z+0:11044:v:0:29800:75:59:6
FNS:11044:v:0:29800:51:49:7
Z+2:11044:v:0:29800:55:53:8
Radio Max:11044:v:0:29800:0:58:14
Love Radio:11044:v:0:29800:0:65:15
DATA KP:11044:v:0:29800:100:0:98
DATA  CTC:11044:v:0:29800:0:0:99
Done.
Итак все нормально, дрова встали, утилиткой scan просканировали транспондер, теперь надо бы приступить собственно к трансляции видео и радио каналов в сеть.
Транслировать будем с помощью
VideoLanServer - проект VideoLAN.org Выкачиваем с сайта все необходимы исходники - вот отсюда http://videolan.org/streaming/download-vls-sources.html. Или с моего сайта, куда я бережно и аккуратно, загребущими руками все собрал :)
libdvb-0.2.2.tar.gz - Рекомендую именно эту библиотеку, несмотря на то что она старая и на сайте разработчиков есть версия поновее.
libdvdcss-1.2.8.tar.gz
libdvbpsi3-0.1.4.tar.gz
libdvdread-0.9.4.tar.gz
vls-0.5.6.tar.gz
Далее распаковываем и устанавливаем все библиотеки по порядку
tar xvzf libdvbpsi3-0.1.4.tar.gz
cd libdvbpsi3-0.1.4
./configure
make
make install
cd ..

tar xvzf libdvdcss-1.2.8.tar.gz
cd libdvdcss-1.2.8
./configure
make
make install
cd ..

tar xvzf libdvdread-0.9.4.tar.gz
cd libdvdread-0.9.4
./configure
make
make install
cd ..

tar xvzf libdvb-0.2.2.tar.gz
cd libdvb-0.2.2
make
make install
Тут все просто, осложнений никогда не было. Теперь собирем сам VLS, стандартно распаковывем, читаем всякие ридми, смотрим что предлагает ./configure --help и делаем примерно так:
./configure --prefix=/usr/local/vls --enable-dvb --enable-debug --with-libdvb=/usr/local/src/libdvb-0.2.2
make
make install
Все, вуаля. Софт собран, теперь осталось его настроить. Этот этап состоит из двух этапов:
1. Надо подготовить файл /root/.dvbrc
2. Надо настроить vls.cfg
Для первого шага нам понадобится вспомнить то, что нам выводила утилитка scan ^^смотри^^вверх^^ Создаем файл /root/.dvbrc. Забиваем шапку
LNB ID 0 TYPE 1  LOF1 9750000 LOF2 10600000 SLOF 11700000 DISEQCNR 0
  SAT ID 1 NAME "ExpressAM22" LNBID 0 FMIN 10700000 FMAX 12700000
Забиваем настройки нашего транспондера:
    TRANSPONDER ID 0001 SATID 1 TYPE 0 NAME "B4" FREQ 11044000 POL V SRATE 29800000 FEC 3/4
Синим отмечен ссылка на идентификатор появившийся ранее (в данном случае ид спутника), который везде будет одинаковым, зеленым - произвольный (по-моему :) ) параметр, красным - обязательно надо подставить свое значение
Теперь заносим каналы. Я выбрал для трансляции из списка тв каналы 1-Muz BY, NEO TV, CTC+2, и два радиоканала Radio Max и Love Radio, обзову их соответственно ch1, ch2, ch3 и r1, r2
Заносим тв канал Первый Белорусский - смотрим у него pmt_pid = 0x0022, шел он под номером 0x0001 (вторая колонка в выводе scan'а). Так и записываем:
      CHANNEL ID 1 NAME "ch1" SATID 1 TPID 0001 SID 1 TYPE 1 VPID 22 APID 20
APID я нашел в табличке каналов на кулички.тв - это ид аудиопотока. Если честно, я не уверен что его его обязательно указывать (проверить сейчас к сожалению не могу), но на всякий случай указываю*. Точно так же вбиваю остальные каналы (не забывая что всяческие ижентификаторы здесь - это шестнадцатеричные значения):
      CHANNEL ID 2 NAME "ch2" SATID 1 TPID 0001 SID 2 TYPE 1 VPID 25 APID 23
      CHANNEL ID 3 NAME "ch3" SATID 1 TPID 0001 SID 3 TYPE 1 VPID 28 APID 26
      CHANNEL ID e NAME "r1" SATID 1 TPID 0001 SID e TYPE 1 VPID 38
      CHANNEL ID f NAME "r2" SATID 1 TPID 0001 SID f TYPE 1 VPID 103
Если нужно - добавляем аналогично другой транспондер (не забывая поставить ему другой ID) и другие каналы на нем (опять же аккуратно везде проставив правильные идентификаторы).
Теперь необходимо настроить VLS. Логично предположить что мы каждый канал будем транслировать на свою мультикаст группу, к которой сможет присоединится любой желающий клиент. Ну и наверно понятно почему выбран именно мультикаст, на этом внимание я не останавливаю, каждый в зависимости от своей потребности может транслировать в сеть, выгодным ему образом. После кромсания оригинального /usr/local/vls/etc/videolan/vls/vls.cfg у меня осталось следующее:

# vls configuration file (Example)
# Секция выделенная серым практически не менялась, все осталось от оригинального, я даже пароли не менял ;)
# Application wide settings
BEGIN "Vls"
  LogFile       = "vls.log"             # log file
  ScreenLog     = "enable"              # log to the console
  SystemLog     = "enable"             # log to the systemlog
END

BEGIN "Groups"
  monitor       = "help|browse|logout"
  master        = "help|browse|start|resume|suspend|stop|shutdown|logout|config|program|input|channel|show"
END

BEGIN "Users"
  monitor       = "3BcKWoiQn0vi6:monitor"       # password is 'monitor'
  bozo          = "JKg2TpPerilnw:master"        # password is 'bozo'
END

BEGIN "Telnet"
  LocalPort     = "9999"                # Port to use for that purpose
  Use = "true"
END

#Ну вот здесь начинается самое интересное
BEGIN "Inputs"
#  local1       = "local"                # Local input example
#  kfir         = "video"               # Video input example (mpeg encoder)
  dvb1          = "dvb"                 # Video input example (DVB card)
END

# Video input (DVB) configuration
BEGIN "dvb1"
# --- Example:
  DeviceNumber = "0"                   # /dev/dvb/adapterN
  SendMethod   = "0"                   # 0 - Send All Pids
                                       # 1 - Send only MPEG2 datas
END

# Channel (outputs) declaration
BEGIN "Channels"
  multicast1     = "network"
  multicast2     = "network"
  multicast3     = "network"
  client1     = "network"
  client2     = "network"
END

BEGIN "multicast1"                        # multicast example
  Type    = "multicast"
  TTL     = "5"                          # Time To Live
  DstHost = "239.2.12.1"                # multicast address
  DstPort = "1234"                       # destination port
END

BEGIN "multicast2"                        # multicast example
  Type    = "multicast"
  TTL     = "5"                          # Time To Live
  DstHost = "239.2.12.2"                # multicast address
  DstPort = "1234"                       # destination port
END

BEGIN "multicast3"                        # multicast example
  Type    = "multicast"
  TTL     = "5"                          # Time To Live
  DstHost = "239.2.12.3"                # multicast address
  DstPort = "1234"                       # destination port
END

# чтобы было разнообразие и пришло понимание конфигов, 
# два тв канала я пускаю не мультикастом, а конкретным клиентам

BEGIN "client1"                          # unicast example
  DstHost = "172.20.1.8"                 # destination host
  DstPort = "1234"                       # destination port
END

BEGIN "client2"                          # unicast example
  DstHost = "172.20.20.2"                 # destination host
  DstPort = "1234"                       # destination port
END


BEGIN "LaunchOnStartUp"
  command1 = "start ch1 multicast1 dvb1" # первый тв-канал запускаем мультикастом
  command2 = "start r1 multicast2 dvb1"  # радио каналы тоже запускаем мультикастом
  command3 = "start r2 multicast3 dvb1"  # каждый на свою группу
  command4 = "start ch2 client1 dvb1"    #в конкретного client1 запускаем тв-каналом ch2
  command5 = "start ch3 client2 dvb1"    #в направлении client2 запускаем тв-канал ch3
END
Ну вот собственно вроде и все, запускаем /usr/local/vls/bin/vls -vvv чтобы увидеть как можно больше информации. Настраиваем автозагрузку - т.е. чтобы модули все при старте нужные поднимались, программа vlsd запускалась, все как обычно.

Настраиваем клиента vlc (Взять можно здесь http://www.videolan.org/vlc/ - его то уж я на своем сайте не держу). Программка вполне понятная с первого раза, но если непонятно - после установки, ловить мультикастовый поток надо так: в меню выбираете File -> Open Network Stream. Выбираете пункт UDP/RTP/Multicast, вбиваете адрес группы соответсвующий желаемому каналу, порт, и наслаждаетесь просмотром/прослушиванием.

P.S. Есть какая то проблема, которую пока решить не могу - одно из радио не слышно. Т.е. трансляция идет, пакетики в группу уходят, но клиент не слышит ничего. Когда я пробовал это радио пускать программой DVBRS под виндовс - для него выставлял галочку нечто вроде "исправлять ошибки в потоке". Вот кто бы подсказал как это сделать с помощью VLS & VLC - был бы очень благодарен.

P.P.S. Все вышенаписанное не претендует на аксиому, и вполне может содержать очень грубые ошибки (не про грамматические и орфографические идет речь - их точно море - пишу прямо на сервере в с шелл доступа :) ) - ткнете меня в них, или подскажете как сделать лучше - буду премного благодарен. Мелкие неточности уж простите пожалуйста :).

P.P.P.S. В качестве заключения скажу что теперь я озадачен еще одной проблемой. Хочу транслировать один из радиоканалов в другой сегмент сети (который связан довольно слабеньким по сравнению с эзернет :) каналом в 1 мбит) через несколько обычных рутеров. Радиоканал занимает примерно 256 кбит, т.е. будет отьедать четверть пропускной способности канала, на что в принципе можно пойти, хотя бы ради/на время эксперимента. Если получится - о результатах может напишу отдельную статейку о мультикаст рутинге :).

-----
* - Как показал дальнейший эксперимент, ни VPID, ни APID не является обязательным. Главное указать ID и SID