[-]
[+]
|
Changed |
nginx.spec
|
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/README.md
^
|
@@ -71,9 +71,10 @@
make
make install
-See this article about building nginx-rtmp with HLS support:
-https://github.com/arut/nginx-rtmp-module/wiki/Building-nginx-rtmp-with-HLS-support
+Several versions of nginx (1.3.14 - 1.4.1) require http_ssl_module to be
+added as well:
+ ./configure --add-module=<path-to-nginx-rtmp-module> --with-http_ssl_module
### RTMP URL format
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/TODO
^
|
@@ -2,5 +2,4 @@
- akamai auth
- manual recorder custom file name
- bandwidth control (per-app & total)
-- DNS round-robin url
- multiple streams per connection
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/hls/ngx_rtmp_hls_module.c
^
|
@@ -739,7 +739,6 @@
ngx_rtmp_hls_ctx_t *ctx;
ngx_file_t file;
ssize_t ret;
- size_t len;
off_t offset;
u_char *p, *last, *end, *next, *pa;
ngx_rtmp_hls_frag_t *f;
@@ -795,8 +794,6 @@
last--;
}
- len = (size_t) (last - p);
-
#define NGX_RTMP_MSEQ "#EXT-X-MEDIA-SEQUENCE:"
#define NGX_RTMP_MSEQ_LEN (sizeof(NGX_RTMP_MSEQ) - 1)
@@ -866,8 +863,8 @@
ngx_log_debug6(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"hls: restore fragment '%*s' id=%uL, "
"duration=%.3f, frag=%uL, nfrags=%ui",
- len, p, f->id, f->duration, ctx->frag,
- ctx->nfrags);
+ (size_t) (last - p), p, f->id, f->duration,
+ ctx->frag, ctx->nfrags);
}
p = next;
@@ -1285,16 +1282,22 @@
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"hls: audio pts=%uL", pts);
+ if (b->last + 7 > b->end) {
+ ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "hls: not enough buffer for audio header");
+ return NGX_OK;
+ }
+
p = b->last;
b->last += 5;
/* copy payload */
- for (; in; in = in->next) {
+ for (; in && b->last < b->end; in = in->next) {
bsize = in->buf->last - in->buf->pos;
if (b->last + bsize > b->end) {
- break;
+ bsize = b->end - b->last;
}
b->last = ngx_cpymem(b->last, in->buf->pos, bsize);
@@ -1679,6 +1682,12 @@
if (ngx_read_dir(&dir) == NGX_ERROR) {
err = ngx_errno;
+ if (ngx_close_dir(&dir) == NGX_ERROR) {
+ ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno,
+ "hls: cleanup " ngx_close_dir_n " \"%V\" failed",
+ ppath);
+ }
+
if (err == NGX_ENOMOREFILES) {
return nentries - nerased;
}
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/ngx_rtmp_auto_push_module.c
^
|
@@ -309,7 +309,9 @@
u_char *p;
ngx_str_t *u;
ngx_pid_t pid;
- char *pname;
+ ngx_int_t npushed;
+ ngx_core_conf_t *ccf;
+ ngx_file_info_t fi;
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"auto_push: reconnect");
@@ -336,6 +338,7 @@
}
slot = ctx->slots;
+ npushed = 0;
for (n = 0; n < NGX_MAX_PROCESSES; ++n, ++slot) {
if (n == ngx_process_slot) {
@@ -347,21 +350,8 @@
continue;
}
- /*
- * This is a dirty way to skip "cache manager" and
- * "cache loader" processes when pushing streams.
- */
-
- pname = ngx_processes[n].name;
- if (ngx_strstr(pname, "cache")) {
- ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "auto_push: skip process slot=%i pid=%i "
- "name='%s' pname='%s'",
- n, (ngx_int_t) pid, ctx->name, pname);
- continue;
- }
-
if (*slot) {
+ npushed++;
continue;
}
@@ -373,6 +363,15 @@
"unix:%V/" NGX_RTMP_AUTO_PUSH_SOCKNAME ".%i",
&apcf->socket_dir, n);
*p = 0;
+
+ if (ngx_file_info(path + sizeof("unix:") - 1, &fi) != NGX_OK) {
+ ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "auto_push: " ngx_file_info_n " failed: "
+ "slot=%i pid=%P socket='%s'" "url='%V' name='%s'",
+ n, pid, path, u, ctx->name);
+ continue;
+ }
+
u->data = path;
u->len = p - path;
if (ngx_parse_url(s->connection->pool, &at.url) != NGX_OK) {
@@ -388,24 +387,54 @@
at.flash_ver.data = flash_ver;
at.flash_ver.len = p - flash_ver;
- ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "auto_push: connect slot=%i pid=%i socket='%s' "
- "name='%s' pname='%s'",
- n, (ngx_int_t) pid, path, ctx->name, pname);
+ ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "auto_push: connect slot=%i pid=%P socket='%s' name='%s'",
+ n, pid, path, ctx->name);
if (ngx_rtmp_relay_push(s, &name, &at) == NGX_OK) {
*slot = 1;
+ npushed++;
continue;
}
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "auto_push: connect failed: slot=%i pid=%i socket='%s'"
- "url='%V' name='%s' pname='%s'",
- n, (ngx_int_t) pid, path, u, ctx->name, pname);
+ ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "auto_push: connect failed: slot=%i pid=%P socket='%s'"
+ "url='%V' name='%s'",
+ n, pid, path, u, ctx->name);
+ }
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
+ ngx_core_module);
- if (!ctx->push_evt.timer_set) {
- ngx_add_timer(&ctx->push_evt, apcf->push_reconnect);
+ ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "auto_push: pushed=%i total=%i failed=%i",
+ npushed, ccf->worker_processes,
+ ccf->worker_processes - 1 - npushed);
+
+ if (ccf->worker_processes == npushed + 1) {
+ return;
+ }
+
+ /* several workers failed */
+
+ slot = ctx->slots;
+
+ for (n = 0; n < NGX_MAX_PROCESSES; ++n, ++slot) {
+ pid = ngx_processes[n].pid;
+
+ if (n == ngx_process_slot || *slot == 1 ||
+ pid == 0 || pid == NGX_INVALID_PID)
+ {
+ continue;
}
+
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "auto_push: connect failed: slot=%i pid=%P name='%s'",
+ n, pid, ctx->name);
+ }
+
+ if (!ctx->push_evt.timer_set) {
+ ngx_add_timer(&ctx->push_evt, apcf->push_reconnect);
}
}
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/ngx_rtmp_live_module.c
^
|
@@ -423,7 +423,7 @@
if (lacf->publish_notify) {
status[nstatus++] = ngx_rtmp_create_status(s,
"NetStream.Play.UnpublishNotify",
- "status", "Start publishing");
+ "status", "Stop publishing");
}
ngx_rtmp_live_set_status(s, control, status, nstatus, 0);
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/ngx_rtmp_mp4_module.c
^
|
@@ -355,7 +355,7 @@
? NULL : &ctx->tracks[ctx->ntracks];
if (ctx->track) {
- ngx_memzero(ctx->track, sizeof(ctx->track));
+ ngx_memzero(ctx->track, sizeof(*ctx->track));
ctx->track->id = ctx->ntracks;
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/ngx_rtmp_notify_module.c
^
|
@@ -10,6 +10,7 @@
#include "ngx_rtmp_cmd_module.h"
#include "ngx_rtmp_netcall_module.h"
#include "ngx_rtmp_record_module.h"
+#include "ngx_rtmp_relay_module.h"
static ngx_rtmp_connect_pt next_connect;
@@ -70,6 +71,7 @@
ngx_uint_t method;
ngx_msec_t update_timeout;
ngx_flag_t update_strict;
+ ngx_flag_t relay_redirect;
} ngx_rtmp_notify_app_conf_t;
@@ -84,6 +86,7 @@
u_char name[NGX_RTMP_MAX_NAME];
u_char args[NGX_RTMP_MAX_ARGS];
ngx_event_t update_evt;
+ time_t start;
} ngx_rtmp_notify_ctx_t;
@@ -180,6 +183,13 @@
offsetof(ngx_rtmp_notify_app_conf_t, update_strict),
NULL },
+ { ngx_string("notify_relay_redirect"),
+ NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_flag_slot,
+ NGX_RTMP_APP_CONF_OFFSET,
+ offsetof(ngx_rtmp_notify_app_conf_t, relay_redirect),
+ NULL },
+
ngx_null_command
};
@@ -230,6 +240,7 @@
nacf->method = NGX_CONF_UNSET;
nacf->update_timeout = NGX_CONF_UNSET;
nacf->update_strict = NGX_CONF_UNSET;
+ nacf->relay_redirect = NGX_CONF_UNSET;
return nacf;
}
@@ -258,6 +269,7 @@
ngx_conf_merge_msec_value(conf->update_timeout, prev->update_timeout,
30000);
ngx_conf_merge_value(conf->update_strict, prev->update_strict, 0);
+ ngx_conf_merge_value(conf->relay_redirect, prev->relay_redirect, 0);
return NGX_CONF_OK;
}
@@ -682,6 +694,7 @@
b = ngx_create_temp_buf(pool,
sizeof("&call=update") + sfx.len +
+ sizeof("&time=") + NGX_TIME_T_LEN +
sizeof("&name=") + name_len * 3 +
1 + args_len);
if (b == NULL) {
@@ -695,6 +708,10 @@
sizeof("&call=update") - 1);
b->last = ngx_cpymem(b->last, sfx.data, sfx.len);
+ b->last = ngx_cpymem(b->last, (u_char *) "&time=",
+ sizeof("&time=") - 1);
+ b->last = ngx_sprintf(b->last, "%T", ngx_cached_time->sec - ctx->start);
+
if (name_len) {
b->last = ngx_cpymem(b->last, (u_char*) "&name=", sizeof("&name=") - 1);
b->last = (u_char*) ngx_escape_uri(b->last, ctx->name, name_len,
@@ -962,9 +979,13 @@
ngx_rtmp_notify_publish_handle(ngx_rtmp_session_t *s,
void *arg, ngx_chain_t *in)
{
- ngx_rtmp_publish_t *v = arg;
- ngx_int_t rc;
- u_char name[NGX_RTMP_MAX_NAME];
+ ngx_rtmp_publish_t *v = arg;
+ ngx_int_t rc;
+ ngx_str_t local_name;
+ ngx_rtmp_relay_target_t target;
+ ngx_url_t *u;
+ ngx_rtmp_notify_app_conf_t *nacf;
+ u_char name[NGX_RTMP_MAX_NAME];
static ngx_str_t location = ngx_string("location");
@@ -974,19 +995,61 @@
return NGX_ERROR;
}
- if (rc == NGX_AGAIN) {
- ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "notify: publish redirect received");
+ if (rc != NGX_AGAIN) {
+ goto next;
+ }
- rc = ngx_rtmp_notify_parse_http_header(s, in, &location, name,
- sizeof(name) - 1);
- if (rc > 0) {
- *ngx_cpymem(v->name, name, rc) = 0;
- ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
- "notify: publish redirect to '%s'", v->name);
- }
+ /* HTTP 3xx */
+
+ ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "notify: publish redirect received");
+
+ rc = ngx_rtmp_notify_parse_http_header(s, in, &location, name,
+ sizeof(name) - 1);
+ if (rc <= 0) {
+ goto next;
}
+ if (ngx_strncasecmp(name, (u_char *) "rtmp://", 7)) {
+ *ngx_cpymem(v->name, name, rc) = 0;
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+ "notify: publish redirect to '%s'", v->name);
+ goto next;
+ }
+
+ /* push */
+
+ nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
+ if (nacf->relay_redirect) {
+ *ngx_cpymem(v->name, name, rc) = 0;
+ }
+
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "notify: push '%s' to '%*s'", v->name, rc, name);
+
+ local_name.data = v->name;
+ local_name.len = ngx_strlen(v->name);
+
+ ngx_memzero(&target, sizeof(target));
+
+ u = &target.url;
+ u->url = local_name;
+ u->url.data = name + 7;
+ u->url.len = rc - 7;
+ u->default_port = 1935;
+ u->uri_part = 1;
+ u->no_resolve = 1; /* want ip here */
+
+ if (ngx_parse_url(s->connection->pool, u) != NGX_OK) {
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+ "notify: push failed '%V'", &local_name);
+ return NGX_ERROR;
+ }
+
+ ngx_rtmp_relay_push(s, &local_name, &target);
+
+next:
+
return next_publish(s, v);
}
@@ -995,11 +1058,15 @@
ngx_rtmp_notify_play_handle(ngx_rtmp_session_t *s,
void *arg, ngx_chain_t *in)
{
- ngx_rtmp_play_t *v = arg;
- ngx_int_t rc;
- u_char name[NGX_RTMP_MAX_NAME];
+ ngx_rtmp_play_t *v = arg;
+ ngx_int_t rc;
+ ngx_str_t local_name;
+ ngx_rtmp_relay_target_t target;
+ ngx_url_t *u;
+ ngx_rtmp_notify_app_conf_t *nacf;
+ u_char name[NGX_RTMP_MAX_NAME];
- static ngx_str_t location = ngx_string("location");
+ static ngx_str_t location = ngx_string("location");
rc = ngx_rtmp_notify_parse_http_retcode(s, in);
if (rc == NGX_ERROR) {
@@ -1007,19 +1074,61 @@
return NGX_ERROR;
}
- if (rc == NGX_AGAIN) {
- ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
- "notify: play redirect received");
+ if (rc != NGX_AGAIN) {
+ goto next;
+ }
- rc = ngx_rtmp_notify_parse_http_header(s, in, &location, name,
- sizeof(name) - 1);
- if (rc > 0) {
- *ngx_cpymem(v->name, name, rc) = 0;
- ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
- "notify: play redirect to '%s'", v->name);
- }
+ /* HTTP 3xx */
+
+ ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
+ "notify: play redirect received");
+
+ rc = ngx_rtmp_notify_parse_http_header(s, in, &location, name,
+ sizeof(name) - 1);
+ if (rc <= 0) {
+ goto next;
+ }
+
+ if (ngx_strncasecmp(name, (u_char *) "rtmp://", 7)) {
+ *ngx_cpymem(v->name, name, rc) = 0;
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+ "notify: play redirect to '%s'", v->name);
+ goto next;
}
+ /* pull */
+
+ nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
+ if (nacf->relay_redirect) {
+ *ngx_cpymem(v->name, name, rc) = 0;
+ }
+
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+ "notify: pull '%s' from '%*s'", v->name, rc, name);
+
+ local_name.data = v->name;
+ local_name.len = ngx_strlen(v->name);
+
+ ngx_memzero(&target, sizeof(target));
+
+ u = &target.url;
+ u->url = local_name;
+ u->url.data = name + 7;
+ u->url.len = rc - 7;
+ u->default_port = 1935;
+ u->uri_part = 1;
+ u->no_resolve = 1; /* want ip here */
+
+ if (ngx_parse_url(s->connection->pool, u) != NGX_OK) {
+ ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
+ "notify: pull failed '%V'", &local_name);
+ return NGX_ERROR;
+ }
+
+ ngx_rtmp_relay_pull(s, &local_name, &target);
+
+next:
+
return next_play(s, v);
}
@@ -1132,6 +1241,8 @@
return;
}
+ ctx->start = ngx_cached_time->sec;
+
e = &ctx->update_evt;
e->data = s->connection;
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/ngx_rtmp_relay_module.c
^
|
@@ -342,6 +342,7 @@
ngx_rtmp_session_t *rs;
ngx_peer_connection_t *pc;
ngx_connection_t *c;
+ ngx_addr_t *addr;
ngx_pool_t *pool;
ngx_int_t rc;
ngx_str_t v, *uri;
@@ -438,18 +439,29 @@
if (pc == NULL) {
goto clear;
}
+
+ if (target->url.naddrs == 0) {
+ ngx_log_error(NGX_LOG_ERR, racf->log, 0,
+ "relay: no address");
+ goto clear;
+ }
+
+ /* get address */
+ addr = &target->url.addrs[target->counter % target->url.naddrs];
+ target->counter++;
+
/* copy log to keep shared log unchanged */
rctx->log = *racf->log;
pc->log = &rctx->log;
pc->get = ngx_rtmp_relay_get_peer;
pc->free = ngx_rtmp_relay_free_peer;
- pc->name = &target->url.host;
- pc->socklen = target->url.socklen;
+ pc->name = &addr->name;
+ pc->socklen = addr->socklen;
pc->sockaddr = (struct sockaddr *)ngx_palloc(pool, pc->socklen);
if (pc->sockaddr == NULL) {
goto clear;
}
- ngx_memcpy(pc->sockaddr, &target->url.sockaddr, pc->socklen);
+ ngx_memcpy(pc->sockaddr, addr->sockaddr, pc->socklen);
rc = ngx_event_connect_peer(pc);
if (rc != NGX_OK && rc != NGX_AGAIN ) {
|
[-]
[+]
|
Changed |
nginx-rtmp-module-0.9.19.tar.bz2/ngx_rtmp_relay_module.h
^
|
@@ -23,8 +23,9 @@
ngx_int_t start;
ngx_int_t stop;
- void *tag; /* usually module reference */
- void *data; /* module-specific data */
+ void *tag; /* usually module reference */
+ void *data; /* module-specific data */
+ ngx_uint_t counter; /* mutable connection counter */
} ngx_rtmp_relay_target_t;
|