mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-05-20 01:51:07 +02:00
added auto-detectiion of size in amf0 writer && improved a lot of code in broadcaster
This commit is contained in:
parent
96ebed8573
commit
b9ee8dbe09
|
@ -405,6 +405,10 @@ ngx_rtmp_amf0_write(ngx_rtmp_amf0_ctx_t *ctx,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NGX_RTMP_AMF0_STRING:
|
case NGX_RTMP_AMF0_STRING:
|
||||||
|
if (len == 0 && data) {
|
||||||
|
len = ngx_strlen((u_char*)data);
|
||||||
|
}
|
||||||
|
|
||||||
if (ngx_rtmp_amf0_put(ctx,
|
if (ngx_rtmp_amf0_put(ctx,
|
||||||
ngx_rtmp_amf0_reverse_copy(buf,
|
ngx_rtmp_amf0_reverse_copy(buf,
|
||||||
&len, 2), 2) != NGX_OK)
|
&len, 2), 2) != NGX_OK)
|
||||||
|
|
|
@ -365,79 +365,69 @@ static ngx_int_t
|
||||||
ngx_rtmp_broadcast_connect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
ngx_rtmp_broadcast_connect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_chain_t *in)
|
ngx_chain_t *in)
|
||||||
{
|
{
|
||||||
|
ngx_connection_t *c;
|
||||||
ngx_rtmp_core_srv_conf_t *cscf;
|
ngx_rtmp_core_srv_conf_t *cscf;
|
||||||
|
|
||||||
static double trans;
|
static double trans;
|
||||||
static u_char app[1024];
|
static u_char app[1024];
|
||||||
static u_char url[1024];
|
static ngx_str_t stream;
|
||||||
static u_char acodecs[1024];
|
|
||||||
static ngx_str_t app_str;
|
|
||||||
static double capabilities = 31;
|
static double capabilities = 31;
|
||||||
static double object_enc;
|
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t in_cmd[] = {
|
static ngx_rtmp_amf0_elt_t in_cmd[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, "app", app, sizeof(app) },
|
{ NGX_RTMP_AMF0_STRING, "app", app, sizeof(app) },
|
||||||
{ NGX_RTMP_AMF0_STRING, "tcUrl" , url, sizeof(url) },
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "audiocodecs" , acodecs, sizeof(acodecs) },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_obj[] = {
|
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, "fmsVer", "FMS/3,0,1,123" , sizeof("FMS/3,0,1,123")-1 },
|
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, 0 },
|
||||||
{ NGX_RTMP_AMF0_NUMBER, "capabilities", &capabilities, sizeof(capabilities) },
|
{ NGX_RTMP_AMF0_OBJECT, NULL, in_cmd, sizeof(in_cmd) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_inf[] = {
|
static ngx_rtmp_amf0_elt_t out_obj[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, "level", NULL, 0 },
|
{ NGX_RTMP_AMF0_STRING, "fmsVer", "FMS/3,0,1,123", 0 },
|
||||||
{ NGX_RTMP_AMF0_STRING, "code", NULL, 0 },
|
{ NGX_RTMP_AMF0_NUMBER, "capabilities", &capabilities, 0 },
|
||||||
{ NGX_RTMP_AMF0_STRING, "description", NULL, 0 },
|
|
||||||
{ NGX_RTMP_AMF0_NUMBER, "objectEncoding", &object_enc , sizeof(object_enc) },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
static ngx_rtmp_amf0_elt_t out_inf[] = {
|
||||||
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_STRING, "level", "status", 0 },
|
||||||
{ NGX_RTMP_AMF0_OBJECT, NULL, in_cmd, sizeof(in_cmd) },
|
{ NGX_RTMP_AMF0_STRING, "code", "NetConnection.Connect.Success", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "description", "Connection succeeded.", 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, "_result", sizeof("_result") - 1 },
|
{ NGX_RTMP_AMF0_STRING, NULL, "_result", 0 },
|
||||||
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, 0 },
|
||||||
{ NGX_RTMP_AMF0_OBJECT, NULL, out_obj, sizeof(out_obj) },
|
{ NGX_RTMP_AMF0_OBJECT, NULL, out_obj, sizeof(out_obj) },
|
||||||
{ NGX_RTMP_AMF0_OBJECT, NULL, out_inf, sizeof(out_inf) },
|
{ NGX_RTMP_AMF0_OBJECT, NULL, out_inf, sizeof(out_inf) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
c = s->connection;
|
||||||
|
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
||||||
|
|
||||||
|
/* parse input */
|
||||||
|
app[0] = 0;
|
||||||
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
||||||
sizeof(in_elts) / sizeof(in_elts[0])))
|
sizeof(in_elts) / sizeof(in_elts[0])))
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
||||||
|
"connect() called; app='%s'", app);
|
||||||
|
|
||||||
ngx_str_set(&out_inf[0], "status");
|
|
||||||
ngx_str_set(&out_inf[1], "NetConnection.Connect.Success");
|
|
||||||
ngx_str_set(&out_inf[2], "Connection succeeded.");
|
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
||||||
"connect() called; app='%s' url='%s'",
|
|
||||||
app, url);
|
|
||||||
|
|
||||||
/*FIXME: app_str allocation!!!!!!! */
|
|
||||||
/*FIXME: add memsetting input data */
|
|
||||||
/* join stream */
|
/* join stream */
|
||||||
ngx_str_set(&app_str, "preved");
|
stream.len = ngx_strlen(app);
|
||||||
/*
|
stream.data = ngx_palloc(c->pool, stream.len);
|
||||||
app_str.data = app;
|
ngx_memcpy(stream.data, app, stream.len);
|
||||||
app_str.len = ngx_strlen(app);
|
ngx_rtmp_broadcast_join(s, &stream, 0);
|
||||||
*/
|
|
||||||
ngx_rtmp_broadcast_join(s, &app_str, 0);
|
|
||||||
|
|
||||||
|
/* send all replies */
|
||||||
return ngx_rtmp_send_ack_size(s, cscf->ack_window)
|
return ngx_rtmp_send_ack_size(s, cscf->ack_window)
|
||||||
|| ngx_rtmp_send_bandwidth(s, cscf->ack_window, NGX_RTMP_LIMIT_DYNAMIC)
|
|| ngx_rtmp_send_bandwidth(s, cscf->ack_window, NGX_RTMP_LIMIT_DYNAMIC)
|
||||||
|| ngx_rtmp_send_user_stream_begin(s, 0)
|
|| ngx_rtmp_send_user_stream_begin(s, 0)
|
||||||
|| ngx_rtmp_send_chunk_size(s, cscf->chunk_size)
|
|| ngx_rtmp_send_chunk_size(s, cscf->chunk_size)
|
||||||
|| ngx_rtmp_send_amf0(s, h, out_elts,
|
|| ngx_rtmp_send_amf0(s, h, out_elts,
|
||||||
sizeof(out_elts) / sizeof(out_elts[0]))
|
sizeof(out_elts) / sizeof(out_elts[0]))
|
||||||
? NGX_OK
|
? NGX_ERROR
|
||||||
: NGX_OK;
|
: NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,31 +436,32 @@ static ngx_int_t
|
||||||
ngx_rtmp_broadcast_create_stream(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
ngx_rtmp_broadcast_create_stream(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_chain_t *in)
|
ngx_chain_t *in)
|
||||||
{
|
{
|
||||||
static double trans;
|
static double trans;
|
||||||
static double stream;
|
static double stream;
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, sizeof(trans) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, "_result", sizeof("_result") - 1 },
|
{ NGX_RTMP_AMF0_STRING, NULL, "_result", 0 },
|
||||||
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, 0 },
|
||||||
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
||||||
{ NGX_RTMP_AMF0_NUMBER, NULL, &stream, sizeof(stream) },
|
{ NGX_RTMP_AMF0_NUMBER, NULL, &stream, sizeof(stream) },
|
||||||
};
|
};
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"createStream() called");
|
"createStream() called");
|
||||||
|
|
||||||
|
/* parse input */
|
||||||
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
||||||
sizeof(in_elts) / sizeof(in_elts[0])))
|
sizeof(in_elts) / sizeof(in_elts[0])))
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send result with standard stream */
|
||||||
stream = NGX_RTMP_BROADCAST_MSID;
|
stream = NGX_RTMP_BROADCAST_MSID;
|
||||||
|
|
||||||
return ngx_rtmp_send_amf0(s, h, out_elts,
|
return ngx_rtmp_send_amf0(s, h, out_elts,
|
||||||
sizeof(out_elts) / sizeof(out_elts[0]));
|
sizeof(out_elts) / sizeof(out_elts[0]));
|
||||||
}
|
}
|
||||||
|
@ -480,54 +471,48 @@ static ngx_int_t
|
||||||
ngx_rtmp_broadcast_publish(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
ngx_rtmp_broadcast_publish(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_chain_t *in)
|
ngx_chain_t *in)
|
||||||
{
|
{
|
||||||
ngx_rtmp_header_t sh;
|
ngx_rtmp_header_t sh;
|
||||||
|
|
||||||
static double trans;
|
static double trans;
|
||||||
static u_char pub_name[1024];
|
|
||||||
static u_char pub_type[1024];
|
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_inf[] = {
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "code", NULL, 0 },
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "level", NULL, 0 },
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "description", NULL, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, 0 },
|
||||||
{ NGX_RTMP_AMF0_NULL, NULL, NULL, 0 },
|
};
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, pub_name, sizeof(pub_name) },
|
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, pub_type, sizeof(pub_type) },
|
static ngx_rtmp_amf0_elt_t out_inf[] = {
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "code", "NetStream.Publish.Start", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "level", "status", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "description", "Publish succeeded.", 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, "onStatus", sizeof("onStatus") - 1 },
|
{ NGX_RTMP_AMF0_STRING, NULL, "onStatus", 0 },
|
||||||
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, 0 },
|
||||||
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
||||||
{ NGX_RTMP_AMF0_OBJECT, NULL, out_inf, sizeof(out_inf) },
|
{ NGX_RTMP_AMF0_OBJECT, NULL, out_inf, sizeof(out_inf) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* parse input */
|
||||||
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
||||||
sizeof(in_elts) / sizeof(in_elts[0])))
|
sizeof(in_elts) / sizeof(in_elts[0])))
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"publish() called; pubName='%s' pubType='%s'",
|
"publish() called");
|
||||||
pub_name, pub_type);
|
|
||||||
|
|
||||||
|
/* mark current session as publisher */
|
||||||
|
ngx_rtmp_broadcast_set_flags(s, NGX_RTMP_BROADCAST_PUBLISHER);
|
||||||
|
|
||||||
|
/* start stream */
|
||||||
if (ngx_rtmp_send_user_stream_begin(s,
|
if (ngx_rtmp_send_user_stream_begin(s,
|
||||||
NGX_RTMP_BROADCAST_MSID) != NGX_OK)
|
NGX_RTMP_BROADCAST_MSID) != NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_rtmp_broadcast_set_flags(s, NGX_RTMP_BROADCAST_PUBLISHER);
|
/* send onStatus reply */
|
||||||
|
|
||||||
ngx_str_set(&out_inf[0], "NetStream.Publish.Start");
|
|
||||||
ngx_str_set(&out_inf[1], "status");
|
|
||||||
ngx_str_set(&out_inf[2], "Publish succeeded.");
|
|
||||||
|
|
||||||
memset(&sh, 0, sizeof(sh));
|
memset(&sh, 0, sizeof(sh));
|
||||||
sh.type = NGX_RTMP_MSG_AMF0_CMD;
|
sh.type = NGX_RTMP_MSG_AMF0_CMD;
|
||||||
sh.csid = NGX_RTMP_BROADCAST_CSID_AMF0;
|
sh.csid = NGX_RTMP_BROADCAST_CSID_AMF0;
|
||||||
|
@ -547,101 +532,105 @@ static ngx_int_t
|
||||||
ngx_rtmp_broadcast_play(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
ngx_rtmp_broadcast_play(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_chain_t *in)
|
ngx_chain_t *in)
|
||||||
{
|
{
|
||||||
ngx_rtmp_header_t sh;
|
ngx_rtmp_header_t sh;
|
||||||
|
|
||||||
static double trans;
|
static double trans;
|
||||||
static u_char play_name[1024];
|
static uint8_t bfalse;
|
||||||
static int bfalse;
|
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_inf[] = {
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "code", NULL, 0 },
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "level", NULL, 0 },
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "description", NULL, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out2_inf[] = {
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "code", NULL, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, 0 },
|
||||||
{ NGX_RTMP_AMF0_NULL, NULL, NULL, 0 },
|
};
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, play_name, sizeof(play_name) },
|
|
||||||
|
static ngx_rtmp_amf0_elt_t out_inf[] = {
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "code", "NetStream.Play.Reset", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "level", "status", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "description", "Playing and resetting.", 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, "onStatus", sizeof("onStatus") - 1 },
|
{ NGX_RTMP_AMF0_STRING, NULL, "onStatus", 0 },
|
||||||
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, 0 },
|
||||||
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
||||||
{ NGX_RTMP_AMF0_OBJECT, NULL, out_inf, sizeof(out_inf) },
|
{ NGX_RTMP_AMF0_OBJECT, NULL, out_inf, sizeof(out_inf) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static ngx_rtmp_amf0_elt_t out2_inf[] = {
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "code", "NetStream.Play.Start", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "level", "status", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "description", "Started playing.", 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out2_elts[] = {
|
static ngx_rtmp_amf0_elt_t out2_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, "onStatus", sizeof("onStatus") - 1 },
|
{ NGX_RTMP_AMF0_STRING, NULL, "onStatus", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, 0 },
|
||||||
|
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
||||||
{ NGX_RTMP_AMF0_OBJECT, NULL, out2_inf, sizeof(out2_inf) },
|
{ NGX_RTMP_AMF0_OBJECT, NULL, out2_inf, sizeof(out2_inf) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out3_elts[] = {
|
static ngx_rtmp_amf0_elt_t out3_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, "|RtmpSampleAccess", sizeof("|RtmpSampleAccess") - 1 },
|
{ NGX_RTMP_AMF0_STRING, NULL, "|RtmpSampleAccess", 0 },
|
||||||
{ NGX_RTMP_AMF0_BOOLEAN, NULL, &bfalse, sizeof(bfalse) },
|
{ NGX_RTMP_AMF0_BOOLEAN,NULL, &bfalse, 0 },
|
||||||
|
{ NGX_RTMP_AMF0_BOOLEAN,NULL, &bfalse, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ngx_rtmp_amf0_elt_t out4_inf[] = {
|
||||||
|
{ NGX_RTMP_AMF0_STRING, "code", "NetStream.Data.Start", 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static ngx_rtmp_amf0_elt_t out4_elts[] = {
|
||||||
|
{ NGX_RTMP_AMF0_STRING, NULL, "onStatus", 0 },
|
||||||
|
{ NGX_RTMP_AMF0_OBJECT, NULL, out4_inf, sizeof(out4_inf) },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* parse input */
|
||||||
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
||||||
sizeof(in_elts) / sizeof(in_elts[0])))
|
sizeof(in_elts) / sizeof(in_elts[0])))
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
play_name[0] = 0;
|
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
"play() called");
|
||||||
"play() called; playame='%s'",
|
|
||||||
play_name);
|
|
||||||
|
|
||||||
|
/* mark session as subscriber */
|
||||||
|
ngx_rtmp_broadcast_set_flags(s, NGX_RTMP_BROADCAST_SUBSCRIBER);
|
||||||
|
|
||||||
|
/* start stream */
|
||||||
if (ngx_rtmp_send_user_stream_begin(s,
|
if (ngx_rtmp_send_user_stream_begin(s,
|
||||||
NGX_RTMP_BROADCAST_MSID) != NGX_OK)
|
NGX_RTMP_BROADCAST_MSID) != NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_rtmp_broadcast_set_flags(s, NGX_RTMP_BROADCAST_SUBSCRIBER);
|
/* send onStatus reply */
|
||||||
|
|
||||||
memset(&sh, 0, sizeof(sh));
|
memset(&sh, 0, sizeof(sh));
|
||||||
sh.type = NGX_RTMP_MSG_AMF0_CMD;
|
sh.type = NGX_RTMP_MSG_AMF0_CMD;
|
||||||
sh.csid = NGX_RTMP_BROADCAST_CSID_AMF0;
|
sh.csid = NGX_RTMP_BROADCAST_CSID_AMF0;
|
||||||
sh.msid = h->msid;
|
sh.msid = h->msid;
|
||||||
|
|
||||||
ngx_str_set(&out_inf[0], "NetStream.Play.Reset");
|
|
||||||
ngx_str_set(&out_inf[1], "status");
|
|
||||||
ngx_str_set(&out_inf[2], "Playing and resetting.");
|
|
||||||
|
|
||||||
if (ngx_rtmp_send_amf0(s, &sh, out_elts,
|
if (ngx_rtmp_send_amf0(s, &sh, out_elts,
|
||||||
sizeof(out_elts) / sizeof(out_elts[0])) != NGX_OK)
|
sizeof(out_elts) / sizeof(out_elts[0])) != NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_str_set(&out_inf[0], "NetStream.Play.Start");
|
/* send sample access meta message FIXME */
|
||||||
ngx_str_set(&out_inf[1], "status");
|
if (ngx_rtmp_send_amf0(s, &sh, out2_elts,
|
||||||
ngx_str_set(&out_inf[2], "Started playing.");
|
sizeof(out2_elts) / sizeof(out2_elts[0])) != NGX_OK)
|
||||||
|
|
||||||
if (ngx_rtmp_send_amf0(s, &sh, out_elts,
|
|
||||||
sizeof(out_elts) / sizeof(out_elts[0])) != NGX_OK)
|
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_str_set(&out2_inf[0], "NetStream.Data.Start");
|
/* send data start meta message */
|
||||||
sh.type = NGX_RTMP_MSG_AMF0_META;
|
sh.type = NGX_RTMP_MSG_AMF0_META;
|
||||||
|
|
||||||
if (ngx_rtmp_send_amf0(s, &sh, out3_elts,
|
if (ngx_rtmp_send_amf0(s, &sh, out3_elts,
|
||||||
sizeof(out3_elts) / sizeof(out3_elts[0])) != NGX_OK)
|
sizeof(out3_elts) / sizeof(out3_elts[0])) != NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_rtmp_send_amf0(s, &sh, out2_elts,
|
if (ngx_rtmp_send_amf0(s, &sh, out4_elts,
|
||||||
sizeof(out2_elts) / sizeof(out2_elts[0])) != NGX_OK)
|
sizeof(out4_elts) / sizeof(out4_elts[0])) != NGX_OK)
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -661,17 +650,17 @@ ngx_rtmp_broadcast_set_data_frame(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_rtmp_core_srv_conf_t *cscf;
|
ngx_rtmp_core_srv_conf_t *cscf;
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL,
|
{ NGX_RTMP_AMF0_STRING, NULL, "@setDataFrame", 0 },
|
||||||
"@setDataFrame", sizeof("@setDataFrame") - 1 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
c = s->connection;
|
c = s->connection;
|
||||||
|
|
||||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
||||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_broadcast_module);
|
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_broadcast_module);
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, c->log, 0, "data_frame arrived");
|
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, c->log, 0, "data_frame arrived");
|
||||||
|
|
||||||
|
/* TODO: allow sending more meta packages to change broadcast content */
|
||||||
|
|
||||||
if (ctx->data_frame) {
|
if (ctx->data_frame) {
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
||||||
"duplicate data_frame");
|
"duplicate data_frame");
|
||||||
|
@ -721,32 +710,35 @@ static ngx_int_t
|
||||||
ngx_rtmp_broadcast_ok(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
ngx_rtmp_broadcast_ok(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_chain_t *in)
|
ngx_chain_t *in)
|
||||||
{
|
{
|
||||||
static double trans;
|
ngx_rtmp_header_t sh;
|
||||||
|
|
||||||
|
static double trans;
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
static ngx_rtmp_amf0_elt_t in_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, 0, &trans, sizeof(trans) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_inf[] = {
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "code", NULL, 0 },
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "level", NULL, 0 },
|
|
||||||
{ NGX_RTMP_AMF0_STRING, "description", NULL, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
||||||
{ NGX_RTMP_AMF0_STRING, NULL, "onStatus", sizeof("onStatus") - 1 },
|
{ NGX_RTMP_AMF0_STRING, NULL, "_result", 0 },
|
||||||
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, sizeof(trans) },
|
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, 0 },
|
||||||
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
||||||
{ NGX_RTMP_AMF0_OBJECT, NULL, out_inf, sizeof(out_inf) },
|
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* parse input */
|
||||||
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
if (ngx_rtmp_receive_amf0(s, in, in_elts,
|
||||||
sizeof(in_elts) / sizeof(in_elts[0])))
|
sizeof(in_elts) / sizeof(in_elts[0])))
|
||||||
{
|
{
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ngx_rtmp_send_amf0(s, h, out_elts,
|
memset(&sh, 0, sizeof(sh));
|
||||||
|
sh.csid = NGX_RTMP_BROADCAST_CSID_AMF0;
|
||||||
|
sh.type = NGX_RTMP_MSG_AMF0_META;
|
||||||
|
sh.msid = h->msid;
|
||||||
|
|
||||||
|
/* send simple _result */
|
||||||
|
return ngx_rtmp_send_amf0(s, &sh, out_elts,
|
||||||
sizeof(out_elts) / sizeof(out_elts[0]));
|
sizeof(out_elts) / sizeof(out_elts[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,11 @@ rtmp {
|
||||||
|
|
||||||
listen 1935;
|
listen 1935;
|
||||||
|
|
||||||
wait_key_frame off;
|
wait_key_frame on;
|
||||||
|
|
||||||
|
chunk_size 128;
|
||||||
|
|
||||||
|
max_buf 1000000;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
<div id="container">Loading the player ...</div>
|
<div id="container">Loading the player ...</div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
jwplayer("container").setup({
|
jwplayer("container").setup({
|
||||||
image: "http://192.168.0.100/showme.jpg",
|
image: "http://10.31.1.78/showme.jpg",
|
||||||
modes: [
|
modes: [
|
||||||
{ type: "flash",
|
{ type: "flash",
|
||||||
src: "/jwplayer/player.swf",
|
src: "/jwplayer/player.swf",
|
||||||
config: {
|
config: {
|
||||||
file: "video.mp4",
|
file: "video.mp4",
|
||||||
streamer: "rtmp://192.168.0.100/helo/p",
|
streamer: "rtmp://10.31.1.78/helo",
|
||||||
provider: "rtmp"
|
provider: "rtmp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var flashvars =
|
var flashvars =
|
||||||
{
|
{
|
||||||
'streamer': 'rtmp://192.168.0.100/helo/p',
|
'streamer': 'rtmp://10.31.1.78/helo',
|
||||||
'file': 'livestream',
|
'file': 'livestream',
|
||||||
'type': 'camera',
|
'type': 'camera',
|
||||||
'controlbar': 'bottom',
|
'controlbar': 'bottom',
|
||||||
|
|
Loading…
Reference in a new issue