mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-05-09 22:11:08 +02:00
test/
added flash tests
This commit is contained in:
parent
996bd6b93e
commit
ec948cd1ea
|
@ -140,6 +140,7 @@ typedef struct {
|
|||
#define NGX_RTMP_USER_RECORDED 4
|
||||
#define NGX_RTMP_USER_PING_REQUEST 6
|
||||
#define NGX_RTMP_USER_PING_RESPONSE 7
|
||||
#define NGX_RTMP_USER_UNKNOWN 8
|
||||
|
||||
|
||||
/* Chunk header:
|
||||
|
@ -344,6 +345,8 @@ ngx_int_t ngx_rtmp_send_user_ping_request(ngx_rtmp_session_t *s,
|
|||
uint32_t timestamp);
|
||||
ngx_int_t ngx_rtmp_send_user_ping_response(ngx_rtmp_session_t *s,
|
||||
uint32_t timestamp);
|
||||
ngx_int_t ngx_rtmp_send_user_unknown(ngx_rtmp_session_t *s,
|
||||
uint32_t timestamp);
|
||||
|
||||
/* AMF0 sender/receiver */
|
||||
ngx_int_t ngx_rtmp_send_amf0(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||
|
|
|
@ -251,9 +251,11 @@ ngx_rtmp_broadcast_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
ngx_chain_t *out;
|
||||
ngx_int_t vftype;
|
||||
ngx_rtmp_core_srv_conf_t *cscf;
|
||||
ngx_rtmp_header_t sh;
|
||||
|
||||
c = s->connection;
|
||||
|
||||
sh = *h;
|
||||
sh.csid = 4;
|
||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_broadcast_module);
|
||||
|
||||
|
@ -270,13 +272,13 @@ ngx_rtmp_broadcast_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
}
|
||||
|
||||
vftype = 0;
|
||||
if (h->type == NGX_RTMP_MSG_VIDEO) {
|
||||
if (sh.type == NGX_RTMP_MSG_VIDEO) {
|
||||
vftype = ngx_rtmp_get_video_frame_type(in);
|
||||
}
|
||||
|
||||
out = ngx_rtmp_append_shared_bufs(cscf, NULL, in);
|
||||
|
||||
ngx_rtmp_prepare_message(s, h, &ctx->lh, out);
|
||||
ngx_rtmp_prepare_message(s, &sh, &ctx->lh, out);
|
||||
|
||||
/* broadcast to all subscribers */
|
||||
for (cctx = *ngx_rtmp_broadcast_get_head(s);
|
||||
|
@ -307,7 +309,7 @@ ngx_rtmp_broadcast_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
|
||||
/* is the subscriber waiting for
|
||||
* a key frame? */
|
||||
if (h->type == NGX_RTMP_MSG_VIDEO
|
||||
if (sh.type == NGX_RTMP_MSG_VIDEO
|
||||
&& cctx->flags & NGX_RTMP_BROADCAST_WANT_KEYFRAME)
|
||||
{
|
||||
if (vftype && vftype != NGX_RTMP_VIDEO_KEY_FRAME) {
|
||||
|
@ -340,6 +342,8 @@ ngx_rtmp_broadcast_connect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
static u_char url[1024];
|
||||
static u_char acodecs[1024];
|
||||
static ngx_str_t app_str;
|
||||
static double capabilities = 31;
|
||||
static double object_enc;
|
||||
|
||||
static ngx_rtmp_amf0_elt_t in_cmd[] = {
|
||||
{ NGX_RTMP_AMF0_STRING, "app", app, sizeof(app) },
|
||||
|
@ -347,10 +351,16 @@ ngx_rtmp_broadcast_connect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
{ NGX_RTMP_AMF0_STRING, "audiocodecs" , acodecs, sizeof(acodecs) },
|
||||
};
|
||||
|
||||
static ngx_rtmp_amf0_elt_t out_obj[] = {
|
||||
{ NGX_RTMP_AMF0_STRING, "fmsVer", "FMS/3,0,1,123" , sizeof("FMS/3,0,1,123")-1 },
|
||||
{ NGX_RTMP_AMF0_NUMBER, "capabilities", &capabilities, sizeof(capabilities) },
|
||||
};
|
||||
|
||||
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, "code", NULL, 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[] = {
|
||||
|
@ -361,7 +371,7 @@ ngx_rtmp_broadcast_connect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
static ngx_rtmp_amf0_elt_t out_elts[] = {
|
||||
{ NGX_RTMP_AMF0_STRING, NULL, "_result", sizeof("_result") - 1 },
|
||||
{ NGX_RTMP_AMF0_NUMBER, NULL, &trans, sizeof(trans) },
|
||||
{ NGX_RTMP_AMF0_NULL , NULL, NULL, 0 },
|
||||
{ NGX_RTMP_AMF0_OBJECT, NULL, out_obj, sizeof(out_obj) },
|
||||
{ NGX_RTMP_AMF0_OBJECT, NULL, out_inf, sizeof(out_inf) },
|
||||
};
|
||||
|
||||
|
@ -373,8 +383,8 @@ ngx_rtmp_broadcast_connect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
|
||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
||||
|
||||
ngx_str_set(&out_inf[0], "NetConnection.Connect.Success");
|
||||
ngx_str_set(&out_inf[1], "status");
|
||||
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,
|
||||
|
@ -392,11 +402,12 @@ ngx_rtmp_broadcast_connect(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
ngx_rtmp_broadcast_join(s, &app_str, 0);
|
||||
|
||||
return ngx_rtmp_send_ack_size(s, cscf->ack_window)
|
||||
|| ngx_rtmp_send_bandwidth(s, cscf->ack_window, NGX_RTMP_LIMIT_SOFT)
|
||||
|| ngx_rtmp_send_bandwidth(s, cscf->ack_window, NGX_RTMP_LIMIT_DYNAMIC)
|
||||
|| ngx_rtmp_send_user_stream_begin(s, 0)
|
||||
|| ngx_rtmp_send_chunk_size(s, cscf->out_chunk_size)
|
||||
|| ngx_rtmp_send_amf0(s, h, out_elts,
|
||||
sizeof(out_elts) / sizeof(out_elts[0]))
|
||||
? NGX_ERROR
|
||||
? NGX_OK
|
||||
: NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ ngx_rtmp_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
|
||||
ngx_conf_merge_value(conf->max_streams, prev->max_streams, 16);
|
||||
ngx_conf_merge_value(conf->out_chunk_size, prev->out_chunk_size, 128);
|
||||
ngx_conf_merge_value(conf->out_chunk_size, prev->out_chunk_size, 4096);
|
||||
ngx_conf_merge_uint_value(conf->ack_window, prev->ack_window, 5000000);
|
||||
|
||||
if (prev->out_pool == NULL) {
|
||||
|
|
|
@ -904,7 +904,7 @@ ngx_rtmp_prepare_message(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|||
"RTMP prep %s (%d) fmt=%d csid=%uD timestamp=%uD "
|
||||
"mlen=%uD msid=%uD nbufs=%d",
|
||||
ngx_rtmp_message_type(h->type), (int)h->type, (int)fmt,
|
||||
h->csid, h->timestamp, h->mlen, h->msid, nbufs);
|
||||
h->csid, h->timestamp, mlen, h->msid, nbufs);
|
||||
|
||||
ext_timestamp = 0;
|
||||
if (timestamp >= 0x00ffffff) {
|
||||
|
|
|
@ -166,7 +166,6 @@ ngx_rtmp_amf0_message_handler(ngx_rtmp_session_t *s,
|
|||
ngx_rtmp_event_handler_pt ch;
|
||||
size_t len;
|
||||
|
||||
static double trans;
|
||||
static u_char func[128];
|
||||
|
||||
static ngx_rtmp_amf0_elt_t elts[] = {
|
||||
|
@ -199,14 +198,14 @@ ngx_rtmp_amf0_message_handler(ngx_rtmp_session_t *s,
|
|||
ngx_hash_strlow(func, func, len), func, len);
|
||||
|
||||
if (ch) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
||||
"AMF0 func '%s' trans=%f passed to handler", func, trans);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
||||
"AMF0 func '%s' passed to handler", func);
|
||||
|
||||
return ch(s, h, in);
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
||||
"AMF0 cmd '%s' trans=%f no handler", func, trans);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
||||
"AMF0 cmd '%s' no handler", func);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
@ -184,6 +184,24 @@ ngx_rtmp_send_user_ping_response(ngx_rtmp_session_t *s, uint32_t timestamp)
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_rtmp_send_user_unknown(ngx_rtmp_session_t *s, uint32_t timestamp)
|
||||
{
|
||||
static uint32_t zero;
|
||||
static uint32_t one = 1;
|
||||
uint32_t val;
|
||||
|
||||
NGX_RTMP_UCTL_START(s, NGX_RTMP_MSG_USER, NGX_RTMP_USER_UNKNOWN);
|
||||
|
||||
NGX_RTMP_USER_OUT4(zero);
|
||||
NGX_RTMP_USER_OUT4(one);
|
||||
val = timestamp & 0x7fffffff;
|
||||
NGX_RTMP_USER_OUT4(val);
|
||||
|
||||
NGX_RTMP_USER_END(s);
|
||||
}
|
||||
|
||||
|
||||
/* AMF0 sender */
|
||||
ngx_int_t
|
||||
ngx_rtmp_send_amf0(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||
|
|
40
test/nginx.conf
Normal file
40
test/nginx.conf
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
#user nobody;
|
||||
worker_processes 1;
|
||||
|
||||
error_log logs/error.log debug;
|
||||
#error_log logs/error.log notice;
|
||||
#error_log logs/error.log info;
|
||||
|
||||
#pid logs/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
rtmp {
|
||||
|
||||
server {
|
||||
|
||||
listen 1935;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
http {
|
||||
|
||||
server {
|
||||
|
||||
# testing framework
|
||||
# based on flowplayer (http://flowplayer.org)
|
||||
|
||||
listen 8080;
|
||||
|
||||
location / {
|
||||
root /home/rarutyunyan/nginx-rtmp-module/test/www;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
test/play.sh
Executable file
1
test/play.sh
Executable file
|
@ -0,0 +1 @@
|
|||
ffplay -loglevel verbose "rtmp://192.168.0.100/helo/pd"
|
20
test/www/index.html
Normal file
20
test/www/index.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<b>Play</b> | <a href="record.html">Record</a>
|
||||
<br/>
|
||||
<script type="text/javascript" src="/jwplayer/jwplayer.js"></script>
|
||||
|
||||
<div id="container">Loading the player ...</div>
|
||||
<script type="text/javascript">
|
||||
jwplayer("container").setup({
|
||||
image: "http://192.168.0.100/showme.jpg",
|
||||
modes: [
|
||||
{ type: "flash",
|
||||
src: "/jwplayer/player.swf",
|
||||
config: {
|
||||
file: "video.mp4",
|
||||
streamer: "rtmp://192.168.0.100/helo/p",
|
||||
provider: "rtmp"
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
</script>
|
1
test/www/jwplayer/jwplayer.js
Normal file
1
test/www/jwplayer/jwplayer.js
Normal file
File diff suppressed because one or more lines are too long
BIN
test/www/jwplayer/player.swf
Normal file
BIN
test/www/jwplayer/player.swf
Normal file
Binary file not shown.
BIN
test/www/jwplayer_old/player.swf
Normal file
BIN
test/www/jwplayer_old/player.swf
Normal file
Binary file not shown.
5
test/www/jwplayer_old/swfobject.js
Normal file
5
test/www/jwplayer_old/swfobject.js
Normal file
File diff suppressed because one or more lines are too long
41
test/www/record.html
Normal file
41
test/www/record.html
Normal file
|
@ -0,0 +1,41 @@
|
|||
<a href="index.html">Play</a> | <b>Record</b>
|
||||
<br/>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script src="jwplayer_old/swfobject.js"></script>
|
||||
<script type="text/javascript">
|
||||
var flashvars =
|
||||
{
|
||||
'streamer': 'rtmp://192.168.0.100/helo/p',
|
||||
'file': 'livestream',
|
||||
'type': 'camera',
|
||||
'controlbar': 'bottom',
|
||||
'stretching': 'none',
|
||||
'frontcolor': '86C29D', // text & icons (green)
|
||||
'backcolor': '849BC1', // playlist background (blue)
|
||||
'lightcolor': 'C286BA', // selected text/track highlight (pink)
|
||||
'screencolor': 'FFFFFF', // screen background (black)
|
||||
'id': 'playerID',
|
||||
'autostart': 'true'
|
||||
};
|
||||
|
||||
var params =
|
||||
{
|
||||
'allowfullscreen': 'true',
|
||||
'allowscriptaccess': 'always',
|
||||
'bgcolor': '#FFFFFF'
|
||||
};
|
||||
|
||||
var attributes =
|
||||
{
|
||||
'id': 'playerID',
|
||||
'name': 'playerID'
|
||||
};
|
||||
swfobject.embedSWF('jwplayer_old/player.swf', 'player', '320', '260', '9.0.124', false, flashvars, params, attributes);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="playercontainer" class="playercontainer"><a id="player" class="player" href="http://get.adobe.com/flashplayer/">Get the Adobe Flash Player to see this video.</a></div>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in a new issue