streaming multicast IPTV to HLS (nginx+RTMP)
Получаем контент 239.192.1.1, 239.192.1.2 и 239.192.1.3. Будем раздавать его через WEB по протоколу HLS,
что позволяет смотреть видео не только на компьютере с flash, но и на
устройствах под управлением iOS(iPhone/iPad), а также на Android.
Для этого будем использовать nginx c поддержкой RTMP-модуля, модуль распространяется по лицензии BSD. Он собирается и работает под Linux и FreeBSD.
Собираем nginx с поддержкой RTMP-модуля:
cd NGINX source directory & run this:
RTMP поддерживает ограниченный набор кодеков, а для просмотра HLS на iPhone нужно кодировать в H264 и AAC.
Для multicast-потока потребуется перекодировка, для этого будем использовать FFMPEG.
nginx-rtmp.conf:
user www;
worker_processes 1;
worker_rlimit_nofile 65535;
worker_priority -5;
error_log /var/log/http/rtmp-error.log error;
events {
worker_connections 1024;
use kqueue; # freebsd specific
}
http {
include /usr/local/etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on; tcp_nopush on;
tcp_nodelay on;
reset_timedout_connection on;
server {
listen xx.219.128.139:80 default_server accept_filter=httpready rcvbuf=4096 sndbuf=262144 backlog=8192;
server_name "";
access_log /var/log/http/access-rtmp.log main buffer=16k;
location / {
root /var/www;
index index.html;
expires 30d;
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
index index.m3u8;
add_header Cache-Control no-cache;
alias /var/tmp/hls;
}
}
}
rtmp_auto_push on;
rtmp {
server {
listen 1935;
chunk_size 4096;
ping 30s;
notify_method get;
application iptv_backend {
live on;
allow publish 127.0.0.1;
deny publish all;
exec_static /usr/local/bin/ffmpeg -loglevel error -re -threads 0 -i udp://239.192.1.1:1234 -tune zerolatency -preset ultrafast -profile:v main -level 4.0 -c:v libx264 -vf yadif=0:-1:0 -c:a libfaac -ar 44100 -ac 2 -f flv rtmp:
//localhost/iptv/ch01 2>>/var/log/http/ffmpeg-ch01.log;
exec_static /usr/local/bin/ffmpeg -loglevel error -re -threads 0 -i udp://239.192.1.2:1234 -tune zerolatency -preset ultrafast -profile:v main -level 4.0 -c:v libx264 -vf yadif=0:-1:0 -c:a libfaac -ar 44100 -ac 2 -f flv rtmp:
//localhost/iptv/ch02 2>>/var/log/http/ffmpeg-ch02.log;
exec_static /usr/local/bin/ffmpeg -loglevel error -re -threads 0 -i udp://239.192.1.3:1234 -tune zerolatency -preset ultrafast -profile:v main -level 4.0 -c:v libx264 -vf yadif=0:-1:0 -c:a libfaac -ar 44100 -ac 2 -f flv rtmp:
//localhost/iptv/ch03 2>>/var/log/http/ffmpeg-ch03.log;
respawn on;
exec_kill_signal 9;
respawn_timeout 10s;
}
application iptv {
live on;
allow publish 127.0.0.1;
deny publish all;
hls on;
hls_type live;
hls_path /var/tmp/hls;
hls_fragment 5s;
hls_playlist_length 60s;
}
}
}
Чтобы не нагружать HDD, /var/tmp/hls разместим в RAM (TMPFS):
/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
tmpfs /var/tmp/hls tmpfs rw,noexec,size=1048576000 0 0
В результате даже при нереально высокой нагрузке на CPU, контент отдаётся вполне приемлемо.
last pid: 33377; load averages: 24.18, 19.76, 18.00 up 0+00:50:25 22:07:55
50 processes: 4 running, 46 sleeping
CPU: 94.6% user, 0.0% nice, 4.6% system, 0.8% interrupt, 0.0% idle
Mem: 1015M Active, 294M Inact, 457M Wired, 417M Buf, 2169M Free
В /var/www создаём тестовую страницу для проверки вещания index.html следующего содержания:
Для этого будем использовать nginx c поддержкой RTMP-модуля, модуль распространяется по лицензии BSD. Он собирается и работает под Linux и FreeBSD.
Собираем nginx с поддержкой RTMP-модуля:
cd NGINX source directory & run this:
./configure --add-module=/path/to/nginx-rtmp-module
make
make install
RTMP поддерживает ограниченный набор кодеков, а для просмотра HLS на iPhone нужно кодировать в H264 и AAC.
Для multicast-потока потребуется перекодировка, для этого будем использовать FFMPEG.
nginx-rtmp.conf:
user www;
worker_processes 1;
worker_rlimit_nofile 65535;
worker_priority -5;
error_log /var/log/http/rtmp-error.log error;
events {
worker_connections 1024;
use kqueue; # freebsd specific
}
http {
include /usr/local/etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on; tcp_nopush on;
tcp_nodelay on;
reset_timedout_connection on;
server {
listen xx.219.128.139:80 default_server accept_filter=httpready rcvbuf=4096 sndbuf=262144 backlog=8192;
server_name "";
access_log /var/log/http/access-rtmp.log main buffer=16k;
location / {
root /var/www;
index index.html;
expires 30d;
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
index index.m3u8;
add_header Cache-Control no-cache;
alias /var/tmp/hls;
}
}
}
rtmp_auto_push on;
rtmp {
server {
listen 1935;
chunk_size 4096;
ping 30s;
notify_method get;
application iptv_backend {
live on;
allow publish 127.0.0.1;
deny publish all;
exec_static /usr/local/bin/ffmpeg -loglevel error -re -threads 0 -i udp://239.192.1.1:1234 -tune zerolatency -preset ultrafast -profile:v main -level 4.0 -c:v libx264 -vf yadif=0:-1:0 -c:a libfaac -ar 44100 -ac 2 -f flv rtmp:
//localhost/iptv/ch01 2>>/var/log/http/ffmpeg-ch01.log;
exec_static /usr/local/bin/ffmpeg -loglevel error -re -threads 0 -i udp://239.192.1.2:1234 -tune zerolatency -preset ultrafast -profile:v main -level 4.0 -c:v libx264 -vf yadif=0:-1:0 -c:a libfaac -ar 44100 -ac 2 -f flv rtmp:
//localhost/iptv/ch02 2>>/var/log/http/ffmpeg-ch02.log;
exec_static /usr/local/bin/ffmpeg -loglevel error -re -threads 0 -i udp://239.192.1.3:1234 -tune zerolatency -preset ultrafast -profile:v main -level 4.0 -c:v libx264 -vf yadif=0:-1:0 -c:a libfaac -ar 44100 -ac 2 -f flv rtmp:
//localhost/iptv/ch03 2>>/var/log/http/ffmpeg-ch03.log;
respawn on;
exec_kill_signal 9;
respawn_timeout 10s;
}
application iptv {
live on;
allow publish 127.0.0.1;
deny publish all;
hls on;
hls_type live;
hls_path /var/tmp/hls;
hls_fragment 5s;
hls_playlist_length 60s;
}
}
}
Чтобы не нагружать HDD, /var/tmp/hls разместим в RAM (TMPFS):
/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
tmpfs /var/tmp/hls tmpfs rw,noexec,size=1048576000 0 0
В результате даже при нереально высокой нагрузке на CPU, контент отдаётся вполне приемлемо.
last pid: 33377; load averages: 24.18, 19.76, 18.00 up 0+00:50:25 22:07:55
50 processes: 4 running, 46 sleeping
CPU: 94.6% user, 0.0% nice, 4.6% system, 0.8% interrupt, 0.0% idle
Mem: 1015M Active, 294M Inact, 457M Wired, 417M Buf, 2169M Free
В /var/www создаём тестовую страницу для проверки вещания index.html следующего содержания:
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>IPTV</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> <script type="text/javascript" src="http://p.jwpcdn.com/6/10/jwplayer.js"></script> <script type="text/javascript"> $(document).ready(function() { if (navigator.userAgent.match(/android/i) != null) { jwplayer("videoPlayer").setup({ playlist: [ { title: "1tv", sources: [ { file: "http://xx.219.128.139/hls/ch01.m3u8" } ]},{ title: "1", sources: [ { file: "http://xx.219.128.139/hls/ch02.m3u8" } ]},{ title: "2", sources: [ { file: "http://xx.219.128.139/hls/ch03.m3u8" } ]},{ title: "3", sources: [ { file: "http://xx.219.128.139/hls/ch04.m3u8" } ]} ], androidhls: true, type: "mp4", primary: "html5", autostart: false, stretching: "fill", width: 920, height: 576, listbar: { position: "right", size: 200 } }); | |||||||||||||||||||||||||||||||||||||||||
|
Комментарии