mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-05-16 16:51:07 +02:00
this version compiles ok
This commit is contained in:
parent
f65f07deb3
commit
eacfd8fac4
|
@ -20,12 +20,9 @@ static void ngx_rtmp_netcall_recv(ngx_event_t *rev);
|
|||
static void ngx_rtmp_netcall_send(ngx_event_t *wev);
|
||||
|
||||
|
||||
ngx_str_t ngx_rtmp_netcall_content_type_urlencoded =
|
||||
ngx_string("application/x-www-form-urlencoded");
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_msec_t timeout;
|
||||
size_t bufsize;
|
||||
ngx_log_t *log;
|
||||
} ngx_rtmp_netcall_app_conf_t;
|
||||
|
||||
|
@ -38,11 +35,13 @@ typedef struct ngx_rtmp_netcall_session_s {
|
|||
void *arg;
|
||||
ngx_rtmp_netcall_handle_pt handle;
|
||||
ngx_rtmp_netcall_filter_pt filter;
|
||||
ngx_rtmp_netcall_sink_pt sink;
|
||||
ngx_chain_t *in;
|
||||
ngx_chain_t *inlast;
|
||||
ngx_chain_t *out;
|
||||
ngx_msec_t timeout;
|
||||
ngx_int_t detached;
|
||||
unsigned detached:1;
|
||||
size_t bufsize;
|
||||
} ngx_rtmp_netcall_session_t;
|
||||
|
||||
|
||||
|
@ -60,6 +59,13 @@ static ngx_command_t ngx_rtmp_netcall_commands[] = {
|
|||
offsetof(ngx_rtmp_netcall_app_conf_t, timeout),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("netcall_buffer"),
|
||||
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_RTMP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_rtmp_netcall_app_conf_t, bufsize),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
@ -103,6 +109,8 @@ ngx_rtmp_netcall_create_app_conf(ngx_conf_t *cf)
|
|||
}
|
||||
|
||||
nacf->timeout = NGX_CONF_UNSET_MSEC;
|
||||
nacf->bufsize = NGX_CONF_UNSET_SIZE;
|
||||
|
||||
nacf->log = &cf->cycle->new_log;
|
||||
|
||||
return nacf;
|
||||
|
@ -116,6 +124,7 @@ ngx_rtmp_netcall_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_rtmp_netcall_app_conf_t *conf = child;
|
||||
|
||||
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 10000);
|
||||
ngx_conf_merge_size_value(conf->bufsize, prev->bufsize, 1024);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -219,9 +228,11 @@ ngx_rtmp_netcall_create(ngx_rtmp_session_t *s, ngx_rtmp_netcall_init_t *ci)
|
|||
}
|
||||
|
||||
cs->timeout = cacf->timeout;
|
||||
cs->bufsize = cacf->bufsize;
|
||||
cs->url = ci->url;
|
||||
cs->session = s;
|
||||
cs->filter = ci->filter;
|
||||
cs->sink = ci->sink;
|
||||
cs->handle = ci->handle;
|
||||
if (cs->handle == NULL) {
|
||||
cs->detached = 1;
|
||||
|
@ -281,6 +292,7 @@ ngx_rtmp_netcall_close(ngx_connection_t *cc)
|
|||
ngx_pool_t *pool;
|
||||
ngx_rtmp_session_t *s;
|
||||
ngx_rtmp_netcall_ctx_t *ctx;
|
||||
ngx_buf_t *b;
|
||||
|
||||
cs = cc->data;
|
||||
|
||||
|
@ -294,6 +306,14 @@ ngx_rtmp_netcall_close(ngx_connection_t *cc)
|
|||
s = cs->session;
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_netcall_module);
|
||||
|
||||
if (cs->in && cs->sink) {
|
||||
cs->sink(cs->session, cs->in);
|
||||
|
||||
b = cs->in->buf;
|
||||
b->pos = b->last = b->start;
|
||||
|
||||
}
|
||||
|
||||
for(css = &ctx->cs; *css; css = &((*css)->next)) {
|
||||
if (*css == cs) {
|
||||
*css = cs->next;
|
||||
|
@ -301,9 +321,7 @@ ngx_rtmp_netcall_close(ngx_connection_t *cc)
|
|||
}
|
||||
}
|
||||
|
||||
if (cs->handle &&
|
||||
cs->handle(s, cs->arg, cs->in) != NGX_OK)
|
||||
{
|
||||
if (cs->handle && cs->handle(s, cs->arg, cs->in) != NGX_OK) {
|
||||
ngx_rtmp_finalize_session(s);
|
||||
}
|
||||
}
|
||||
|
@ -352,29 +370,43 @@ ngx_rtmp_netcall_recv(ngx_event_t *rev)
|
|||
|
||||
for ( ;; ) {
|
||||
|
||||
if (cs->inlast == NULL
|
||||
|| cs->inlast->buf->last == cs->inlast->buf->end)
|
||||
if (cs->inlast == NULL ||
|
||||
cs->inlast->buf->last == cs->inlast->buf->end)
|
||||
{
|
||||
cl = ngx_alloc_chain_link(cc->pool);
|
||||
if (cl == NULL) {
|
||||
ngx_rtmp_netcall_close(cc);
|
||||
return;
|
||||
}
|
||||
cl->next = NULL;
|
||||
if (cs->in && cs->sink) {
|
||||
if (!cs->detached) {
|
||||
if (cs->sink(cs->session, cs->in) != NGX_OK) {
|
||||
ngx_rtmp_netcall_close(cc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cl->buf = ngx_create_temp_buf(cc->pool, 1024);
|
||||
if (cl->buf == NULL) {
|
||||
ngx_rtmp_netcall_close(cc);
|
||||
return;
|
||||
}
|
||||
b = cs->in->buf;
|
||||
b->pos = b->last = b->start;
|
||||
|
||||
if (cs->in == NULL) {
|
||||
cs->in = cl;
|
||||
} else {
|
||||
cs->inlast->next = cl;
|
||||
}
|
||||
cl = ngx_alloc_chain_link(cc->pool);
|
||||
if (cl == NULL) {
|
||||
ngx_rtmp_netcall_close(cc);
|
||||
return;
|
||||
}
|
||||
|
||||
cs->inlast = cl;
|
||||
cl->next = NULL;
|
||||
|
||||
cl->buf = ngx_create_temp_buf(cc->pool, cs->bufsize);
|
||||
if (cl->buf == NULL) {
|
||||
ngx_rtmp_netcall_close(cc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cs->in == NULL) {
|
||||
cs->in = cl;
|
||||
} else {
|
||||
cs->inlast->next = cl;
|
||||
}
|
||||
|
||||
cs->inlast = cl;
|
||||
}
|
||||
}
|
||||
|
||||
b = cs->inlast->buf;
|
||||
|
@ -459,8 +491,9 @@ ngx_rtmp_netcall_send(ngx_event_t *wev)
|
|||
|
||||
|
||||
ngx_chain_t *
|
||||
ngx_rtmp_netcall_http_format_header(ngx_url_t *url, ngx_pool_t *pool,
|
||||
size_t content_length, ngx_str_t *content_type)
|
||||
ngx_rtmp_netcall_http_format_header(ngx_str_t *uri, ngx_str_t *host,
|
||||
ngx_pool_t *pool, size_t content_length,
|
||||
ngx_str_t *content_type)
|
||||
{
|
||||
ngx_chain_t *cl;
|
||||
ngx_buf_t *b;
|
||||
|
@ -480,8 +513,8 @@ ngx_rtmp_netcall_http_format_header(ngx_url_t *url, ngx_pool_t *pool,
|
|||
}
|
||||
|
||||
b = ngx_create_temp_buf(pool, sizeof(rq_tmpl)
|
||||
+ url->uri.len
|
||||
+ url->host.len
|
||||
+ uri->len
|
||||
+ host->len
|
||||
+ content_type->len
|
||||
+ 5);
|
||||
|
||||
|
@ -492,7 +525,7 @@ ngx_rtmp_netcall_http_format_header(ngx_url_t *url, ngx_pool_t *pool,
|
|||
cl->buf = b;
|
||||
|
||||
b->last = ngx_snprintf(b->last, b->end - b->last, rq_tmpl,
|
||||
&url->uri, &url->host, content_type, content_length);
|
||||
uri, host, content_type, content_length);
|
||||
|
||||
return cl;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
typedef ngx_chain_t * (*ngx_rtmp_netcall_create_pt)(ngx_rtmp_session_t *s,
|
||||
void *arg, ngx_pool_t *pool);
|
||||
typedef ngx_int_t (*ngx_rtmp_netcall_filter_pt)(ngx_chain_t *in);
|
||||
typedef ngx_int_t (*ngx_rtmp_netcall_sink_pt)(ngx_rtmp_session_t *s,
|
||||
ngx_chain_t *in);
|
||||
typedef ngx_int_t (*ngx_rtmp_netcall_handle_pt)(ngx_rtmp_session_t *s,
|
||||
void *arg, ngx_chain_t *in);
|
||||
|
||||
|
@ -32,6 +34,7 @@ typedef struct {
|
|||
ngx_url_t *url;
|
||||
ngx_rtmp_netcall_create_pt create;
|
||||
ngx_rtmp_netcall_filter_pt filter;
|
||||
ngx_rtmp_netcall_sink_pt sink;
|
||||
ngx_rtmp_netcall_handle_pt handle;
|
||||
void *arg;
|
||||
size_t argsize;
|
||||
|
@ -41,14 +44,13 @@ typedef struct {
|
|||
ngx_int_t ngx_rtmp_netcall_create(ngx_rtmp_session_t *s,
|
||||
ngx_rtmp_netcall_init_t *ci);
|
||||
|
||||
extern ngx_str_t ngx_rtmp_netcall_content_type_urlencoded;
|
||||
|
||||
|
||||
/* HTTP handling */
|
||||
ngx_chain_t * ngx_rtmp_netcall_http_format_session(ngx_rtmp_session_t *s,
|
||||
ngx_pool_t *pool);
|
||||
ngx_chain_t * ngx_rtmp_netcall_http_format_header(ngx_url_t *url,
|
||||
ngx_pool_t *pool, size_t content_length, ngx_str_t *content_type);
|
||||
ngx_chain_t * ngx_rtmp_netcall_http_format_header(ngx_str_t *uri,
|
||||
ngx_str_t *host, ngx_pool_t *pool, size_t content_length,
|
||||
ngx_str_t *content_type);
|
||||
ngx_chain_t * ngx_rtmp_netcall_http_skip_header(ngx_chain_t *in);
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@ static ngx_int_t ngx_rtmp_notify_done(ngx_rtmp_session_t *s, char *cbname,
|
|||
ngx_url_t *url);
|
||||
|
||||
|
||||
ngx_str_t ngx_rtmp_notify_urlencoded =
|
||||
ngx_string("application/x-www-form-urlencoded");
|
||||
|
||||
|
||||
#define NGX_RTMP_NOTIFY_PUBLISHING 0x01
|
||||
#define NGX_RTMP_NOTIFY_PLAYING 0x02
|
||||
|
||||
|
@ -190,6 +194,7 @@ ngx_rtmp_notify_publish_create(ngx_rtmp_session_t *s, void *arg,
|
|||
ngx_chain_t *hl, *cl, *pl;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *addr_text;
|
||||
ngx_url_t *url;
|
||||
size_t name_len, type_len, args_len;
|
||||
|
||||
nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
|
||||
|
@ -244,9 +249,10 @@ ngx_rtmp_notify_publish_create(ngx_rtmp_session_t *s, void *arg,
|
|||
}
|
||||
|
||||
/* HTTP header */
|
||||
hl = ngx_rtmp_netcall_http_format_header(nacf->url[NGX_RTMP_NOTIFY_PUBLISH],
|
||||
url = nacf->url[NGX_RTMP_NOTIFY_PUBLISH];
|
||||
hl = ngx_rtmp_netcall_http_format_header(&url->uri, &url->host,
|
||||
pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
|
||||
&ngx_rtmp_netcall_content_type_urlencoded);
|
||||
&ngx_rtmp_notify_urlencoded);
|
||||
|
||||
if (hl == NULL) {
|
||||
return NULL;
|
||||
|
@ -270,6 +276,7 @@ ngx_rtmp_notify_play_create(ngx_rtmp_session_t *s, void *arg,
|
|||
ngx_chain_t *hl, *cl, *pl;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *addr_text;
|
||||
ngx_url_t *url;
|
||||
size_t name_len, args_len;
|
||||
|
||||
nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
|
||||
|
@ -324,9 +331,10 @@ ngx_rtmp_notify_play_create(ngx_rtmp_session_t *s, void *arg,
|
|||
}
|
||||
|
||||
/* HTTP header */
|
||||
hl = ngx_rtmp_netcall_http_format_header(nacf->url[NGX_RTMP_NOTIFY_PLAY],
|
||||
url = nacf->url[NGX_RTMP_NOTIFY_PLAY];
|
||||
hl = ngx_rtmp_netcall_http_format_header(&url->uri, &url->host,
|
||||
pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
|
||||
&ngx_rtmp_netcall_content_type_urlencoded);
|
||||
&ngx_rtmp_notify_urlencoded);
|
||||
|
||||
if (hl == NULL) {
|
||||
return NULL;
|
||||
|
@ -401,9 +409,9 @@ ngx_rtmp_notify_done_create(ngx_rtmp_session_t *s, void *arg,
|
|||
}
|
||||
|
||||
/* HTTP header */
|
||||
hl = ngx_rtmp_netcall_http_format_header(ds->url, pool,
|
||||
cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
|
||||
&ngx_rtmp_netcall_content_type_urlencoded);
|
||||
hl = ngx_rtmp_netcall_http_format_header(&ds->url->uri, &ds->url->host,
|
||||
pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
|
||||
&ngx_rtmp_notify_urlencoded);
|
||||
|
||||
if (hl == NULL) {
|
||||
return NULL;
|
||||
|
@ -428,6 +436,7 @@ ngx_rtmp_notify_record_done_create(ngx_rtmp_session_t *s, void *arg,
|
|||
ngx_chain_t *hl, *cl, *pl;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *addr_text;
|
||||
ngx_url_t *url;
|
||||
size_t name_len, args_len;
|
||||
|
||||
nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
|
||||
|
@ -489,10 +498,10 @@ ngx_rtmp_notify_record_done_create(ngx_rtmp_session_t *s, void *arg,
|
|||
}
|
||||
|
||||
/* HTTP header */
|
||||
hl = ngx_rtmp_netcall_http_format_header(
|
||||
nacf->url[NGX_RTMP_NOTIFY_RECORD_DONE],
|
||||
url = nacf->url[NGX_RTMP_NOTIFY_RECORD_DONE];
|
||||
hl = ngx_rtmp_netcall_http_format_header(&url->uri, &url->host,
|
||||
pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
|
||||
&ngx_rtmp_netcall_content_type_urlencoded);
|
||||
&ngx_rtmp_notify_urlencoded);
|
||||
|
||||
if (hl == NULL) {
|
||||
return NULL;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "ngx_rtmp_play_module.h"
|
||||
#include "ngx_rtmp_cmd_module.h"
|
||||
#include "ngx_rtmp_netcall_module.h"
|
||||
#include "ngx_rtmp_streams.h"
|
||||
|
||||
|
||||
|
@ -14,6 +15,8 @@ static ngx_rtmp_seek_pt next_seek;
|
|||
static ngx_rtmp_pause_pt next_pause;
|
||||
|
||||
|
||||
static char *ngx_rtmp_play_url(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static void *ngx_rtmp_play_create_main_conf(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_rtmp_play_postconfiguration(ngx_conf_t *cf);
|
||||
static void * ngx_rtmp_play_create_app_conf(ngx_conf_t *cf);
|
||||
|
@ -24,15 +27,29 @@ static ngx_int_t ngx_rtmp_play_done(ngx_rtmp_session_t *s);
|
|||
static ngx_int_t ngx_rtmp_play_start(ngx_rtmp_session_t *s, double timestamp);
|
||||
static ngx_int_t ngx_rtmp_play_stop(ngx_rtmp_session_t *s);
|
||||
static void ngx_rtmp_play_send(ngx_event_t *e);
|
||||
static ngx_int_t ngx_rtmp_play_open(ngx_rtmp_session_t *s, double start);
|
||||
static ngx_int_t ngx_rtmp_play_remote_handle(ngx_rtmp_session_t *s,
|
||||
void *arg, ngx_chain_t *in);
|
||||
static ngx_chain_t * ngx_rtmp_play_remote_create(ngx_rtmp_session_t *s,
|
||||
void *arg, ngx_pool_t *pool);
|
||||
static ngx_int_t ngx_rtmp_play_open_remote(ngx_rtmp_session_t *s,
|
||||
ngx_rtmp_play_t *v);
|
||||
|
||||
|
||||
static ngx_command_t ngx_rtmp_play_commands[] = {
|
||||
|
||||
{ ngx_string("play"),
|
||||
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
|
||||
ngx_rtmp_play_url,
|
||||
NGX_RTMP_APP_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("play_temp_path"),
|
||||
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_str_slot,
|
||||
NGX_RTMP_APP_CONF_OFFSET,
|
||||
offsetof(ngx_rtmp_play_app_conf_t, root),
|
||||
offsetof(ngx_rtmp_play_app_conf_t, temp_path),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
|
@ -111,6 +128,7 @@ ngx_rtmp_play_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_rtmp_play_app_conf_t *conf = child;
|
||||
|
||||
ngx_conf_merge_str_value(conf->root, prev->root, "");
|
||||
ngx_conf_merge_str_value(conf->temp_path, prev->temp_path, "/tmp");
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -352,7 +370,6 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
|
|||
ngx_rtmp_play_app_conf_t *pacf;
|
||||
ngx_rtmp_play_ctx_t *ctx;
|
||||
u_char *p;
|
||||
ngx_event_t *e;
|
||||
ngx_rtmp_play_fmt_t *fmt, **pfmt;
|
||||
ngx_str_t *pfx, *sfx;
|
||||
ngx_str_t name;
|
||||
|
@ -457,17 +474,46 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
|
|||
p = ngx_snprintf(path, sizeof(path), "%V/%V%V", &pacf->root, &name, sfx);
|
||||
*p = 0;
|
||||
|
||||
ctx->file.fd = NGX_INVALID_FILE;
|
||||
|
||||
if (pacf->url) {
|
||||
return ngx_rtmp_play_open_remote(s, v);
|
||||
}
|
||||
|
||||
/* open local */
|
||||
|
||||
ctx->file.fd = ngx_open_file(path, NGX_FILE_RDONLY, NGX_FILE_OPEN,
|
||||
NGX_FILE_DEFAULT_ACCESS);
|
||||
|
||||
if (ctx->file.fd == NGX_INVALID_FILE) {
|
||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno,
|
||||
"play: error opening file '%s'", path);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||
"play: opened file '%s'", path);
|
||||
"play: opened local file '%s'", path);
|
||||
|
||||
if (ngx_rtmp_play_open(s, v->start) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
next:
|
||||
return next_play(s, v);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_play_open(ngx_rtmp_session_t *s, double start)
|
||||
{
|
||||
ngx_rtmp_play_ctx_t *ctx;
|
||||
ngx_event_t *e;
|
||||
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
|
||||
|
||||
if (ctx->file.fd == NGX_INVALID_FILE) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
e = &ctx->send_evt;
|
||||
e->data = s;
|
||||
|
@ -480,12 +526,247 @@ ngx_rtmp_play_play(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_rtmp_play_start(s, v->start) != NGX_OK) {
|
||||
if (ngx_rtmp_play_start(s, start) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
next:
|
||||
return next_play(s, v);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_chain_t *
|
||||
ngx_rtmp_play_remote_create(ngx_rtmp_session_t *s, void *arg, ngx_pool_t *pool)
|
||||
{
|
||||
ngx_rtmp_play_t *v = arg;
|
||||
|
||||
ngx_rtmp_play_app_conf_t *pacf;
|
||||
ngx_chain_t *hl, *cl, *pl;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *addr_text, uri;
|
||||
u_char *p;
|
||||
size_t name_len, args_len;
|
||||
static ngx_str_t text_plain = ngx_string("text/plain");
|
||||
|
||||
pacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_play_module);
|
||||
|
||||
/* common variables */
|
||||
cl = ngx_rtmp_netcall_http_format_session(s, pool);
|
||||
|
||||
if (cl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* publish variables */
|
||||
pl = ngx_alloc_chain_link(pool);
|
||||
|
||||
if (pl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name_len = ngx_strlen(v->name);
|
||||
args_len = ngx_strlen(v->args);
|
||||
addr_text = &s->connection->addr_text;
|
||||
|
||||
b = ngx_create_temp_buf(pool,
|
||||
sizeof("&addr=") + addr_text->len +
|
||||
1 + args_len);
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pl->buf = b;
|
||||
|
||||
b->last = ngx_cpymem(b->last, (u_char*)"&addr=", sizeof("&addr=") -1);
|
||||
b->last = (u_char*)ngx_escape_uri(b->last, addr_text->data,
|
||||
addr_text->len, 0);
|
||||
|
||||
if (args_len) {
|
||||
*b->last++ = '&';
|
||||
b->last = (u_char *)ngx_cpymem(b->last, v->args, args_len);
|
||||
}
|
||||
|
||||
/* create uri */
|
||||
uri.len = pacf->url->uri.len + name_len;
|
||||
uri.data = ngx_palloc(pool, uri.len);
|
||||
|
||||
p = ngx_cpymem(uri.data, pacf->url->uri.data, pacf->url->uri.len);
|
||||
ngx_memcpy(p, v->name, name_len);
|
||||
|
||||
/* HTTP header */
|
||||
hl = ngx_rtmp_netcall_http_format_header(&uri, &pacf->url->host,
|
||||
pool, cl->buf->last - cl->buf->pos + (pl->buf->last - pl->buf->pos),
|
||||
&text_plain);
|
||||
|
||||
if (hl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hl->next = cl;
|
||||
cl->next = pl;
|
||||
pl->next = NULL;
|
||||
|
||||
return hl;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_play_remote_handle(ngx_rtmp_session_t *s, void *arg, ngx_chain_t *in)
|
||||
{
|
||||
ngx_rtmp_play_t *v = arg;
|
||||
|
||||
if (ngx_rtmp_play_open(s, v->start) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return next_play(s, (ngx_rtmp_play_t *)arg);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_play_remote_sink(ngx_rtmp_session_t *s, ngx_chain_t *in)
|
||||
{
|
||||
ngx_rtmp_play_ctx_t *ctx;
|
||||
ngx_buf_t *b;
|
||||
ngx_int_t rc;
|
||||
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
|
||||
|
||||
/* skip HTTP header */
|
||||
for (; in && ctx->ncrs != 2; in = in->next) {
|
||||
b = in->buf;
|
||||
|
||||
for (; b->pos != b->last && ctx->ncrs != 2; ++b->pos) {
|
||||
switch (*b->pos) {
|
||||
case '\n':
|
||||
++ctx->ncrs;
|
||||
break;
|
||||
case '\r':
|
||||
break;
|
||||
default:
|
||||
ctx->ncrs = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write to temp file */
|
||||
for (; in; in = in->next) {
|
||||
b = in->buf;
|
||||
|
||||
if (b->pos == b->last) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = ngx_write_fd(ctx->file.fd, b->pos, b->last - b->pos);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_log_error(NGX_LOG_INFO, s->connection->log, ngx_errno,
|
||||
"play: error writing to temp file");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_play_open_remote(ngx_rtmp_session_t *s, ngx_rtmp_play_t *v)
|
||||
{
|
||||
ngx_rtmp_play_app_conf_t *pacf;
|
||||
ngx_rtmp_play_ctx_t *ctx;
|
||||
ngx_rtmp_netcall_init_t ci;
|
||||
u_char *p;
|
||||
ngx_err_t err;
|
||||
static u_char path[NGX_MAX_PATH];
|
||||
static ngx_uint_t counter;
|
||||
|
||||
pacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_play_module);
|
||||
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
|
||||
|
||||
for ( ;; ) {
|
||||
p = ngx_snprintf(path, sizeof(path), "%V/nginx-rtmp-play%ui",
|
||||
&pacf->temp_path, counter++);
|
||||
*p = 0;
|
||||
|
||||
ctx->file.fd = ngx_open_tempfile(path, 0, 0);
|
||||
|
||||
if (ctx->file.fd != NGX_INVALID_FILE) {
|
||||
break;
|
||||
}
|
||||
|
||||
err = ngx_errno;
|
||||
|
||||
if (err != NGX_EEXIST) {
|
||||
ngx_log_error(NGX_LOG_INFO, s->connection->log, err,
|
||||
"play: failed to create temp file");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_memzero(&ci, sizeof(ci));
|
||||
|
||||
ci.url = pacf->url;;
|
||||
ci.create = ngx_rtmp_play_remote_create;
|
||||
ci.sink = ngx_rtmp_play_remote_sink;
|
||||
ci.handle = ngx_rtmp_play_remote_handle;
|
||||
ci.arg = v;
|
||||
ci.argsize = sizeof(*v);
|
||||
|
||||
return ngx_rtmp_netcall_create(s, &ci);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_rtmp_play_url(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_rtmp_play_app_conf_t *pacf;
|
||||
ngx_str_t url;
|
||||
ngx_url_t *u;
|
||||
size_t add;
|
||||
ngx_str_t *value;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_strncasecmp(value[1].data, (u_char *) "http://", 7)) {
|
||||
|
||||
/* local file */
|
||||
|
||||
pacf->root = value[1];
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
/* http case */
|
||||
|
||||
url = value[1];
|
||||
|
||||
add = sizeof("http://") - 1;
|
||||
|
||||
url.data += add;
|
||||
url.len -= add;
|
||||
|
||||
u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t));
|
||||
if (u == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
u->url.len = url.len;
|
||||
u->url.data = url.data;
|
||||
u->default_port = 80;
|
||||
u->uri_part = 1;
|
||||
|
||||
if (ngx_parse_url(cf->pool, u) != NGX_OK) {
|
||||
if (u->err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in url \"%V\"", u->err, &u->url);
|
||||
}
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
pacf->url = u;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,11 +39,14 @@ typedef struct {
|
|||
ngx_file_t file;
|
||||
ngx_rtmp_play_fmt_t *fmt;
|
||||
ngx_event_t send_evt;
|
||||
ngx_uint_t ncrs;
|
||||
} ngx_rtmp_play_ctx_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t root;
|
||||
ngx_str_t temp_path;
|
||||
ngx_url_t *url;
|
||||
} ngx_rtmp_play_app_conf_t;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue