本文章转自开源团队未央千城的博客,全文如下:
近几年直播行业火爆,开源的直播软件解决方案有SRS(Simple-RTMP-Server)和nginx-rtmp-module,前者是国人发起的一个优秀的开源项目,目前国内很多公司都使用它作为直播解决方案,由C++编写;后者依赖Nginx,以第三方模块的方式提供直播功能,由C编写。SRS采用多线程方式,性能优秀,经受住了众多场景的考验,但是SRS3已经闭源(更正:是有一段时间闭源了,现在又开源了);nginx-rtmp-module是采用多进程方式,Nginx的性能优秀,但是据网友测试,nginx-rtmp-module的性能不如SRS,并且nginx-rtmp-module的作者已经很久没有更新版本了,支持的功能也有限,例如不支持HTTP方式的FLV直播,而这是国内直播行业普遍采用的方式;再如推流不支持upstream,无法分布式部署功能;还有饱受诟病的播放响应延迟时间很长的问题(即俗称的不能秒播)等。
我在nginx-rtmp-module的基础上实现了基于HTTP方式的FLV直播功能,支持GOP缓存,减少播放响应延迟时间;支持流式和Transfer-Encoding: chunked两种HTTP响应格式;修复nginx-rtmp-module没有listen配置项时,推流失败的问题;解决nginx-rtmp-module已知的bug,见nginx-http-flv-module,欢迎下载测试和修复bug。有问题或者建议,可以加Q群:711969608详聊。目前已经有厂商准备将本模块商用,目前已知有4家,陆续反馈过不少bug,修复后功能已经越来越稳定,在此表示感谢。
如果不想推流,可以用一个现成的直播地址rtmp://live.hkstv.hk.lxdns.com/live/hks。
典型的nginx.conf如下:
worker_processes 4; #Nginx开启4个子进程,子进程个数最好跟CPU的核心数一样
worker_cpu_affinity 0001 0010 0100 1000; #CPU的mask,子进程使用它来绑定CPU核心,避免进程切换造成性能损失
error_log logs/error.log error; #错误日志位置和日志级别,如果使用默认编译选项,位置为/usr/local/nginx/logs/error.log,error表示只打印错误日志
events {
worker_connections 1024; #Nginx处理的最大连接数
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 80; #Nginx监听的HTTP请求端口
location / {
root /var/www; #HTTP请求URL映射到服务器的位置
index index.html index.htm; #HTTP请求优先请求的文件,如http://localhost/,如果有index.html在/var/www目录下,那么请求的是/var/www/index.html
}
error_page 500 502 503 504 /50x.html; #如果遇到这些HTTP请求错误,Nginx返回50x.html的内容
location = /50x.html {
root html; #因为/配置了root /var/www,所以这儿html对应的是/var/www/html,所以50x.html的路径是/var/www/html/50x.html
}
location /live {
flv_live on; #当HTTP请求以/live结尾,匹配这儿,这个选项表示开启了flv直播播放功能
chunked on; #HTTP协议开启Transfer-Encoding: chunked;方式回复
}
}
}
rtmp_auto_push on; #因为Nginx可能开启多个子进程,这个选项表示推流时,媒体流会发布到多个子进程
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp; #多个子进程情况下,推流时,最开始只有一个子进程在竞争中接收到数据,然后它再relay给其他子进程,他们之间通过unix domain socket传输数据,这个选项表示unix domain socket的路径
rtmp {
out_queue 4096;
out_cork 8;
max_streams 64; #Nginx能接受的最大的推流数
server {
listen 1935; #Nginx监听的RTMP推流/拉流端口,可以省略,默认监听1935
application myapp {
live on; #当推流时,RTMP路径中的APP(RTMP中一个概念)匹配myapp时,开启直播
gop_cache on; #开启GOP(Group of Picture)缓存,播放器解码时,收到一个完整的GOP才会开始播放,这个是减少播放延迟的选项
pull rtmp://live.hkstv.hk.lxdns.com/live/hks; #如果懒得推流,那可以用这个,香港卫视的直播推流
}
application app1 {
proxy_pass rtmp://host(ip or domain name)[:host]/app2; #将推流反向代理到上游服务器,并将app1自动转化为app2
#proxy_pass rtmp://backend; #将推流反向代理到上游服务器,见upstream配置
}
}
server {
listen 1935;
server_name *.test.com; #或者www.test.*/www.test.com
application myapp {
live on;
gop_cache on;
}
}
upstream backend {
#开启负载均衡
server host1:port1;
server host2:port2;
}
}
启动Nginx,在vlc播放器中以“网络”方式打开媒体,填入http://localhost/live?stream=hks即可。
通用URL:http://example.com[:port]/dir?[srv=index&app=xxx&]stream=xxx。
如果http配置块里的监听端口不是80(默认),那么必须加上:port,如:8080。
如果rtmp配置块里有多个server配置块,如果想要播放的流的配置是在第二个server配置块中,那么必须加上srv=1(从0开始计数)。
如果rtmp配置块中的某个server块下有多个application配置块,如果想要播放的流的APP(RTMP中的一个概念)的名称是test,那么必须指明app=test,stream对应的是推流的名称。
推流的通用命令:ffmpeg -i -re xxx.mp4(或者与RTMP兼容的媒体文件)-vcodec copy -acodec copy -f flv rtmp://example.com[:port]/app/stream,后面也可以像HTTP的URL那样加参数,目前没仔细研究过,如果想推流到myapp,那么app换成myapp,stream随便取名,播放的时候跟它保持一致就可以。
其他的见nginx-rtmp-module的wiki说明。
测试效果图如下:
2017-09-18更新:
反向代理和负载均衡的功能已经基本可用,但是之前并为考虑到如果推流数很多,例如1000路推流,这可能对服务器造成沉重的负担。那为什么HTTP协议使用反向代理和负载均衡没有这个问题呢?那是因为HTTP请求占用的带宽很有限,负载瞬时可能很高,但是不会太持久。
2017-10-07更新:
虚拟主机功能已基本可用,即可以像HTTP配置那样配置server_name了,由于可以通过虚拟主机查找配置,所以不再支持参数srv=index,添加了一个参数port,如果不指定,默认为1935,用于指定以该port查找推流对应的配置。通用URL变为:http://example.com[:port]/dir?[port=xxx&]app=xxx&stream=xxx
2017-11-10更新:
近几年直播行业火爆,开源的直播软件
解决方案有SRS(Simple-RTMP-Server)和nginx-rtmp-module,前者是国人发起的一个优秀的开源项目,目前国内很多公司都使用它作为直播解决方案,由C++编写;后者依赖Nginx,以第三方模块的方式提供直播功能,由C编写。SRS采用多线程方式,性能优秀,经受住了众多场景的考验,但是SRS3已经闭源(更正:是有一段时间闭源了,现在又开源了);nginx-rtmp-module是采用多进程方式,Nginx的性能优秀,但是据网友测试,nginx-rtmp-module的性能不如SRS,并且nginx-rtmp-module的作者已经很久没有更新版本了,支持的功能也有限,例如不支持HTTP方式的FLV直播,而这是国内直播行业普遍采用的方式;再如推流不支持upstream,无法分布式部署功能;还有饱受诟病的播放响应延迟时间很长的问题(即俗称的不能秒播)等。
我在nginx-rtmp-module的基础上实现了基于HTTP方式的FLV直播功能,支持GOP缓存,减少播放响应延迟时间;支持流式和Transfer-Encoding: chunked两种HTTP响应格式;修复nginx-rtmp-module没有listen配置项时,推流失败的问题;解决nginx-rtmp-module已知的bug,见nginx-http-flv-module,欢迎下载测试和修复bug。有问题或者建议,可以加Q群:711969608详聊。目前已经有厂商准备将本模块商用,目前已知有4家,陆续反馈过不少bug,修复后功能已经越来越稳定,在此表示感谢。
近几年直播行业火爆,开源的直播软件解决方案有SRS(Simple-RTMP-Server)和nginx-rtmp-module,前者是国人发起的一个优秀的开源项目,目前国内很多公司都使用它作为直播解决方案,由C++编写;后者依赖Nginx,以第三方模块的方式提供直播功能,由C编写。SRS采用多线程方式,性能优秀,经受住了众多场景的考验,但是SRS3已经闭源(更正:是有一段时间闭源了,现在又开源了);nginx-rtmp-module是采用多进程方式,Nginx的性能优秀,但是据网友测试,nginx-rtmp-module的性能不如SRS,并且nginx-rtmp-module的作者已经很久没有更新版本了,支持的功能也有限,例如不支持HTTP方式的FLV直播,而这是国内直播行业普遍采用的方式;再如推流不支持upstream,无法分布式部署功能;还有饱受诟病的播放响应延迟时间很长的问题(即俗称的不能秒播)等。
我在nginx-rtmp-module的基础上实现了基于HTTP方式的FLV直播功能,支持GOP缓存,减少播放响应延迟时间;支持流式和Transfer-Encoding: chunked两种HTTP响应格式;修复nginx-rtmp-module没有listen配置项时,推流失败的问题;解决nginx-rtmp-module已知的bug,见nginx-http-flv-module,欢迎下载测试和修复bug。有问题或者建议,可以加Q群:711969608详聊。目前已经有厂商准备将本模块商用,目前已知有4家,陆续反馈过不少bug,修复后功能已经越来越稳定,在此表示感谢。
如果不想推流,可以用一个现成的直播地址rtmp://live.hkstv.hk.lxdns.com/live/hks。
典型的nginx.conf如下:
worker_processes 4; #Nginx开启4个子进程,子进程个数最好跟CPU的核心数一样
worker_cpu_affinity 0001 0010 0100 1000; #CPU的mask,子进程使用它来绑定CPU核心,避免进程切换造成性能损失
error_log logs/error.log error; #错误日志位置和日志级别,如果使用默认编译选项,位置为/usr/local/nginx/logs/error.log,error表示只打印错误日志
events {
worker_connections 1024; #Nginx处理的最大连接数
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 80; #Nginx监听的HTTP请求端口
location / {
root /var/www; #HTTP请求URL映射到服务器的位置
index index.html index.htm; #HTTP请求优先请求的文件,如http://localhost/,如果有index.html在/var/www目录下,那么请求的是/var/www/index.html
}
error_page 500 502 503 504 /50x.html; #如果遇到这些HTTP请求错误,Nginx返回50x.html的内容
location = /50x.html {
root html; #因为/配置了root /var/www,所以这儿html对应的是/var/www/html,所以50x.html的路径是/var/www/html/50x.html
}
location /live {
flv_live on; #当HTTP请求以/live结尾,匹配这儿,这个选项表示开启了flv直播播放功能
chunked on; #HTTP协议开启Transfer-Encoding: chunked;方式回复
}
}
}
rtmp_auto_push on; #因为Nginx可能开启多个子进程,这个选项表示推流时,媒体流会发布到多个子进程
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp; #多个子进程情况下,推流时,最开始只有一个子进程在竞争中接收到数据,然后它再relay给其他子进程,他们之间通过unix domain socket传输数据,这个选项表示unix domain socket的路径
rtmp {
out_queue 4096;
out_cork 8;
max_streams 64; #Nginx能接受的最大的推流数
server {
listen 1935; #Nginx监听的RTMP推流/拉流端口,可以省略,默认监听1935
application myapp {
live on; #当推流时,RTMP路径中的APP(RTMP中一个概念)匹配myapp时,开启直播
gop_cache on; #开启GOP(Group of Picture)缓存,播放器解码时,收到一个完整的GOP才会开始播放,这个是减少播放延迟的选项
pull rtmp://live.hkstv.hk.lxdns.com/live/hks; #如果懒得推流,那可以用这个,香港卫视的直播推流
}
application app1 {
proxy_pass rtmp://host(ip or domain name)[:host]/app2; #将推流反向代理到上游服务器,并将app1自动转化为app2
#proxy_pass rtmp://backend; #将推流反向代理到上游服务器,见upstream配置
}
}
server {
listen 1935;
server_name *.test.com; #或者www.test.*/www.test.com
application myapp {
live on;
gop_cache on;
}
}
upstream backend {
#开启负载均衡
server host1:port1;
server host2:port2;
}
}
启动Nginx,在vlc播放器中以“网络”方式打开媒体,填入http://localhost/live?stream=hks即可。
通用URL:http://example.com[:port]/dir?[srv=index&app=xxx&]stream=xxx。
如果http配置块里的监听端口不是80(默认),那么必须加上:port,如:8080。
如果rtmp配置块里有多个server配置块,如果想要播放的流的配置是在第二个server配置块中,那么必须加上srv=1(从0开始计数)。
如果rtmp配置块中的某个server块下有多个application配置块,如果想要播放的流的APP(RTMP中的一个概念)的名称是test,那么必须指明app=test,stream对应的是推流的名称。
推流的通用命令:ffmpeg -i -re xxx.mp4(或者与RTMP兼容的媒体文件)-vcodec copy -acodec copy -f flv rtmp://example.com[:port]/app/stream,后面也可以像HTTP的URL那样加参数,目前没仔细研究过,如果想推流到myapp,那么app换成myapp,stream随便取名,播放的时候跟它保持一致就可以。
其他的见nginx-rtmp-module的wiki说明。
测试效果图如下:
error_log logs/error.log error; #错误日志位置和日志级别,如果使用默认编译选项,位置为/usr/local/nginx/logs/error.log,error表示只打印错误日志
events {
worker_connections 1024; #Nginx处理的最大连接数
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 80; #Nginx监听的HTTP请求端口
location / {
root /var/www; #HTTP请求URL映射到服务器的位置
index index.html index.htm; #HTTP请求优先请求的文件,如http://localhost/,如果有index.html在/var/www目录下,那么请求的是/var/www/index.html
}
error_page 500 502 503 504 /50x.html; #如果遇到这些HTTP请求错误,Nginx返回50x.html的内容
location = /50x.html {
root html; #因为/配置了root /var/www,所以这儿html对应的是/var/www/html,所以50x.html的路径是/var/www/html/50x.html
}
location /live {
flv_live on; #当HTTP请求以/live结尾,匹配这儿,这个选项表示开启了flv直播播放功能
chunked on; #HTTP协议开启Transfer-Encoding: chunked;方式回复
}
}
}
rtmp_auto_push on; #因为Nginx可能开启多个子进程,这个选项表示推流时,媒体流会发布到多个子进程
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp; #多个子进程情况下,推流时,最开始只有一个子进程在竞争中接收到数据,然后它再relay给其他子进程,他们之间通过unix domain socket传输数据,这个选项表示unix domain socket的路径
rtmp {
out_queue 4096;
out_cork 8;
max_streams 64; #Nginx能接受的最大的推流数
server {
listen 1935; #Nginx监听的RTMP推流/拉流端口,可以省略,默认监听1935
application myapp {
live on; #当推流时,RTMP路径中的APP(RTMP中一个概念)匹配myapp时,开启直播
gop_cache on; #开启GOP(Group of Picture)缓存,播放器解码时,收到一个完整的GOP才会开始播放,这个是减少播放延迟的选项
pull rtmp://live.hkstv.hk.lxdns.com/live/hks; #如果懒得推流,那可以用这个,香港卫视的直播推流
}
application app1 {
proxy_pass rtmp://host(ip or domain name)[:host]/app2; #将推流反向代理到上游服务器,并将app1自动转化为app2
#proxy_pass rtmp://backend; #将推流反向代理到上游服务器,见upstream配置
}
}
server {
listen 1935;
server_name *.test.com; #或者www.test.*/www.test.com
application myapp {
live on;
gop_cache on;
}
}
upstream backend {
#开启负载均衡
server host1:port1;
server host2:port2;
}
}
启动Nginx,在vlc播放器中以“网络”方式打开媒体,填入http://localhost/live?stream=hks即可。
通用URL:http://example.com[:port]/dir?[srv=index&app=xxx&]stream=xxx。
如果http配置块里的监听端口不是80(默认),那么必须加上:port,如:8080。
如果rtmp配置块里有多个server配置块,如果想要播放的流的配置是在第二个server配置块中,那么必须加上srv=1(从0开始计数)。
如果rtmp配置块中的某个server块下有多个application配置块,如果想要播放的流的APP(RTMP中的一个概念)的名称是test,那么必须指明app=test,stream对应的是推流的名称。
推流的通用命令:ffmpeg -i -re xxx.mp4(或者与RTMP兼容的媒体文件)-vcodec copy -acodec copy -f flv rtmp://example.com[:port]/app/stream,后面也可以像HTTP的URL那样加参数,目前没仔细研究过,如果想推流到myapp,那么app换成myapp,stream随便取名,播放的时候跟它保持一致就可以。
其他的见nginx-rtmp-module的wiki说明。
测试效果图如下:
2017-09-18更新:
反向代理和负载均衡的功能已经基本可用,但是之前并为考虑到如果推流数很多,例如1000路推流,这可能对服务器造成沉重的负担。那为什么HTTP协议使用反向代理和负载均衡没有这个问题呢?那是因为HTTP请求占用的带宽很有限,负载瞬时可能很高,但是不会太持久。
2017-10-07更新:
虚拟主机功能已基本可用,即可以像HTTP配置那样配置server_name了,由于可以通过虚拟主机查找配置,所以不再支持参数srv=index,添加了一个参数port,如果不指定,默认为1935,用于指定以该port查找推流对应的配置。通用URL变为:http://example.com[:port]/dir?[port=xxx&]app=xxx&stream=xxx
2017-11-10更新:
car-eye 开源团队网址:www.car-eye.cn 加群:590411159