0%

OBS推流,使用nginx-http-flv-module搭建流媒体服务器

0x00 nginx-http-flv-module简介

nginx-http-flv-module是一个基于nginx-rtmp-module的流媒体服务器模块,除了具有nginx-rtmp-module所包含的所有功能之外,还具有以下特性

功能 nginx-http-flv-module nginx-rtmp-module 备注
HTTP-FLV (播放) x 支持HTTPS-FLV和chunked回复
GOP缓存 x
虚拟主机 x
省略listen配置 见备注 配置中必须有一个listen
纯音频支持 见备注 wait_videowait_key开启后无法工作
reuseport支持 x
定时打印访问记录 x
JSON风格的stat x

其他详情特性请参照项目GitHub页面

0x01 依赖与环境

以博主使用的版本为例(其他版本未经测试,以下依赖的相应版本经过测试是没有问题的)

首先,去上面的GitHub页面下载模块

  • nginx-http-flv-module

服务器系统及中间件:

  • ubuntu_18_04_x64
  • nginx-1.16.1

依赖以及相应版本:

  • pcre-8.42
  • zlib-1.2.11
  • openssl-1.1.1a

0x02 编译与安装

将以上依赖与环境在您的服务器上准备好后,进行编译安装

注意,为防止出现意料之外的问题,建议将nginx删除后,重新编译安装

将以上依赖与环境放在同一目录下,在解压后的nginx目录下(configure所在文件夹)执行如下命令

1
./configure --with-http_ssl_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-openssl=../openssl-1.1.1a --with-pcre=../pcre-8.42 --with-zlib=../zlib-1.2.11 --add-module=../nginx-http-flv-module

之后编译安装

1
2
make
make install

0x03 修改nginx配置文件

安装完成后,切换到您的nginx工作目录下,找到配置文件打开(默认路径为/usr/local/nginx/conf/nginx.conf)

在末尾添加rtmp的配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;

rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;

log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用
log_size 1m; #log模块用来记录日志的缓冲区大小


server {
listen 1935;
server_name localhost; #用于虚拟主机名一致

application myapp {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
}

application flv {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
}

application hls {
live on;
hls on;
hls_path /tmp/hls;
}

application dash {
live on;
dash on;
dash_path /tmp/dash;
}
}
}

在http-server下添加location

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
location /live {
flv_live on; #打开HTTP播放FLV直播流功能
chunked_transfer_encoding on; #支持'Transfer-Encoding: chunked'方式回复

add_header 'Access-Control-Allow-Origin' '*'; #添加额外的HTTP头
add_header 'Access-Control-Allow-Credentials' 'true'; #添加额外的HTTP头
}

#以下hls按照需求添加

location /hls { #添加视频流存放地址。
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
#访问权限开启,否则访问这个地址会报403
autoindex on;
alias /usr/local/html/hls;#视频流存放地址,与上面的hls_path相对应,这里root和alias的区别可自行百度
expires -1;
add_header Cache-Control no-cache;
#防止跨域问题
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}

以下为博主的nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

#user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
worker_connections 1024;
}


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"';

#access_log logs/access.log main;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

#gzip on;

server {
listen 80;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
root html;
index index.html index.htm;
}

location /live {
flv_live on; #打开HTTP播放FLV直播流功能
chunked_transfer_encoding on; #支持'Transfer-Encoding: chunked'方式回复

add_header 'Access-Control-Allow-Origin' '*'; #添加额外的HTTP头
add_header 'Access-Control-Allow-Credentials' 'true'; #添加额外的HTTP头
}

location /hls { #添加视频流存放地址。
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
#访问权限开启,否则访问这个地址会报403
autoindex on;
alias /usr/local/html/hls;#视频流存放地址,与上面的hls_path相对应,这里root和alias的区别可自行百度
expires -1;
add_header Cache-Control no-cache;
#防止跨域问题
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}


# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;

# location / {
# root html;
# index index.html index.htm;
# }
#}


# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;

# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;

# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;

# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;

# location / {
# root html;
# index index.html index.htm;
# }
#}

}

rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;

rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;

log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用
log_size 1m; #log模块用来记录日志的缓冲区大小


server {
listen 1935;
server_name localhost; #用于虚拟主机名完全匹配

application myapp {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
}

application flv {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
}

application hls {
live on;
hls on;
hls_path /tmp/hls;
}

application dash {
live on;
dash on;
dash_path /tmp/dash;
}
}
}

在完成以上操作后,重启nginx

1
2
cd /usr/local/nginx/sbin/
./nginx -s reload

0x04 使用OBS进行推流

点击设置-推流,服务选择自定义,服务器按以下格式填入

1
rtmp://yourip/myapp

其中,myapp与刚刚的nginx配置文件中填写的application一致

串流密钥随意,博主这里是一个字母m(新版OBS不填推流会报错)

1
m

如下图所示,之后应用-确定

image.png

设置好来源后,点击开始推流即可,在OBS的左下角出现如下信息

image.png

0x05 观看推流效果

以下介绍两种直播观看方式,也可根据模块官方文档选择您喜欢的方式

1.播放器直接打开URL

以PotPlayer为例,主界面右击-打开-打开链接,打开如下url即可,端口port默认为1935,app与上面的推流地址的(这里都是myapp)一致,stream即为刚刚推流所使用的串流密钥

1
http://yourip/live?port=1935&app=myapp&stream=m
image.png

等待缓冲结束后即可看到所推流的内容

image.png

2.flv.js

使用flv,js直接在网页端播放推流内容

在flv.js的GitHub页面release下下载flv.min.js

创建html文件,博主示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<!DOCTYPE html>
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>flv.js demo</title>
<style>
.mainContainer {
display: block;
width: 1024px;
margin-left: auto;
margin-right: auto;
}

.urlInput {
display: block;
width: 100%;
margin-left: auto;
margin-right: auto;
margin-top: 8px;
margin-bottom: 8px;
}

.centeredVideo {
display: block;
width: 100%;
height: 576px;
margin-left: auto;
margin-right: auto;
margin-bottom: auto;
}

.controls {
display: block;
width: 100%;
text-align: left;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
<div class="mainContainer">
<video id="videoElement" class="centeredVideo" controls autoplay width="1024" height="576">Your browser is too old which doesn't support HTML5 video.</video>
</div>
<br>
<div class="controls">
<!--<button onclick="flv_load()">加载</button>-->
<button onclick="flv_start()">开始</button>
<button onclick="flv_pause()">暂停</button>
<button onclick="flv_destroy()">停止</button>
<input style="width:100px" type="text" name="seekpoint" />
<button onclick="flv_seekto()">跳转</button>
</div>
<script src="flv.min.js"></script>
<script>
var player = document.getElementById('videoElement');
if (flvjs.isSupported()) {
var flvPlayer = flvjs.createPlayer({
type: 'flv',
"isLive": true,
url: 'http://yourip/live?port=1935&app=myapp&stream=m', //修改为您的url

});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load(); //加载
flv_start();
}

function flv_start() {
player.play();
}

function flv_pause() {
player.pause();
}

function flv_destroy() {
player.pause();
player.unload();
player.detachMediaElement();
player.destroy();
player = null;
}

function flv_seekto() {
player.currentTime = parseFloat(document.getElementsByName('seekpoint')[0].value);
}
</script>
</body>

</html>

打开该html页面即可看到推流内容

image.png