Add playlist update notification for HLS/DASH

This commit is contained in:
Sergey Dryabzhinsky 2015-12-17 03:36:58 +03:00
parent 06e49e05fd
commit f8da609671
6 changed files with 174 additions and 4 deletions

View File

@ -12,6 +12,7 @@ static ngx_rtmp_publish_pt next_publish;
static ngx_rtmp_close_stream_pt next_close_stream;
static ngx_rtmp_stream_begin_pt next_stream_begin;
static ngx_rtmp_stream_eof_pt next_stream_eof;
static ngx_rtmp_playlist_pt next_playlist;
static ngx_int_t ngx_rtmp_dash_postconfiguration(ngx_conf_t *cf);
@ -228,6 +229,8 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s)
ngx_rtmp_dash_frag_t *f;
ngx_rtmp_dash_app_conf_t *dacf;
ngx_rtmp_playlist_t v;
static u_char buffer[NGX_RTMP_DASH_BUFSIZE];
static u_char start_time[sizeof("1970-09-28T12:00:00+06:00")];
static u_char end_time[sizeof("1970-09-28T12:00:00+06:00")];
@ -491,7 +494,11 @@ ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s)
return NGX_ERROR;
}
return NGX_OK;
ngx_memzero(&v, sizeof(v));
ngx_str_set(&(v.module), "dash");
v.playlist.data = ctx->playlist.data;
v.playlist.len = ctx->playlist.len;
return next_playlist(s, &v);
}
@ -1464,6 +1471,11 @@ ngx_rtmp_dash_cleanup(void *data)
return cleanup->playlen / 500;
}
static ngx_int_t
ngx_rtmp_dash_playlist(ngx_rtmp_session_t *s, ngx_rtmp_playlist_t *v)
{
return next_playlist(s, v);
}
static void *
ngx_rtmp_dash_create_app_conf(ngx_conf_t *cf)
@ -1565,5 +1577,8 @@ ngx_rtmp_dash_postconfiguration(ngx_conf_t *cf)
next_stream_eof = ngx_rtmp_stream_eof;
ngx_rtmp_stream_eof = ngx_rtmp_dash_stream_eof;
next_playlist = ngx_rtmp_playlist;
ngx_rtmp_playlist = ngx_rtmp_dash_playlist;
return NGX_OK;
}

View File

