Первоначальная настройка и запуск вещания IPTV хорошо описана в статье «Прием спутниковых тв каналов в linux».
Основные проблемы при вещании IPTV: утечка памяти и пропадание видео или звука в одном из каналов.
Утечка памяти
Проблема утечки памяти решается либо 1) перезагрузкой демона vlc раз в день или больше по необходимости через crontab либо 2) периодической проверкой свободной памяти и перезагрузкой демона при уменьшении сводной памяти до определенного значения.
1)
crontab:
# Перезагружаем vlc в 3 часа ночи
0 3 * * * /home/desecho/vlc/vlc_regular_reload.sh
vlc_regular_reload.sh:
#!/bin/bash<br/>echo "`date`;VLC regular reload" >> /home/desecho/vlc/logs/vlc_restart.log<br/>/home/desecho/vlc/vlc_starter.sh<br/>2)
crontab:
#Проверяем каждые 5 минут
*/5 * * * * /home/desecho/vlc/memory_check.sh
memory_check.sh:
#!/bin/bash<br/>#Получаем переменную свободной памяти<br/>free_mem=$(free -m | grep ^M | awk -F' ' '{print $4 }')<br/>#Указываем предельное значение свободной памяти<br/>mem_limit=16<br/>#Если свободной памяти меньше или же она совпадает со значением предела то происходит перезагрузка демона<br/>if [ $free_mem -le $mem_limit ]<br/> then<br/> echo "`date`;Memory Overload" >> /home/desecho/vlc/logs/vlc_restart.log<br/> /home/desecho/vlc/vlc_starter.sh<br/>fi <br/>Пропадание видео или звука
Для решения проблемы необходимо периодически проверять наличие видео и звука в каналах.
Реализация скриптов на примере вещания двух каналов. Вещание идет в два потока — оригинального и сжатого. Иногда помогает перезагрузка проблемного канала, но иногда необходима полная перезагрузка демона.
Для работоспособности скрипта необходимо запустить следующие команды:
cp /usr/bin/vlc /usr/bin/vlc2<br/>touch /home/desecho/vlc/run.sh<br/>chmod +x /home/desecho/vlc/run.sh<br/>Скрипт запуска и перезагрузки каналов:
vlc_starter.sh:
#!/bin/bash<br/>echo "`date`;Reloaded" >> /home/desecho/vlc/logs/vlc_restart.log<br/> <br/>#Выключаем все запущенные vlc процессы<br/>killall -9 vlc<br/>#Запуск вещания<br/>vlc --no-stats -vvv --color --daemon --ttl 12 --ts-es-id-pid --dvb-adapter 0 --programs=13,14 dvb: --dvb-frequency=10995000 --dvb-srate=20000000 --dvb-voltage=13 --sout '#duplicate{dst=std{access=http,mux=asf,url=0.0.0.0:8001},select="program=13",dst=std{access=http,mux=asf,url=0.0.0.0:8002},select="program=14"}'<br/>#Ждем несколько секунд для инициализации вещания<br/>sleep 5<br/>#Вещаем сжатый поток в 820Kbit/s видео и 70Kbit/s аудио<br/>vlc http://127.0.0.1:8001 -vvv --daemon --color --sout '#transcode{vcodec=mp4v,vb=820,scale=1,acodec=mpga,ab=70,channels=1}:duplicate{dst=std{access=http,mux=asf,url=0.0.0.0:8011}'<br/>vlc http://127.0.0.1:8002 -vvv --daemon --color --sout '#transcode{vcodec=mp4v,vb=820,scale=1,acodec=mpga,ab=70,channels=1}:duplicate{dst=std{access=http,mux=asf,url=0.0.0.0:8012}'<br/>Скрипт проверки каналов:
vlc_restarter.sh:
#!/bin/bash<br/> <br/>#Запись канала<br/>#$1 - id порта сжатого канала<br/>function rec {<br/> #Запись видео<br/> b="vlc2 http://127.0.0.1:80$1 -vvv --color --daemon --noaudio --sout '#duplicate{dst=std{access=file,mux=asf,dst=\"/home/desecho/vlc/0$1.avi\"}}'"<br/> #Создание временного исполняемого файла - такой способ необходим из-за наличия в строке запуска vlc различных ковычек<br/> echo $b > /home/desecho/vlc/run.sh<br/> /home/desecho/vlc/run.sh<br/> #Запись аудио<br/> b="vlc2 http://127.0.0.1:80$1 -vvv --color --daemon --novideo --sout '#duplicate{dst=std{access=file,mux=asf,dst=\"/home/desecho/vlc/0$1.mp3\"}}'"<br/> echo $b > /home/desecho/vlc/run.sh<br/> /home/desecho/vlc/run.sh<br/> sleep 5<br/> killall -9 vlc2<br/>}<br/> <br/>#Полная перезагрузка vlc<br/>#$1 - имя канала<br/>function reload {<br/> echo "`date`;$1 - Reload" >> /home/desecho/vlc/logs/vlc_restart.log<br/> /home/desecho/vlc/vlc_starter.sh<br/>}<br/> <br/>#Проверка канала<br/>#$1 - id порта сжатого канала<br/>#$2 - имя канала<br/>function check {<br/> #Смотрим размер видео<br/> y="$(du /home/desecho/vlc/0$1.avi | grep -oE --regexp='[0-9]+' | sed -n '1p')"<br/> #Проверяем пустой ли файл<br/> if [ $y -gt 10 ] ; then<br/> x011=1<br/> else<br/> x011=0<br/> fi<br/> #Смотрим размер аудио<br/> y="$(du /home/desecho/vlc/0$1.mp3 | grep -oE --regexp='[0-9]+' | sed -n '1p')"<br/> if [ $y -gt 10 ] ; then<br/> x012=1<br/> else<br/> x012=0<br/> fi<br/> echo " $2 - $x011 $x012" >> /home/desecho/vlc/logs/vlc_restart.log<br/> let x01=x011+x012<br/> #Если отсутствует звук или видео, то переменная z=0<br/> if [ $x01 != 2 ]<br/> then<br/> z=0<br/> else<br/> z=1<br/> fi<br/>}<br/> <br/>#Полная проверка<br/>#$1 - id порта сжатого канала<br/>#$2 - имя канала<br/>function check_full {<br/> #Запись канала<br/> rec $1<br/> #Проверка на отсутствие видео или звука<br/> check $1 $2<br/> #Если видео и звук в норме то помечаем переменную z канала<br/> if [ $z = 1 ] ; then<br/> z[$1]=1<br/> fi<br/>}<br/> <br/>#Перезагрузка канала<br/>#$1 - id порта сжатого канала<br/>#$2 - имя канала<br/>#$3 - id порта исходного канала<br/>function restart {<br/> echo "`date`;$2 - Restart" >> /home/desecho/vlc/logs/vlc_restart.log<br/> #Выключение неработающего канала<br/> a="$(ps -C vlc -o '%p%a' | grep "http://127.0.0.1:80$3 -vvv --daemon --color --sout" | grep -oE --regexp='[0-9]+' | sed -n '1p')"<br/> kill $a<br/> #Перезапуск вещания канала<br/> b="vlc http://127.0.0.1:80$3 -vvv --daemon --color --sout '#transcode{vcodec=mp4v,vb=820,scale=1,acodec=mpga,ab=70,channels=1}:duplicate{dst=std{access=http,mux=asf,url=0.0.0.0:80$1}'"<br/> echo $b > /home/desecho/vlc/run.sh<br/> /home/desecho/vlc/run.sh<br/>}<br/> <br/>#Перезагрузка канала<br/>#$1 - id порта сжатого канала<br/>#$2 - имя канала<br/>#$3 - id порта исходного канала<br/>function fix {<br/> #Если нет видео или звука на канале то перезагружается канал<br/> if [ ${z[$1]} != 1 ] ; then<br/> restart $1 $2 $3<br/> sleep 5<br/> #повторная проверка<br/> check_full $1 $2<br/> fi<br/> #Если по прежнему нет звука то перезагружаем VLC полностью<br/> if [ ${z[$1]} != 1 ] ; then<br/> reload $2<br/> exit<br/>fi<br/>}<br/>#Присваиваем значение 0 по умолчанию переменным z каналов<br/>z[11]=0<br/>z[12]=0<br/> <br/>#Проверка канала на отсутствие видео/звука<br/>check_full 11 perviy<br/>#Перезагрузка канала при проблемах с видео/звуком<br/>fix 11 perviy 01<br/> <br/>check_full 12 rossiya<br/>fix 12 rossiya 02<br/> <br/>echo "`date`;DVB - Status: Stable" >> /home/desecho/vlc/logs/vlc_restart.log<br/>Осталось добавить запись в crontab:
*/5 * * * * /home/desecho/vlc/vlc_restarter.sh
В итоге получаем систему, которая автоматически восстановит вещание каналов при пропадании видео или аудио. Все действия скриптов восстановления вещания будут писаться в лог файл.
Удачного вещания!
UPD: Перенес в блог IPTV. P.S. Спасибо за карму!
UPD2: Для нейтрализации утечки памяти можно собрать vlc без флага «optimisememory» либо попробовать обновить vlc, см. статью «Вещание видеофайлов с помощью VLC multicast. С теорией». Спасибо Breaker.

