转载请注明出处:https://blog.csdn.net/impingo
项目地址:https://github.com/im-pingo/pingos
项目官网:http://pingos.io
在远古时代,互联网刚开始发展的时候,世界上出现了一种叫做IPC的东西,它可以通过TCP或者UDP将视频数据传送给播放器。开始的时候人们惊叹这种技术带来的便利,因为人们终于可以在自己电脑上安装播放器然后观看IPC捕获的画面。
随着互联网的普及和智能手机的普及,人们的欲望也在野蛮生长,终于他们不再满足于在固定的一台电脑前观看IPC监控的视频。而是希望随时随地可以看到想看的IPC直播内容。
有些厂商意识到了这一点,前些年各大安防厂商开始支持输出rtmp协议,这就很方便的能够与互联网对接。
更有一些互联网公司针对家用和商用场景直接就出了一些互联网安防设备,在他们平台申请个账号,购买设备直接联网。如360水滴摄像头、海康萤石等等。
但是由于世界上遗留的IPC设备实在太多,无法做到给每一台设备都实现rtmp协议,这种情况下就需要我们将IPC支持的rtsp协议转换成rtmp协议了。
支持rtmp协议的安防监控设备是这样接入流媒体服务器的:
不支持rtmp协议的安防设备是这样接入流媒体服务器的:
需要注意的是,图二中使用ffmpeg将rtsp协议转换成rtmp协议
为了方便实施,可以利用ffmpeg命令行工具直接做协议转换。
如下命令:
ffmpeg -i rtsp://xxxxxx -vcodec copy -acodec aac -f flv rtmp://ip/app/stream-name
这样做的问题在于,如果你的安防设备过多,你需要手动开启很多个ffmpeg任务。而且如果你新增或者减少一些设备,还要去修改你的ffmepg 任务,除非你去开发一套自动伸缩的系统来管理这些任务。
有没有一种比较简单,不需要开发工作又自动化的方式呢?有!!!
触发流程是这样的:
解释:
关键之处在于“双网卡rtmp服务器”,这台服务器的功能是能够拉取rtsp流,同时能够将rtsp协议转换成rtmp协议。
首先,搭建nginx-rtmp-module服务器,搭建流程参考我以前的博文分布式直播系统(二)【搭建单点rtmp\http-flv\hls流媒体服务器】。
exec_pull bash -c "ffmepg -i rtsp://$parg_ip/$parg_uri -vcodec copy -acodec aac -f flv rtmp://127.0.0.1/live/$name";
使用这个配置可以在有观众请求进来时,nginx-rtmp服务器向目IPC设备发起rtsp拉流,并且将rtsp协议转换成rtmp协议回推给本机。等待公网服务器过来拉流。
如果IPC设备rtsp地址为:rtsp://192.168.1.2/stream/1
双网卡rtmp服务器的公网地址为:34.2.1.2
公网rtmp服务器地址为:34.2.1.3
双网卡rtmp服务器配置模板如下:
user root;
daemon on;
master_process on;
worker_processes 1;
#worker_rlimit 4g;
#working_directory /usr/local/openresty/nginx/logs;
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
worker_rlimit_nofile 102400;
worker_rlimit_core 2G;
working_directory /tmp;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_listen unix:/tmp/http 80;
multi_listen unix:/tmp/rtmp 1935;
}
stream_zone buckets=1024 streams=4096;
rtmp {
log_format log_bandwidth '{"app":"$app","name":"$name","bitrate":$bitrate,"args":"$args","timestamp":$ntp,"ts":"$time_local","type":"$command","remote_addr":"$remote_addr","domain":"$domain"}';
access_log logs/bandwidth.log log_bandwidth trunc=60s;
server {
listen 1935;
serverid 000;
out_queue 2048;
application live {
rtmp_auto_pull on;
rtmp_auto_pull_port unix:/tmp/rtmp;
# live_record on;
#live_record_path /tmp/record;
# recorder r1{
# record all;
# record_path /tmp/record;
# }
exec_pull bash -c "ffmepg -i rtsp://$parg_ip/$parg_uri -vcodec copy -acodec aac -f flv rtmp://127.0.0.1/live/$name";
live on;
hls on;
hls_path /tmp/hls;
hls_fragment 4000ms;
hls_max_fragment 6000ms;
hls_playlist_length 12000ms;
hls_type event;
hls2memory on;
mpegts_cache_time 20s;
hls2_fragment 1300ms;
hls2_max_fragment 1600ms;
hls2_playlist_length 3900ms;
wait_key on;
wait_video on;
cache_time 3s;
low_latency off;
fix_timestamp 0s;
# h265 codecid, default 12
hevc_codecid 12;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_X-Forwarded-For" "$http_X-Real-IP" "$host"';
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#reset_server_name www.test1.com www.test2.com;
#gzip on;
server {
listen 80;
location /rtmp_stat {
rtmp_stat all;
rtmp_stat_stylesheet /stat.xsl;
}
location /xstat {
rtmp_stat all;
}
location /sys_stat {
sys_stat;
}
location /control {
rtmp_control all;
}
location /live {
flv_live 1935;
}
location /ts {
ts_live 1935 app=live;
}
location /hls {
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
expires -1;
add_header Cache-Control no-cache;
add_header 'Access-Control-Allow-Origin' '*';
}
location /hls2 {
hls2_live 1935 app=live;
add_header 'Access-Control-Allow-Origin' '*';
add_header Cache-Control no-cache;
}
location / {
chunked_transfer_encoding on;
root html/;
}
}
}
公网服务器配置模板:
user root;
daemon on;
master_process on;
worker_processes 1;
#worker_rlimit 4g;
#working_directory /usr/local/openresty/nginx/logs;
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
worker_rlimit_nofile 102400;
worker_rlimit_core 2G;
working_directory /tmp;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_listen unix:/tmp/http 80;
multi_listen unix:/tmp/rtmp 1935;
}
stream_zone buckets=1024 streams=4096;
rtmp {
log_format log_bandwidth '{"app":"$app","name":"$name","bitrate":$bitrate,"args":"$args","timestamp":$ntp,"ts":"$time_local","type":"$command","remote_addr":"$remote_addr","domain":"$domain"}';
access_log logs/bandwidth.log log_bandwidth trunc=60s;
server {
listen 1935;
serverid 000;
out_queue 2048;
application live {
rtmp_auto_pull on;
rtmp_auto_pull_port unix:/tmp/rtmp;
# live_record on;
#live_record_path /tmp/record;
# recorder r1{
# record all;
# record_path /tmp/record;
# }
# exec_publish bash -c "ffmepg -i rtmp://127.0.0.1/live/$name -c copy /tmp/mp4/$name-$starttime.mp4";
pull rtmp://34.2.1.2/live app=live; # 双网卡rtmp服务器地址
live on;
hls on;
hls_path /tmp/hls;
hls_fragment 4000ms;
hls_max_fragment 6000ms;
hls_playlist_length 12000ms;
hls_type event;
hls2memory on;
mpegts_cache_time 20s;
hls2_fragment 1300ms;
hls2_max_fragment 1600ms;
hls2_playlist_length 3900ms;
wait_key on;
wait_video on;
cache_time 3s;
low_latency off;
fix_timestamp 0s;
# h265 codecid, default 12
hevc_codecid 12;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_X-Forwarded-For" "$http_X-Real-IP" "$host"';
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#reset_server_name www.test1.com www.test2.com;
#gzip on;
server {
listen 80;
location /rtmp_stat {
rtmp_stat all;
rtmp_stat_stylesheet /stat.xsl;
}
location /xstat {
rtmp_stat all;
}
location /sys_stat {
sys_stat;
}
location /control {
rtmp_control all;
}
location /live {
flv_live 1935;
}
location /ts {
ts_live 1935 app=live;
}
location /hls {
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
expires -1;
add_header Cache-Control no-cache;
add_header 'Access-Control-Allow-Origin' '*';
}
location /hls2 {
hls2_live 1935 app=live;
add_header 'Access-Control-Allow-Origin' '*';
add_header Cache-Control no-cache;
}
location / {
chunked_transfer_encoding on;
root html/;
}
}
}
配置模板里和下面出现的ip地址和ipc的rtsp地址都是为了方便描述虚构的,你要根据自己的实际情况配置真实地址
从公网rtmp服务器播放视频:
rtmp://34.2.1.3/live/s0?ip=192.168.1.2&uri=/strea/0
http://34.2.1.3/live/s0?ip=192.168.1.2&uri=/strea/0
QQ交流群:697773082