@ -16,6 +16,7 @@ static ngx_rtmp_publish_pt next_publish;
static ngx_rtmp_close_stream_pt next_close_stream;
static ngx_rtmp_stream_begin_pt next_stream_begin;
static ngx_rtmp_stream_eof_pt next_stream_eof;
static ngx_rtmp_playlist_pt next_playlist;
static char * ngx_rtmp_hls_variant(ngx_conf_t *cf, ngx_command_t *cmd,
@ -422,6 +423,8 @@ ngx_rtmp_hls_write_variant_playlist(ngx_rtmp_session_t *s)
ngx_rtmp_hls_variant_t *var;
ngx_rtmp_hls_app_conf_t *hacf;
ngx_rtmp_playlist_t v;
hacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_hls_module);
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_hls_module);
@ -497,7 +500,11 @@ ngx_rtmp_hls_write_variant_playlist(ngx_rtmp_session_t *s)
return NGX_ERROR;
}
return NGX_OK;
ngx_memzero(&v, sizeof(v));
ngx_str_set(&(v.module), "hls");
v.playlist.data = ctx->playlist.data;
v.playlist.len = ctx->playlist.len;
return next_playlist(s, &v);
}
@ -516,6 +523,10 @@ ngx_rtmp_hls_write_playlist(ngx_rtmp_session_t *s)
uint64_t prev_key_id;
const char *sep, *key_sep;
ngx_rtmp_playlist_t v;
ngx_log_error(NGX_LOG_DEBUG, s->connection->log, 0,
"hls: write playlist");
hacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_hls_module);
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_hls_module);
@ -638,7 +649,11 @@ ngx_rtmp_hls_write_playlist(ngx_rtmp_session_t *s)
return ngx_rtmp_hls_write_variant_playlist(s);
}
return NGX_OK;
ngx_memzero(&v, sizeof(v));
ngx_str_set(&(v.module), "hls");
v.playlist.data = ctx->playlist.data;
v.playlist.len = ctx->playlist.len;
return next_playlist(s, &v);
write_err:
ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno,
@ -1658,6 +1673,9 @@ ngx_rtmp_hls_update_fragment(ngx_rtmp_session_t *s, uint64_t ts,
ngx_buf_t *b;
int64_t d;
ngx_log_error(NGX_LOG_DEBUG, s->connection->log, 0,
"hls: update fragment");
hacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_hls_module);
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_hls_module);
f = NULL;
@ -2166,6 +2184,9 @@ ngx_rtmp_hls_stream_begin(ngx_rtmp_session_t *s, ngx_rtmp_stream_begin_t *v)
static ngx_int_t
ngx_rtmp_hls_stream_eof(ngx_rtmp_session_t *s, ngx_rtmp_stream_eof_t *v)
{
ngx_log_error(NGX_LOG_DEBUG, s->connection->log, 0,
"hls: stream eof");
ngx_rtmp_hls_flush_audio(s);
ngx_rtmp_hls_close_fragment(s);
@ -2383,6 +2404,13 @@ ngx_rtmp_hls_variant(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
static ngx_int_t
ngx_rtmp_hls_playlist(ngx_rtmp_session_t *s, ngx_rtmp_playlist_t *v)
{
return next_playlist(s, v);
}
static void *
ngx_rtmp_hls_create_app_conf(ngx_conf_t *cf)
{
@ -2559,5 +2587,8 @@ ngx_rtmp_hls_postconfiguration(ngx_conf_t *cf)
next_stream_eof = ngx_rtmp_stream_eof;
ngx_rtmp_stream_eof = ngx_rtmp_hls_stream_eof;
next_playlist = ngx_rtmp_playlist;
ngx_rtmp_playlist = ngx_rtmp_hls_playlist;
return NGX_OK;
}

View File

@ -44,6 +44,7 @@ static ngx_int_t ngx_rtmp_cmd_recorded(ngx_rtmp_session_t *s,
static ngx_int_t ngx_rtmp_cmd_set_buflen(ngx_rtmp_session_t *s,
ngx_rtmp_set_buflen_t *v);
static ngx_int_t ngx_rtmp_cmd_playlist(ngx_rtmp_session_t *s, ngx_rtmp_playlist_t *v);
ngx_rtmp_connect_pt ngx_rtmp_connect;
ngx_rtmp_disconnect_pt ngx_rtmp_disconnect;
@ -62,6 +63,7 @@ ngx_rtmp_stream_dry_pt ngx_rtmp_stream_dry;
ngx_rtmp_recorded_pt ngx_rtmp_recorded;
ngx_rtmp_set_buflen_pt ngx_rtmp_set_buflen;
ngx_rtmp_playlist_pt ngx_rtmp_playlist;
static ngx_int_t ngx_rtmp_cmd_postconfiguration(ngx_conf_t *cf);
@ -788,6 +790,14 @@ ngx_rtmp_cmd_set_buflen(ngx_rtmp_session_t *s, ngx_rtmp_set_buflen_t *v)
}
static ngx_int_t
ngx_rtmp_cmd_playlist(ngx_rtmp_session_t *s, ngx_rtmp_playlist_t *v)
{
return NGX_OK;
}
static ngx_rtmp_amf_handler_t ngx_rtmp_cmd_map[] = {
{ ngx_string("connect"), ngx_rtmp_cmd_connect_init },
{ ngx_string("createStream"), ngx_rtmp_cmd_create_stream_init },
@ -854,5 +864,7 @@ ngx_rtmp_cmd_postconfiguration(ngx_conf_t *cf)
ngx_rtmp_recorded = ngx_rtmp_cmd_recorded;
ngx_rtmp_set_buflen = ngx_rtmp_cmd_set_buflen;
ngx_rtmp_playlist = ngx_rtmp_cmd_playlist;
return NGX_OK;
}

View File

@ -59,6 +59,12 @@ typedef struct {
} ngx_rtmp_publish_t;
typedef struct {
ngx_str_t playlist;
ngx_str_t module;
} ngx_rtmp_playlist_t;
typedef struct {
u_char name[NGX_RTMP_MAX_NAME];
u_char args[NGX_RTMP_MAX_ARGS];
@ -130,6 +136,7 @@ typedef ngx_int_t (*ngx_rtmp_recorded_pt)(ngx_rtmp_session_t *s,
typedef ngx_int_t (*ngx_rtmp_set_buflen_pt)(ngx_rtmp_session_t *s,
ngx_rtmp_set_buflen_t *v);
typedef ngx_int_t (*ngx_rtmp_playlist_pt)(ngx_rtmp_session_t *s, ngx_rtmp_playlist_t *v);
extern ngx_rtmp_connect_pt ngx_rtmp_connect;
extern ngx_rtmp_disconnect_pt ngx_rtmp_disconnect;
@ -147,5 +154,6 @@ extern ngx_rtmp_stream_dry_pt ngx_rtmp_stream_dry;
extern ngx_rtmp_set_buflen_pt ngx_rtmp_set_buflen;
extern ngx_rtmp_recorded_pt ngx_rtmp_recorded;
extern ngx_rtmp_playlist_pt ngx_rtmp_playlist;
#endif /*_NGX_RTMP_CMD_H_INCLUDED_ */

View File

@ -20,6 +20,7 @@ static ngx_rtmp_publish_pt next_publish;
static ngx_rtmp_play_pt next_play;
static ngx_rtmp_close_stream_pt next_close_stream;
static ngx_rtmp_record_done_pt next_record_done;
static ngx_rtmp_playlist_pt next_playlist;
static char *ngx_rtmp_notify_on_srv_event(ngx_conf_t *cf, ngx_command_t *cmd,
@ -57,6 +58,7 @@ enum {
NGX_RTMP_NOTIFY_DONE,
NGX_RTMP_NOTIFY_RECORD_DONE,
NGX_RTMP_NOTIFY_UPDATE,
NGX_RTMP_NOTIFY_PLAYLIST,
NGX_RTMP_NOTIFY_APP_MAX
};
@ -167,6 +169,13 @@ static ngx_command_t ngx_rtmp_notify_commands[] = {
0,
NULL },
{ ngx_string("on_playlist"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
ngx_rtmp_notify_on_app_event,
NGX_RTMP_APP_CONF_OFFSET,
0,
NULL },
{ ngx_string("notify_method"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
ngx_rtmp_notify_method,
@ -862,6 +871,65 @@ ngx_rtmp_notify_record_done_create(ngx_rtmp_session_t *s, void *arg,
pl);
}
static ngx_chain_t *
ngx_rtmp_notify_playlist_create(ngx_rtmp_session_t *s, void *arg,
ngx_pool_t *pool)
{
ngx_rtmp_playlist_t *v = arg;
ngx_rtmp_notify_ctx_t *ctx;
ngx_chain_t *pl;
ngx_buf_t *b;
size_t name_len;
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_notify_module);
pl = ngx_alloc_chain_link(pool);
if (pl == NULL) {
return NULL;
}
name_len = ngx_strlen(ctx->name);
b = ngx_create_temp_buf(pool,
sizeof("&call=playlist") +
sizeof("&module=") + v->module.len +
sizeof("&app=") + s->app.len * 3 +
sizeof("&name=") + name_len * 3 +
sizeof("&path=") + v->playlist.len * 3 +
1);
if (b == NULL) {
return NULL;
}
pl->buf = b;
pl->next = NULL;
b->last = ngx_cpymem(b->last, (u_char*) "&call=playlist",
sizeof("&call=playlist") - 1);
b->last = ngx_cpymem(b->last, (u_char *) "&module=",
sizeof("&module=") - 1);
b->last = (u_char*) ngx_escape_uri(b->last, v->module.data,
v->module.len, NGX_ESCAPE_ARGS);
b->last = ngx_cpymem(b->last, (u_char*) "&app=", sizeof("&app=") - 1);
b->last = (u_char*) ngx_escape_uri(b->last, s->app.data, s->app.len,
NGX_ESCAPE_ARGS);
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,
NGX_ESCAPE_ARGS);
b->last = ngx_cpymem(b->last, (u_char*) "&path=", sizeof("&path=") - 1);
b->last = (u_char*) ngx_escape_uri(b->last, v->playlist.data, v->playlist.len,
NGX_ESCAPE_ARGS);
return ngx_rtmp_notify_create_request(s, pool, NGX_RTMP_NOTIFY_PLAYLIST,
pl);
}
static ngx_int_t
ngx_rtmp_notify_parse_http_retcode(ngx_rtmp_session_t *s,
@ -1830,6 +1898,35 @@ ngx_rtmp_notify_parse_url(ngx_conf_t *cf, ngx_str_t *url)
}
static ngx_int_t
ngx_rtmp_notify_playlist(ngx_rtmp_session_t *s, ngx_rtmp_playlist_t *v)
{
ngx_rtmp_netcall_init_t ci;
ngx_rtmp_notify_app_conf_t *nacf;
nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module);
if (nacf == NULL || nacf->url[NGX_RTMP_NOTIFY_PLAYLIST] == NULL) {
goto next;
}
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"notify: playlist url='%V'",
&nacf->url[NGX_RTMP_NOTIFY_PLAYLIST]->url);
ngx_memzero(&ci, sizeof(ci));
ci.url = nacf->url[NGX_RTMP_NOTIFY_PLAYLIST];
ci.create = ngx_rtmp_notify_playlist_create;
ci.arg = v;
ngx_rtmp_netcall_create(s, &ci);
next:
return next_playlist(s, v);
}
static char *
ngx_rtmp_notify_on_srv_event(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
@ -1899,6 +1996,10 @@ ngx_rtmp_notify_on_app_event(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
n = NGX_RTMP_NOTIFY_UPDATE;
break;
case sizeof("on_playlist") - 1:
n = NGX_RTMP_NOTIFY_PLAYLIST;
break;
case sizeof("on_publish") - 1:
n = NGX_RTMP_NOTIFY_PUBLISH;
break;
@ -2006,5 +2107,8 @@ ngx_rtmp_notify_postconfiguration(ngx_conf_t *cf)
next_record_done = ngx_rtmp_record_done;
ngx_rtmp_record_done = ngx_rtmp_notify_record_done;
next_playlist = ngx_rtmp_playlist;
ngx_rtmp_playlist = ngx_rtmp_notify_playlist;
return NGX_OK;
}

View File

@ -9,7 +9,7 @@
#define nginx_rtmp_version 1001007
#define NGINX_RTMP_VERSION "1.1.7.9"
#define NGINX_RTMP_VERSION "1.1.7.10"
#endif /* _NGX_RTMP_VERSION_H_INCLUDED_ */