mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-05-10 14:31:07 +02:00
moved metadata handlers from live to codec module & fixed setDataFrame handler to handle ffmpeg packets
This commit is contained in:
parent
fca76ef349
commit
95e2c4172a
|
@ -146,11 +146,31 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
ngx_rtmp_header_t ch, lh;
|
||||
ngx_uint_t *version;
|
||||
|
||||
|
||||
if (h->type != NGX_RTMP_MSG_AUDIO && h->type != NGX_RTMP_MSG_VIDEO) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||
if (ctx == NULL) {
|
||||
ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_codec_ctx_t));
|
||||
ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_codec_module);
|
||||
}
|
||||
|
||||
/* save codec */
|
||||
if (in->buf->last - in->buf->pos < 1) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
fmt = in->buf->pos[0];
|
||||
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
||||
ctx->audio_codec_id = (fmt & 0xf0) >> 4;
|
||||
} else {
|
||||
ctx->video_codec_id = (fmt & 0x0f);
|
||||
}
|
||||
|
||||
/* save AVC/AAC header */
|
||||
if ((h->type != NGX_RTMP_MSG_AUDIO
|
||||
&& h->type != NGX_RTMP_MSG_VIDEO)
|
||||
|| in->buf->last - in->buf->pos < 2)
|
||||
{
|
||||
if (in->buf->last - in->buf->pos < 2) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
@ -160,16 +180,9 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
}
|
||||
|
||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||
if (ctx == NULL) {
|
||||
ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_codec_ctx_t));
|
||||
ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_codec_module);
|
||||
}
|
||||
|
||||
fmt = in->buf->pos[0];
|
||||
header = NULL;
|
||||
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
||||
if (((fmt & 0xf0) >> 4) == NGX_RTMP_AUDIO_AAC) {
|
||||
if (ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC) {
|
||||
header = &ctx->aac_header;
|
||||
pheader = &ctx->aac_pheader;
|
||||
version = &ctx->aac_version;
|
||||
|
@ -177,7 +190,7 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
"codec: AAC header arrived");
|
||||
}
|
||||
} else {
|
||||
if ((fmt & 0x0f) == NGX_RTMP_VIDEO_H264) {
|
||||
if (ctx->video_codec_id == NGX_RTMP_VIDEO_H264) {
|
||||
header = &ctx->avc_header;
|
||||
pheader = &ctx->avc_pheader;
|
||||
version = &ctx->avc_version;
|
||||
|
@ -219,11 +232,148 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_codec_meta_data(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||
ngx_chain_t *in)
|
||||
{
|
||||
ngx_rtmp_codec_ctx_t *ctx;
|
||||
ngx_uint_t skip;
|
||||
|
||||
static struct {
|
||||
double width;
|
||||
double height;
|
||||
double duration;
|
||||
double frame_rate;
|
||||
double video_data_rate;
|
||||
double video_codec_id_n;
|
||||
u_char video_codec_id_s[32];
|
||||
double audio_data_rate;
|
||||
double audio_codec_id_n;
|
||||
u_char audio_codec_id_s[32];
|
||||
} v;
|
||||
|
||||
static ngx_rtmp_amf_elt_t in_video_codec_id[] = {
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_null_string,
|
||||
&v.video_codec_id_n, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_STRING,
|
||||
ngx_null_string,
|
||||
&v.video_codec_id_s, sizeof(v.video_codec_id_s) },
|
||||
};
|
||||
|
||||
static ngx_rtmp_amf_elt_t in_audio_codec_id[] = {
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_null_string,
|
||||
&v.audio_codec_id_n, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_STRING,
|
||||
ngx_null_string,
|
||||
&v.audio_codec_id_s, sizeof(v.audio_codec_id_s) },
|
||||
};
|
||||
|
||||
static ngx_rtmp_amf_elt_t in_inf[] = {
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("width"),
|
||||
&v.width, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("height"),
|
||||
&v.height, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("duration"),
|
||||
&v.duration, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("framerate"),
|
||||
&v.frame_rate, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("videodatarate"),
|
||||
&v.video_data_rate, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_VARIANT,
|
||||
ngx_string("videocodecid"),
|
||||
in_video_codec_id, sizeof(in_video_codec_id) },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("audiodatarate"),
|
||||
&v.audio_data_rate, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_VARIANT,
|
||||
ngx_string("audiocodecid"),
|
||||
in_audio_codec_id, sizeof(in_audio_codec_id) },
|
||||
};
|
||||
|
||||
static ngx_rtmp_amf_elt_t in_elts[] = {
|
||||
|
||||
{ NGX_RTMP_AMF_STRING,
|
||||
ngx_null_string,
|
||||
NULL, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_OBJECT,
|
||||
ngx_null_string,
|
||||
in_inf, sizeof(in_inf) },
|
||||
};
|
||||
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||
if (ctx == NULL) {
|
||||
ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_codec_ctx_t));
|
||||
ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_codec_module);
|
||||
}
|
||||
|
||||
ngx_memzero(&v, sizeof(v));
|
||||
|
||||
/* use -1 as a sign of unchanged data;
|
||||
* 0 is a valid value for uncompressed audio */
|
||||
v.audio_codec_id_n = -1;
|
||||
|
||||
/* FFmpeg sends a string in front of actal metadata; ignore it */
|
||||
skip = !(in->buf->last > in->buf->pos
|
||||
&& *in->buf->pos == NGX_RTMP_AMF_STRING);
|
||||
if (ngx_rtmp_receive_amf(s, in, in_elts + skip,
|
||||
sizeof(in_elts) / sizeof(in_elts[0]) - skip))
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||
"codec: error parsing data frame");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ctx->width = v.width;
|
||||
ctx->height = v.height;
|
||||
ctx->duration = v.duration;
|
||||
ctx->frame_rate = v.frame_rate;
|
||||
ctx->video_data_rate = v.video_data_rate;
|
||||
ctx->video_codec_id = v.video_codec_id_n;
|
||||
ctx->audio_data_rate = v.audio_data_rate;
|
||||
ctx->audio_codec_id = (v.audio_codec_id_n == -1
|
||||
? 0 : v.audio_codec_id_n == 0
|
||||
? NGX_RTMP_AUDIO_UNCOMPRESSED : v.audio_codec_id_n);
|
||||
|
||||
ngx_log_debug8(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||
"codec: data frame: "
|
||||
"width=%ui height=%ui duration=%ui frame_rate=%ui "
|
||||
"video=%s (%ui) audio=%s (%ui)",
|
||||
ctx->width, ctx->height, ctx->duration, ctx->frame_rate,
|
||||
ngx_rtmp_get_video_codec_name(ctx->video_codec_id),
|
||||
ctx->video_codec_id,
|
||||
ngx_rtmp_get_audio_codec_name(ctx->audio_codec_id),
|
||||
ctx->audio_codec_id);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_codec_postconfiguration(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_rtmp_core_main_conf_t *cmcf;
|
||||
ngx_rtmp_handler_pt *h;
|
||||
ngx_rtmp_amf_handler_t *ch;
|
||||
|
||||
cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);
|
||||
|
||||
|
@ -236,5 +386,21 @@ ngx_rtmp_codec_postconfiguration(ngx_conf_t *cf)
|
|||
h = ngx_array_push(&cmcf->events[NGX_RTMP_DISCONNECT]);
|
||||
*h = ngx_rtmp_codec_disconnect;
|
||||
|
||||
/* register metadata handler */
|
||||
ch = ngx_array_push(&cmcf->amf);
|
||||
if (ch == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_str_set(&ch->name, "@setDataFrame");
|
||||
ch->handler = ngx_rtmp_codec_meta_data;
|
||||
|
||||
ch = ngx_array_push(&cmcf->amf);
|
||||
if (ch == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_str_set(&ch->name, "onMetaData");
|
||||
ch->handler = ngx_rtmp_codec_meta_data;
|
||||
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,15 @@ u_char * ngx_rtmp_get_video_codec_name(ngx_uint_t id);
|
|||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t width;
|
||||
ngx_uint_t height;
|
||||
ngx_uint_t duration;
|
||||
ngx_uint_t frame_rate;
|
||||
ngx_uint_t video_data_rate;
|
||||
ngx_uint_t video_codec_id;
|
||||
ngx_uint_t audio_data_rate;
|
||||
ngx_uint_t audio_codec_id;
|
||||
|
||||
ngx_uint_t avc_version;
|
||||
ngx_uint_t aac_version;
|
||||
|
||||
|
|
|
@ -290,7 +290,6 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
ngx_rtmp_header_t ch, lh;
|
||||
ngx_uint_t prio, peer_prio;
|
||||
ngx_uint_t peers, dropped_peers;
|
||||
uint8_t flv_fmt;
|
||||
size_t header_offset;
|
||||
ngx_uint_t header_version;
|
||||
|
||||
|
@ -351,15 +350,6 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
peers = 0;
|
||||
dropped_peers = 0;
|
||||
|
||||
if (in->buf->last - in->buf->pos >= 1) {
|
||||
flv_fmt = *in->buf->pos;
|
||||
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
||||
ctx->stream->meta.audio_codec_id = (flv_fmt & 0xf0) >> 4;
|
||||
} else {
|
||||
ctx->stream->meta.video_codec_id = (flv_fmt & 0x0f);
|
||||
}
|
||||
}
|
||||
|
||||
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||
header_out = NULL;
|
||||
pheader_out = NULL;
|
||||
|
@ -489,192 +479,14 @@ next:
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_live_ext_meta_data(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||
ngx_chain_t *in, ngx_uint_t skip)
|
||||
{
|
||||
ngx_rtmp_live_app_conf_t *lacf;
|
||||
ngx_rtmp_live_ctx_t *ctx;
|
||||
ngx_rtmp_live_meta_t *meta;
|
||||
|
||||
static struct {
|
||||
double width;
|
||||
double height;
|
||||
double duration;
|
||||
double frame_rate;
|
||||
double video_data_rate;
|
||||
double video_codec_id_n;
|
||||
u_char video_codec_id_s[32];
|
||||
double audio_data_rate;
|
||||
double audio_codec_id_n;
|
||||
u_char audio_codec_id_s[32];
|
||||
} v;
|
||||
|
||||
static ngx_rtmp_amf_elt_t in_video_codec_id[] = {
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_null_string,
|
||||
&v.video_codec_id_n, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_STRING,
|
||||
ngx_null_string,
|
||||
&v.video_codec_id_s, sizeof(v.video_codec_id_s) },
|
||||
};
|
||||
|
||||
static ngx_rtmp_amf_elt_t in_audio_codec_id[] = {
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_null_string,
|
||||
&v.audio_codec_id_n, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_STRING,
|
||||
ngx_null_string,
|
||||
&v.audio_codec_id_s, sizeof(v.audio_codec_id_s) },
|
||||
};
|
||||
|
||||
static ngx_rtmp_amf_elt_t in_inf[] = {
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("width"),
|
||||
&v.width, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("height"),
|
||||
&v.height, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("duration"),
|
||||
&v.duration, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("framerate"),
|
||||
&v.frame_rate, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("videodatarate"),
|
||||
&v.video_data_rate, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_VARIANT,
|
||||
ngx_string("videocodecid"),
|
||||
in_video_codec_id, sizeof(in_video_codec_id) },
|
||||
|
||||
{ NGX_RTMP_AMF_NUMBER,
|
||||
ngx_string("audiodatarate"),
|
||||
&v.audio_data_rate, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_VARIANT,
|
||||
ngx_string("audiocodecid"),
|
||||
in_audio_codec_id, sizeof(in_audio_codec_id) },
|
||||
};
|
||||
|
||||
static ngx_rtmp_amf_elt_t in_elts[] = {
|
||||
|
||||
{ NGX_RTMP_AMF_STRING,
|
||||
ngx_null_string,
|
||||
NULL, 0 },
|
||||
|
||||
{ NGX_RTMP_AMF_OBJECT,
|
||||
ngx_null_string,
|
||||
in_inf, sizeof(in_inf) },
|
||||
};
|
||||
|
||||
|
||||
lacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_live_module);
|
||||
if (lacf == NULL || !lacf->live) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_memzero(&v, sizeof(v));
|
||||
|
||||
/* use -1 as a sign of unchanged data;
|
||||
* 0 is a valid value for uncompressed audio */
|
||||
v.audio_codec_id_n = -1;
|
||||
|
||||
if (ngx_rtmp_receive_amf(s, in, in_elts + skip,
|
||||
sizeof(in_elts) / sizeof(in_elts[0]) - skip))
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||
"live: error parsing data frame");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_live_module);
|
||||
if (ctx == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if ((ctx->flags & NGX_RTMP_LIVE_PUBLISHING) == 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||
"live: received data stream from non-publisher");
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
meta = &ctx->stream->meta;
|
||||
meta->width = v.width;
|
||||
meta->height = v.height;
|
||||
meta->duration = v.duration;
|
||||
meta->frame_rate = v.frame_rate;
|
||||
meta->video_data_rate = v.video_data_rate;
|
||||
meta->video_codec_id = v.video_codec_id_n;
|
||||
meta->audio_data_rate = v.audio_data_rate;
|
||||
meta->audio_codec_id = (v.audio_codec_id_n == -1
|
||||
? 0 : v.audio_codec_id_n == 0
|
||||
? NGX_RTMP_AUDIO_UNCOMPRESSED : v.audio_codec_id_n);
|
||||
|
||||
ngx_log_debug8(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||
"live: data frame: "
|
||||
"width=%ui height=%ui duration=%ui frame_rate=%ui "
|
||||
"video=%s (%ui) audio=%s (%ui)",
|
||||
meta->width, meta->height, meta->duration, meta->frame_rate,
|
||||
ngx_rtmp_get_video_codec_name(meta->video_codec_id),
|
||||
meta->video_codec_id,
|
||||
ngx_rtmp_get_audio_codec_name(meta->audio_codec_id),
|
||||
meta->audio_codec_id);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_live_data_frame(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||
ngx_chain_t *in)
|
||||
{
|
||||
return ngx_rtmp_live_ext_meta_data(s, h, in, 0);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_live_meta_data(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||
ngx_chain_t *in)
|
||||
{
|
||||
return ngx_rtmp_live_ext_meta_data(s, h, in, 1);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_rtmp_live_postconfiguration(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_rtmp_core_main_conf_t *cmcf;
|
||||
ngx_rtmp_handler_pt *h;
|
||||
ngx_rtmp_amf_handler_t *ch;
|
||||
|
||||
cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);
|
||||
|
||||
/* register metadata handler */
|
||||
ch = ngx_array_push(&cmcf->amf);
|
||||
if (ch == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_str_set(&ch->name, "@setDataFrame");
|
||||
ch->handler = ngx_rtmp_live_data_frame;
|
||||
|
||||
ch = ngx_array_push(&cmcf->amf);
|
||||
if (ch == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_str_set(&ch->name, "onMetaData");
|
||||
ch->handler = ngx_rtmp_live_meta_data;
|
||||
|
||||
/* register raw event handlers */
|
||||
h = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_AUDIO]);
|
||||
*h = ngx_rtmp_live_av;
|
||||
|
|
|
@ -22,18 +22,6 @@
|
|||
#define NGX_RTMP_LIVE_MSID 1
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t width;
|
||||
ngx_uint_t height;
|
||||
ngx_uint_t duration;
|
||||
ngx_uint_t frame_rate;
|
||||
ngx_uint_t video_data_rate;
|
||||
ngx_uint_t video_codec_id;
|
||||
ngx_uint_t audio_data_rate;
|
||||
ngx_uint_t audio_codec_id;
|
||||
} ngx_rtmp_live_meta_t;
|
||||
|
||||
|
||||
typedef struct ngx_rtmp_live_ctx_s ngx_rtmp_live_ctx_t;
|
||||
typedef struct ngx_rtmp_live_stream_s ngx_rtmp_live_stream_t;
|
||||
|
||||
|
@ -61,7 +49,6 @@ struct ngx_rtmp_live_stream_s {
|
|||
ngx_uint_t flags;
|
||||
ngx_rtmp_bandwidth_t bw_in;
|
||||
ngx_rtmp_bandwidth_t bw_out;
|
||||
ngx_rtmp_live_meta_t meta;
|
||||
ngx_msec_t epoch;
|
||||
};
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
|
|||
ngx_rtmp_live_app_conf_t *lacf)
|
||||
{
|
||||
ngx_rtmp_live_stream_t *stream;
|
||||
ngx_rtmp_live_meta_t *meta;
|
||||
ngx_rtmp_codec_ctx_t *codec;
|
||||
ngx_rtmp_live_ctx_t *ctx;
|
||||
ngx_rtmp_session_t *s;
|
||||
ngx_int_t n;
|
||||
|
@ -258,7 +258,7 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
|
|||
ngx_int_t publishing;
|
||||
u_char buf[NGX_OFF_T_LEN + 1];
|
||||
ngx_rtmp_stat_loc_conf_t *slcf;
|
||||
u_char *codec;
|
||||
u_char *cname;
|
||||
|
||||
slcf = ngx_http_get_module_loc_conf(r, ngx_rtmp_stat_module);
|
||||
|
||||
|
@ -279,36 +279,12 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
|
|||
"%M", ngx_current_msec - stream->epoch) - buf);
|
||||
NGX_RTMP_STAT_L("</time>");
|
||||
|
||||
meta = &stream->meta;
|
||||
NGX_RTMP_STAT_L("<meta><width>");
|
||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||
"%ui", meta->width) - buf);
|
||||
NGX_RTMP_STAT_L("</width><height>");
|
||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||
"%ui", meta->height) - buf);
|
||||
NGX_RTMP_STAT_L("</height><framerate>");
|
||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||
"%ui", meta->frame_rate) - buf);
|
||||
NGX_RTMP_STAT_L("</framerate><video>");
|
||||
codec = ngx_rtmp_get_video_codec_name(meta->video_codec_id);
|
||||
if (*codec) {
|
||||
NGX_RTMP_STAT_ECS(codec);
|
||||
}
|
||||
NGX_RTMP_STAT_L("</video><audio>");
|
||||
codec = ngx_rtmp_get_audio_codec_name(meta->audio_codec_id);
|
||||
if (*codec) {
|
||||
NGX_RTMP_STAT_ECS(codec);
|
||||
}
|
||||
NGX_RTMP_STAT_L("</audio></meta>\r\n");
|
||||
|
||||
ngx_rtmp_stat_bw(r, lll, &stream->bw_in, &stream->bw_out);
|
||||
|
||||
nclients = 0;
|
||||
codec = NULL;
|
||||
for (ctx = stream->ctx; ctx; ctx = ctx->next, ++nclients) {
|
||||
s = ctx->session;
|
||||
/* TODO: add
|
||||
* 1) session start time
|
||||
* 2) drop stats */
|
||||
if (slcf->stat & NGX_RTMP_STAT_CLIENTS) {
|
||||
NGX_RTMP_STAT_L("<client>");
|
||||
|
||||
|
@ -356,10 +332,34 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
|
|||
}
|
||||
if (ctx->flags & NGX_RTMP_LIVE_PUBLISHING) {
|
||||
publishing = 1;
|
||||
codec = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||
}
|
||||
}
|
||||
total_nclients += nclients;
|
||||
|
||||
if (codec) {
|
||||
NGX_RTMP_STAT_L("<meta><width>");
|
||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||
"%ui", codec->width) - buf);
|
||||
NGX_RTMP_STAT_L("</width><height>");
|
||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||
"%ui", codec->height) - buf);
|
||||
NGX_RTMP_STAT_L("</height><framerate>");
|
||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||
"%ui", codec->frame_rate) - buf);
|
||||
NGX_RTMP_STAT_L("</framerate><video>");
|
||||
cname = ngx_rtmp_get_video_codec_name(codec->video_codec_id);
|
||||
if (*cname) {
|
||||
NGX_RTMP_STAT_ECS(cname);
|
||||
}
|
||||
NGX_RTMP_STAT_L("</video><audio>");
|
||||
cname = ngx_rtmp_get_audio_codec_name(codec->audio_codec_id);
|
||||
if (*cname) {
|
||||
NGX_RTMP_STAT_ECS(cname);
|
||||
}
|
||||
NGX_RTMP_STAT_L("</audio></meta>\r\n");
|
||||
}
|
||||
|
||||
NGX_RTMP_STAT_L("<nclients>");
|
||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||
"%uz", nclients) - buf);
|
||||
|
|
Loading…
Reference in a new issue