mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for bug #215, srs rtmp dump support conn args. 2.0.90
This commit is contained in:
parent
4c18234678
commit
0e03d019a8
6 changed files with 296 additions and 41 deletions
|
@ -26,34 +26,194 @@ gcc srs_rtmp_dump.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_rtmp_dum
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "../../objs/include/srs_librtmp.h"
|
#include "../../objs/include/srs_librtmp.h"
|
||||||
|
|
||||||
|
void parse_amf0_object(char* p, srs_amf0_t args)
|
||||||
|
{
|
||||||
|
char opvt = 0; // object property value type.
|
||||||
|
const char* opnp = NULL; // object property name ptr.
|
||||||
|
const char* opvp = NULL; // object property value ptr.
|
||||||
|
|
||||||
|
while (*p) {
|
||||||
|
switch (*p++) {
|
||||||
|
case 'O':
|
||||||
|
while (*p && *p++ != ':') {
|
||||||
|
}
|
||||||
|
if (*p++ == '1') {
|
||||||
|
printf("amf0 object start\n");
|
||||||
|
} else {
|
||||||
|
printf("amf0 object end\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
opvt = *p++;
|
||||||
|
if (*p++ != ':') {
|
||||||
|
printf("object property must split by :.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
opnp = p++;
|
||||||
|
while (*p && *p++ != ':') {
|
||||||
|
}
|
||||||
|
p[-1] = 0;
|
||||||
|
opvp = p;
|
||||||
|
printf("amf0 %c property[%s]=%s\n", opvt, opnp, opvp);
|
||||||
|
switch(opvt) {
|
||||||
|
case 'S':
|
||||||
|
srs_amf0_object_property_set(args, opnp, srs_amf0_create_string(opvp));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unsupported object property.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
*p=0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("only supports an object arg.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
printf("dump rtmp stream to flv file\n");
|
printf("dump rtmp stream to flv file\n");
|
||||||
printf("srs(simple-rtmp-server) client librtmp library.\n");
|
printf("srs(simple-rtmp-server) client librtmp library.\n");
|
||||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||||
|
printf("@refer to http://rtmpdump.mplayerhq.hu/rtmpdump.1.html\n");
|
||||||
|
|
||||||
if (argc <= 2) {
|
struct option long_options[] = {
|
||||||
printf("Usage: %s <rtmp_url> <flv_path>\n"
|
{"rtmp", required_argument, 0, 'r'},
|
||||||
" rtmp_url RTMP stream url to play\n"
|
{"flv", required_argument, 0, 'o'},
|
||||||
" flv_path The flv file path to save\n"
|
{"swfUrl", required_argument, 0, 's'},
|
||||||
|
{"tcUrl", required_argument, 0, 't'},
|
||||||
|
{"pageUrl", required_argument, 0, 'p'},
|
||||||
|
{"conn", required_argument, 0, 'C'},
|
||||||
|
{"complex", no_argument, 0, 'x'},
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
int show_help = 0;
|
||||||
|
int complex_handshake = 0;
|
||||||
|
const char* rtmp_url = NULL;
|
||||||
|
const char* output_flv = NULL;
|
||||||
|
const char* swfUrl = NULL;
|
||||||
|
const char* tcUrl = NULL;
|
||||||
|
const char* pageUrl = NULL;
|
||||||
|
srs_amf0_t args = NULL;
|
||||||
|
|
||||||
|
int opt = 0;
|
||||||
|
int option_index = 0;
|
||||||
|
while((opt = getopt_long(argc, argv, "hxr:o:s:t:p:C:", long_options, &option_index)) != -1){
|
||||||
|
switch(opt){
|
||||||
|
case 'r':
|
||||||
|
rtmp_url = optarg;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
output_flv = optarg;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
swfUrl = optarg;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
tcUrl = optarg;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
pageUrl = optarg;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
if (!args) {
|
||||||
|
args = srs_amf0_create_object();
|
||||||
|
}
|
||||||
|
char* p = (char*)optarg;
|
||||||
|
parse_amf0_object(p, args);
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
complex_handshake = 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
show_help = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unsupported opt.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rtmp_url || show_help) {
|
||||||
|
printf("Usage: %s -r url [-o output] [-s swfUrl] [-t tcUrl] [-p pageUrl] [-C conndata] [--complex] [-h]\n"
|
||||||
|
"Options:\n"
|
||||||
|
" --rtmp -r url\n"
|
||||||
|
" URL of the server and media content.\n"
|
||||||
|
" --flv -o output\n"
|
||||||
|
" Specify the output file name. If the name is − or is omitted, the stream is written to stdout.\n"
|
||||||
|
" --complex\n"
|
||||||
|
" Whether use complex handshake(srs-librtmp with ssl required).\n"
|
||||||
|
" --swfUrl -s url\n"
|
||||||
|
" URL of the SWF player for the media. By default no value will be sent.\n"
|
||||||
|
" --tcUrl -t url\n"
|
||||||
|
" URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath.\n"
|
||||||
|
" --pageUrl -p url\n"
|
||||||
|
" URL of the web page in which the media was embedded. By default no value will be sent.\n"
|
||||||
|
" −−conn −C type:data\n"
|
||||||
|
" Append arbitrary AMF data to the Connect message. The type must be B for Boolean, N for number, S for string, O for object, or Z for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE, respectively. Likewise for Objects the data must be 0 or 1 to end or begin an object, respectively. Data items in subobjects may be named, by prefixing the type with 'N' and specifying the name before the value, e.g. NB:myFlag:1. This option may be used multiple times to construct arbitrary AMF sequences. E.g.\n"
|
||||||
|
" −C B:1 −C S:authMe −C O:1 −C NN:code:1.23 −C NS:flag:ok −C O:0\n"
|
||||||
|
" -C O:1 -C NS:CONN:\" -C B:4Rg9vr0\" -C O:0\n"
|
||||||
|
" @remark, support a object args only.\n"
|
||||||
|
" --help -h\n"
|
||||||
|
" Print a summary of command options.\n"
|
||||||
"For example:\n"
|
"For example:\n"
|
||||||
" %s rtmp://127.0.0.1:1935/live/livestream output.flv\n",
|
" %s -r rtmp://127.0.0.1:1935/live/livestream -o output.flv\n"
|
||||||
argv[0], argv[0]);
|
" %s -h\n",
|
||||||
|
argv[0], argv[0], argv[0]);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_human_trace("rtmp url: %s", argv[1]);
|
srs_human_trace("rtmp url: %s", rtmp_url);
|
||||||
srs_human_trace("flv path: %s", argv[2]);
|
srs_human_trace("handshake: %s", (complex_handshake? "complex" : "simple"));
|
||||||
srs_rtmp_t rtmp = srs_rtmp_create(argv[1]);
|
srs_human_trace("swfUrl: %s", swfUrl);
|
||||||
|
srs_human_trace("pageUrl: %s", pageUrl);
|
||||||
|
srs_human_trace("tcUrl: %s", tcUrl);
|
||||||
|
if (output_flv) {
|
||||||
|
srs_human_trace("flv output path: %s", output_flv);
|
||||||
|
} else {
|
||||||
|
srs_human_trace("output to console");
|
||||||
|
}
|
||||||
|
|
||||||
if (srs_rtmp_handshake(rtmp) != 0) {
|
srs_rtmp_t rtmp = srs_rtmp_create(rtmp_url);
|
||||||
srs_human_trace("simple handshake failed.");
|
|
||||||
|
if (__srs_rtmp_dns_resolve(rtmp) != 0) {
|
||||||
|
srs_human_trace("dns resolve failed.");
|
||||||
|
goto rtmp_destroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__srs_rtmp_connect_server(rtmp) != 0) {
|
||||||
|
srs_human_trace("connect to server failed.");
|
||||||
|
goto rtmp_destroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (complex_handshake) {
|
||||||
|
if (__srs_rtmp_do_complex_handshake(rtmp) != 0) {
|
||||||
|
srs_human_trace("complex handshake failed.");
|
||||||
|
goto rtmp_destroy;
|
||||||
|
}
|
||||||
|
srs_human_trace("do complex handshake success");
|
||||||
|
} else {
|
||||||
|
if (__srs_rtmp_do_simple_handshake(rtmp) != 0) {
|
||||||
|
srs_human_trace("simple handshake failed.");
|
||||||
|
goto rtmp_destroy;
|
||||||
|
}
|
||||||
|
srs_human_trace("do simple handshake success");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srs_rtmp_set_connect_args(rtmp, tcUrl, swfUrl, pageUrl, args) != 0) {
|
||||||
|
srs_human_trace("set connect args failed.");
|
||||||
goto rtmp_destroy;
|
goto rtmp_destroy;
|
||||||
}
|
}
|
||||||
srs_human_trace("simple handshake success");
|
|
||||||
|
|
||||||
if (srs_rtmp_connect_app(rtmp) != 0) {
|
if (srs_rtmp_connect_app(rtmp) != 0) {
|
||||||
srs_human_trace("connect vhost/app failed.");
|
srs_human_trace("connect vhost/app failed.");
|
||||||
|
@ -67,26 +227,31 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
srs_human_trace("play stream success");
|
srs_human_trace("play stream success");
|
||||||
|
|
||||||
srs_flv_t flv = srs_flv_open_write(argv[2]);
|
srs_flv_t flv = NULL;
|
||||||
|
if (output_flv) {
|
||||||
|
flv = srs_flv_open_write(output_flv);
|
||||||
|
}
|
||||||
|
|
||||||
// flv header
|
if (flv) {
|
||||||
char header[9];
|
// flv header
|
||||||
// 3bytes, signature, "FLV",
|
char header[9];
|
||||||
header[0] = 'F';
|
// 3bytes, signature, "FLV",
|
||||||
header[1] = 'L';
|
header[0] = 'F';
|
||||||
header[2] = 'V';
|
header[1] = 'L';
|
||||||
// 1bytes, version, 0x01,
|
header[2] = 'V';
|
||||||
header[3] = 0x01;
|
// 1bytes, version, 0x01,
|
||||||
// 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present.
|
header[3] = 0x01;
|
||||||
header[4] = 0x03; // audio + video.
|
// 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present.
|
||||||
// 4bytes, dataoffset
|
header[4] = 0x03; // audio + video.
|
||||||
header[5] = 0x00;
|
// 4bytes, dataoffset
|
||||||
header[6] = 0x00;
|
header[5] = 0x00;
|
||||||
header[7] = 0x00;
|
header[6] = 0x00;
|
||||||
header[8] = 0x09;
|
header[7] = 0x00;
|
||||||
if (srs_flv_write_header(flv, header) != 0) {
|
header[8] = 0x09;
|
||||||
srs_human_trace("write flv header failed.");
|
if (srs_flv_write_header(flv, header) != 0) {
|
||||||
goto rtmp_destroy;
|
srs_human_trace("write flv header failed.");
|
||||||
|
goto rtmp_destroy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -105,9 +270,11 @@ int main(int argc, char** argv)
|
||||||
goto rtmp_destroy;
|
goto rtmp_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srs_flv_write_tag(flv, type, timestamp, data, size) != 0) {
|
if (flv) {
|
||||||
srs_human_trace("dump rtmp packet failed.");
|
if (srs_flv_write_tag(flv, type, timestamp, data, size) != 0) {
|
||||||
goto rtmp_destroy;
|
srs_human_trace("dump rtmp packet failed.");
|
||||||
|
goto rtmp_destroy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -115,7 +282,9 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
rtmp_destroy:
|
rtmp_destroy:
|
||||||
srs_rtmp_destroy(rtmp);
|
srs_rtmp_destroy(rtmp);
|
||||||
srs_flv_close(flv);
|
if (flv) {
|
||||||
|
srs_flv_close(flv);
|
||||||
|
}
|
||||||
srs_human_trace("completed");
|
srs_human_trace("completed");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// current release version
|
// current release version
|
||||||
#define VERSION_MAJOR 2
|
#define VERSION_MAJOR 2
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 89
|
#define VERSION_REVISION 90
|
||||||
// server info.
|
// server info.
|
||||||
#define RTMP_SIG_SRS_KEY "SRS"
|
#define RTMP_SIG_SRS_KEY "SRS"
|
||||||
#define RTMP_SIG_SRS_ROLE "origin/edge server"
|
#define RTMP_SIG_SRS_ROLE "origin/edge server"
|
||||||
|
|
|
@ -66,6 +66,9 @@ struct Context
|
||||||
std::string app;
|
std::string app;
|
||||||
std::string stream;
|
std::string stream;
|
||||||
std::string param;
|
std::string param;
|
||||||
|
|
||||||
|
// extra request object for connect to server, NULL to ignore.
|
||||||
|
SrsRequest* req;
|
||||||
|
|
||||||
SrsRtmpClient* rtmp;
|
SrsRtmpClient* rtmp;
|
||||||
SimpleSocketStream* skt;
|
SimpleSocketStream* skt;
|
||||||
|
@ -93,12 +96,14 @@ struct Context
|
||||||
Context() {
|
Context() {
|
||||||
rtmp = NULL;
|
rtmp = NULL;
|
||||||
skt = NULL;
|
skt = NULL;
|
||||||
|
req = NULL;
|
||||||
stream_id = 0;
|
stream_id = 0;
|
||||||
h264_sps_pps_sent = false;
|
h264_sps_pps_sent = false;
|
||||||
h264_sps_changed = false;
|
h264_sps_changed = false;
|
||||||
h264_pps_changed = false;
|
h264_pps_changed = false;
|
||||||
}
|
}
|
||||||
virtual ~Context() {
|
virtual ~Context() {
|
||||||
|
srs_freep(req);
|
||||||
srs_freep(rtmp);
|
srs_freep(rtmp);
|
||||||
srs_freep(skt);
|
srs_freep(skt);
|
||||||
}
|
}
|
||||||
|
@ -595,6 +600,53 @@ int __srs_rtmp_connect_server(srs_rtmp_t rtmp)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __srs_rtmp_do_complex_handshake(srs_rtmp_t rtmp)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_assert(rtmp != NULL);
|
||||||
|
Context* context = (Context*)rtmp;
|
||||||
|
|
||||||
|
srs_assert(context->skt != NULL);
|
||||||
|
|
||||||
|
// simple handshake
|
||||||
|
srs_freep(context->rtmp);
|
||||||
|
context->rtmp = new SrsRtmpClient(context->skt);
|
||||||
|
|
||||||
|
if ((ret = context->rtmp->complex_handshake()) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srs_rtmp_set_connect_args(srs_rtmp_t rtmp,
|
||||||
|
const char* tcUrl, const char* swfUrl, const char* pageUrl, srs_amf0_t args
|
||||||
|
) {
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_assert(rtmp != NULL);
|
||||||
|
Context* context = (Context*)rtmp;
|
||||||
|
|
||||||
|
srs_freep(context->req);
|
||||||
|
context->req = new SrsRequest();
|
||||||
|
|
||||||
|
if (args) {
|
||||||
|
context->req->args = (SrsAmf0Object*)args;
|
||||||
|
}
|
||||||
|
if (tcUrl) {
|
||||||
|
context->req->tcUrl = tcUrl;
|
||||||
|
}
|
||||||
|
if (swfUrl) {
|
||||||
|
context->req->swfUrl = swfUrl;
|
||||||
|
}
|
||||||
|
if (pageUrl) {
|
||||||
|
context->req->pageUrl = pageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int __srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp)
|
int __srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -628,7 +680,7 @@ int srs_rtmp_connect_app(srs_rtmp_t rtmp)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ((ret = context->rtmp->connect_app(
|
if ((ret = context->rtmp->connect_app(
|
||||||
context->app, tcUrl, NULL, true)) != ERROR_SUCCESS)
|
context->app, tcUrl, context->req, true)) != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1725,6 +1777,11 @@ srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed)
|
||||||
return amf0;
|
return amf0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srs_amf0_t srs_amf0_create_string(const char* value)
|
||||||
|
{
|
||||||
|
return SrsAmf0Any::str(value);
|
||||||
|
}
|
||||||
|
|
||||||
srs_amf0_t srs_amf0_create_number(srs_amf0_number value)
|
srs_amf0_t srs_amf0_create_number(srs_amf0_number value)
|
||||||
{
|
{
|
||||||
return SrsAmf0Any::number(value);
|
return SrsAmf0Any::number(value);
|
||||||
|
@ -2374,6 +2431,9 @@ int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int
|
||||||
|
|
||||||
u_int32_t pts;
|
u_int32_t pts;
|
||||||
if (srs_utils_parse_timestamp(timestamp, type, data, size, &pts) != 0) {
|
if (srs_utils_parse_timestamp(timestamp, type, data, size, &pts) != 0) {
|
||||||
|
srs_human_trace("Video packet type=%s, dts=%d, pts=%d, size=%d, DecodeError",
|
||||||
|
srs_human_flv_tag_type2string(type), timestamp, pts, size
|
||||||
|
);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ extern int srs_version_revision();
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
// the RTMP handler.
|
// the RTMP handler.
|
||||||
typedef void* srs_rtmp_t;
|
typedef void* srs_rtmp_t;
|
||||||
|
typedef void* srs_amf0_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create/destroy a rtmp protocol stack.
|
* create/destroy a rtmp protocol stack.
|
||||||
|
@ -142,6 +143,18 @@ extern int __srs_rtmp_dns_resolve(srs_rtmp_t rtmp);
|
||||||
extern int __srs_rtmp_connect_server(srs_rtmp_t rtmp);
|
extern int __srs_rtmp_connect_server(srs_rtmp_t rtmp);
|
||||||
// do simple handshake over socket.
|
// do simple handshake over socket.
|
||||||
extern int __srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp);
|
extern int __srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp);
|
||||||
|
// do complex handshake over socket.
|
||||||
|
extern int __srs_rtmp_do_complex_handshake(srs_rtmp_t rtmp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the args of connect packet for rtmp.
|
||||||
|
* @param args, the extra amf0 object args.
|
||||||
|
* @remark, all params can be NULL to ignore.
|
||||||
|
* @remark, user should never free the args for we directly use it.
|
||||||
|
*/
|
||||||
|
extern int srs_rtmp_set_connect_args(srs_rtmp_t rtmp,
|
||||||
|
const char* tcUrl, const char* swfUrl, const char* pageUrl, srs_amf0_t args
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* connect to rtmp vhost/app
|
* connect to rtmp vhost/app
|
||||||
|
@ -546,7 +559,6 @@ extern srs_bool srs_flv_is_keyframe(char* data, int32_t size);
|
||||||
**************************************************************
|
**************************************************************
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
/* the output handler. */
|
/* the output handler. */
|
||||||
typedef void* srs_amf0_t;
|
|
||||||
typedef double srs_amf0_number;
|
typedef double srs_amf0_number;
|
||||||
/**
|
/**
|
||||||
* parse amf0 from data.
|
* parse amf0 from data.
|
||||||
|
@ -555,6 +567,7 @@ typedef double srs_amf0_number;
|
||||||
* @remark user must free the parsed or created object by srs_amf0_free.
|
* @remark user must free the parsed or created object by srs_amf0_free.
|
||||||
*/
|
*/
|
||||||
extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed);
|
extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed);
|
||||||
|
extern srs_amf0_t srs_amf0_create_string(const char* value);
|
||||||
extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value);
|
extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value);
|
||||||
extern srs_amf0_t srs_amf0_create_ecma_array();
|
extern srs_amf0_t srs_amf0_create_ecma_array();
|
||||||
extern srs_amf0_t srs_amf0_create_strict_array();
|
extern srs_amf0_t srs_amf0_create_strict_array();
|
||||||
|
|
|
@ -469,13 +469,17 @@ int SrsRtmpClient::connect_app2(
|
||||||
SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
|
SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
|
||||||
|
|
||||||
pkt->command_object->set("app", SrsAmf0Any::str(app.c_str()));
|
pkt->command_object->set("app", SrsAmf0Any::str(app.c_str()));
|
||||||
pkt->command_object->set("flashVer", SrsAmf0Any::str("WIN 12,0,0,41"));
|
pkt->command_object->set("flashVer", SrsAmf0Any::str("WIN 15,0,0,239"));
|
||||||
if (req) {
|
if (req) {
|
||||||
pkt->command_object->set("swfUrl", SrsAmf0Any::str(req->swfUrl.c_str()));
|
pkt->command_object->set("swfUrl", SrsAmf0Any::str(req->swfUrl.c_str()));
|
||||||
} else {
|
} else {
|
||||||
pkt->command_object->set("swfUrl", SrsAmf0Any::str());
|
pkt->command_object->set("swfUrl", SrsAmf0Any::str());
|
||||||
}
|
}
|
||||||
pkt->command_object->set("tcUrl", SrsAmf0Any::str(tc_url.c_str()));
|
if (req && req->tcUrl != "") {
|
||||||
|
pkt->command_object->set("tcUrl", SrsAmf0Any::str(req->tcUrl.c_str()));
|
||||||
|
} else {
|
||||||
|
pkt->command_object->set("tcUrl", SrsAmf0Any::str(tc_url.c_str()));
|
||||||
|
}
|
||||||
pkt->command_object->set("fpad", SrsAmf0Any::boolean(false));
|
pkt->command_object->set("fpad", SrsAmf0Any::boolean(false));
|
||||||
pkt->command_object->set("capabilities", SrsAmf0Any::number(239));
|
pkt->command_object->set("capabilities", SrsAmf0Any::number(239));
|
||||||
pkt->command_object->set("audioCodecs", SrsAmf0Any::number(3575));
|
pkt->command_object->set("audioCodecs", SrsAmf0Any::number(3575));
|
||||||
|
|
|
@ -31,7 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_protocol_buffer.hpp>
|
#include <srs_protocol_buffer.hpp>
|
||||||
#include <srs_protocol_utility.hpp>
|
#include <srs_protocol_utility.hpp>
|
||||||
|
|
||||||
|
// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213
|
||||||
|
#ifndef _WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -868,9 +872,14 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
|
||||||
int SrsProtocol::do_iovs_send(iovec* iovs, int size)
|
int SrsProtocol::do_iovs_send(iovec* iovs, int size)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// the limits of writev iovs.
|
// the limits of writev iovs.
|
||||||
|
// for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213
|
||||||
|
#ifndef _WIN32
|
||||||
static int limits = sysconf(_SC_IOV_MAX);
|
static int limits = sysconf(_SC_IOV_MAX);
|
||||||
|
#else
|
||||||
|
static int limits = 1024;
|
||||||
|
#endif
|
||||||
|
|
||||||
// send in a time.
|
// send in a time.
|
||||||
if (size < limits) {
|
if (size < limits) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue