mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
support ecma array. connect app response.
This commit is contained in:
parent
8283ed465a
commit
1beee1e970
6 changed files with 344 additions and 26 deletions
|
@ -54,6 +54,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define RTMP_AMF0_Invalid 0x3F
|
#define RTMP_AMF0_Invalid 0x3F
|
||||||
|
|
||||||
int srs_amf0_get_object_eof_size();
|
int srs_amf0_get_object_eof_size();
|
||||||
|
int srs_amf0_get_any_size(SrsAmf0Any* value);
|
||||||
int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);
|
int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&);
|
||||||
int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*);
|
int srs_amf0_write_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*);
|
||||||
int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);
|
int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value);
|
||||||
|
@ -88,43 +89,51 @@ bool SrsAmf0Any::is_object()
|
||||||
return marker == RTMP_AMF0_Object;
|
return marker == RTMP_AMF0_Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsAmf0Any::is_ecma_array()
|
||||||
|
{
|
||||||
|
return marker == RTMP_AMF0_EcmaArray;
|
||||||
|
}
|
||||||
|
|
||||||
bool SrsAmf0Any::is_object_eof()
|
bool SrsAmf0Any::is_object_eof()
|
||||||
{
|
{
|
||||||
return marker == RTMP_AMF0_ObjectEnd;
|
return marker == RTMP_AMF0_ObjectEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0String::SrsAmf0String()
|
SrsAmf0String::SrsAmf0String(const char* _value)
|
||||||
{
|
{
|
||||||
marker = RTMP_AMF0_String;
|
marker = RTMP_AMF0_String;
|
||||||
|
if (_value) {
|
||||||
|
value = _value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0String::~SrsAmf0String()
|
SrsAmf0String::~SrsAmf0String()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0Boolean::SrsAmf0Boolean()
|
SrsAmf0Boolean::SrsAmf0Boolean(bool _value)
|
||||||
{
|
{
|
||||||
marker = RTMP_AMF0_Boolean;
|
marker = RTMP_AMF0_Boolean;
|
||||||
value = false;
|
value = _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0Boolean::~SrsAmf0Boolean()
|
SrsAmf0Boolean::~SrsAmf0Boolean()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0Number::SrsAmf0Number()
|
SrsAmf0Number::SrsAmf0Number(double _value)
|
||||||
{
|
{
|
||||||
marker = RTMP_AMF0_Number;
|
marker = RTMP_AMF0_Number;
|
||||||
value = 0;
|
value = _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0Number::~SrsAmf0Number()
|
SrsAmf0Number::~SrsAmf0Number()
|
||||||
{
|
{
|
||||||
marker = RTMP_AMF0_ObjectEnd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()
|
SrsAmf0ObjectEOF::SrsAmf0ObjectEOF()
|
||||||
{
|
{
|
||||||
|
marker = RTMP_AMF0_ObjectEnd;
|
||||||
utf8_empty = 0x00;
|
utf8_empty = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +182,47 @@ SrsAmf0Any* SrsAmf0Object::ensure_property_string(std::string name)
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsASrsAmf0EcmaArray::SrsASrsAmf0EcmaArray()
|
||||||
|
{
|
||||||
|
marker = RTMP_AMF0_EcmaArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsASrsAmf0EcmaArray::~SrsASrsAmf0EcmaArray()
|
||||||
|
{
|
||||||
|
std::map<std::string, SrsAmf0Any*>::iterator it;
|
||||||
|
for (it = properties.begin(); it != properties.end(); ++it) {
|
||||||
|
SrsAmf0Any* any = it->second;
|
||||||
|
delete any;
|
||||||
|
}
|
||||||
|
properties.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsAmf0Any* SrsASrsAmf0EcmaArray::get_property(std::string name)
|
||||||
|
{
|
||||||
|
std::map<std::string, SrsAmf0Any*>::iterator it;
|
||||||
|
|
||||||
|
if ((it = properties.find(name)) == properties.end()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsAmf0Any* SrsASrsAmf0EcmaArray::ensure_property_string(std::string name)
|
||||||
|
{
|
||||||
|
SrsAmf0Any* prop = get_property(name);
|
||||||
|
|
||||||
|
if (!prop) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prop->is_string()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
int srs_amf0_read_utf8(SrsStream* stream, std::string& value)
|
int srs_amf0_read_utf8(SrsStream* stream, std::string& value)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -481,6 +531,14 @@ int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value)
|
||||||
value = p;
|
value = p;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
case RTMP_AMF0_EcmaArray: {
|
||||||
|
SrsASrsAmf0EcmaArray* p = NULL;
|
||||||
|
if ((ret = srs_amf0_read_ecma_array(stream, p)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
value = p;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
case RTMP_AMF0_Invalid:
|
case RTMP_AMF0_Invalid:
|
||||||
default: {
|
default: {
|
||||||
ret = ERROR_RTMP_AMF0_INVALID;
|
ret = ERROR_RTMP_AMF0_INVALID;
|
||||||
|
@ -518,6 +576,10 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
|
||||||
SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
|
SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
|
||||||
return srs_amf0_write_object(stream, p);
|
return srs_amf0_write_object(stream, p);
|
||||||
}
|
}
|
||||||
|
case RTMP_AMF0_EcmaArray: {
|
||||||
|
SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);
|
||||||
|
return srs_amf0_write_ecma_array(stream, p);
|
||||||
|
}
|
||||||
case RTMP_AMF0_Invalid:
|
case RTMP_AMF0_Invalid:
|
||||||
default: {
|
default: {
|
||||||
ret = ERROR_RTMP_AMF0_INVALID;
|
ret = ERROR_RTMP_AMF0_INVALID;
|
||||||
|
@ -529,6 +591,52 @@ int srs_amf0_write_any(SrsStream* stream, SrsAmf0Any* value)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int srs_amf0_get_any_size(SrsAmf0Any* value)
|
||||||
|
{
|
||||||
|
if (!value) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
switch (value->marker) {
|
||||||
|
case RTMP_AMF0_String: {
|
||||||
|
SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value);
|
||||||
|
size += srs_amf0_get_string_size(p->value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_Boolean: {
|
||||||
|
size += srs_amf0_get_boolean_size();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_Number: {
|
||||||
|
size += srs_amf0_get_number_size();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_ObjectEnd: {
|
||||||
|
size += srs_amf0_get_object_eof_size();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_Object: {
|
||||||
|
SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
|
||||||
|
size += srs_amf0_get_object_size(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RTMP_AMF0_EcmaArray: {
|
||||||
|
SrsASrsAmf0EcmaArray* p = srs_amf0_convert<SrsASrsAmf0EcmaArray>(value);
|
||||||
|
size += srs_amf0_get_ecma_array_size(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// TOOD: other AMF0 types.
|
||||||
|
srs_warn("ignore unkown AMF0 type size.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)
|
int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -699,6 +807,125 @@ int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// marker
|
||||||
|
if (!stream->require(1)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 read ecma_array marker failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char marker = stream->read_1bytes();
|
||||||
|
if (marker != RTMP_AMF0_EcmaArray) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 check ecma_array marker failed. "
|
||||||
|
"marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_verbose("amf0 read ecma_array marker success");
|
||||||
|
|
||||||
|
// count
|
||||||
|
if (!stream->require(4)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_DECODE;
|
||||||
|
srs_error("amf0 read ecma_array count failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t count = stream->read_4bytes();
|
||||||
|
srs_verbose("amf0 read ecma_array count success. count=%d", count);
|
||||||
|
|
||||||
|
// value
|
||||||
|
value = new SrsASrsAmf0EcmaArray();
|
||||||
|
value->count = count;
|
||||||
|
|
||||||
|
while (!stream->empty()) {
|
||||||
|
// property-name: utf8 string
|
||||||
|
std::string property_name;
|
||||||
|
if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("amf0 ecma_array read property name failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// property-value: any
|
||||||
|
SrsAmf0Any* property_value = NULL;
|
||||||
|
if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("amf0 ecma_array read property_value failed. "
|
||||||
|
"name=%s, ret=%d", property_name.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AMF0 Object EOF.
|
||||||
|
if (property_name.empty() || !property_value || property_value->is_object_eof()) {
|
||||||
|
if (property_value) {
|
||||||
|
delete property_value;
|
||||||
|
}
|
||||||
|
srs_info("amf0 read ecma_array EOF.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add property
|
||||||
|
value->properties[property_name] = property_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_assert(value != NULL);
|
||||||
|
|
||||||
|
// marker
|
||||||
|
if (!stream->require(1)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_ENCODE;
|
||||||
|
srs_error("amf0 write ecma_array marker failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->write_1bytes(RTMP_AMF0_EcmaArray);
|
||||||
|
srs_verbose("amf0 write ecma_array marker success");
|
||||||
|
|
||||||
|
// count
|
||||||
|
if (!stream->require(4)) {
|
||||||
|
ret = ERROR_RTMP_AMF0_ENCODE;
|
||||||
|
srs_error("amf0 write ecma_array count failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream->write_4bytes(value->count);
|
||||||
|
srs_verbose("amf0 write ecma_array count success. count=%d", value->count);
|
||||||
|
|
||||||
|
// value
|
||||||
|
std::map<std::string, SrsAmf0Any*>::iterator it;
|
||||||
|
for (it = value->properties.begin(); it != value->properties.end(); ++it) {
|
||||||
|
std::string name = it->first;
|
||||||
|
SrsAmf0Any* any = it->second;
|
||||||
|
|
||||||
|
if ((ret = srs_amf0_write_utf8(stream, name)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("write ecma_array property name failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = srs_amf0_write_any(stream, any)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("write ecma_array property value failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_verbose("write amf0 property success. name=%s", name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = srs_amf0_write_object_eof(stream, &value->eof)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("write ecma_array eof failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
srs_verbose("write ecma_array object success.");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int srs_amf0_get_utf8_size(std::string value)
|
int srs_amf0_get_utf8_size(std::string value)
|
||||||
{
|
{
|
||||||
return 2 + value.length();
|
return 2 + value.length();
|
||||||
|
@ -733,21 +960,29 @@ int srs_amf0_get_object_size(SrsAmf0Object* obj)
|
||||||
SrsAmf0Any* value = it->second;
|
SrsAmf0Any* value = it->second;
|
||||||
|
|
||||||
size += srs_amf0_get_utf8_size(name);
|
size += srs_amf0_get_utf8_size(name);
|
||||||
|
size += srs_amf0_get_any_size(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
size += srs_amf0_get_object_eof_size();
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr)
|
||||||
|
{
|
||||||
|
if (!arr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = 1 + 4;
|
||||||
|
|
||||||
|
std::map<std::string, SrsAmf0Any*>::iterator it;
|
||||||
|
for (it = arr->properties.begin(); it != arr->properties.end(); ++it) {
|
||||||
|
std::string name = it->first;
|
||||||
|
SrsAmf0Any* value = it->second;
|
||||||
|
|
||||||
if (value->is_boolean()) {
|
size += srs_amf0_get_utf8_size(name);
|
||||||
size += srs_amf0_get_boolean_size();
|
size += srs_amf0_get_any_size(value);
|
||||||
} else if (value->is_number()) {
|
|
||||||
size += srs_amf0_get_number_size();
|
|
||||||
} else if (value->is_string()) {
|
|
||||||
SrsAmf0String* p = srs_amf0_convert<SrsAmf0String>(value);
|
|
||||||
size += srs_amf0_get_string_size(p->value);
|
|
||||||
} else if (value->is_object()) {
|
|
||||||
SrsAmf0Object* p = srs_amf0_convert<SrsAmf0Object>(value);
|
|
||||||
size += srs_amf0_get_object_size(p);
|
|
||||||
} else {
|
|
||||||
// TOOD: other AMF0 types.
|
|
||||||
srs_warn("ignore unkown AMF0 type size.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size += srs_amf0_get_object_eof_size();
|
size += srs_amf0_get_object_eof_size();
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct SrsAmf0Any
|
||||||
virtual bool is_number();
|
virtual bool is_number();
|
||||||
virtual bool is_object();
|
virtual bool is_object();
|
||||||
virtual bool is_object_eof();
|
virtual bool is_object_eof();
|
||||||
|
virtual bool is_ecma_array();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,7 +69,7 @@ struct SrsAmf0String : public SrsAmf0Any
|
||||||
{
|
{
|
||||||
std::string value;
|
std::string value;
|
||||||
|
|
||||||
SrsAmf0String();
|
SrsAmf0String(const char* _value = NULL);
|
||||||
virtual ~SrsAmf0String();
|
virtual ~SrsAmf0String();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ struct SrsAmf0Boolean : public SrsAmf0Any
|
||||||
{
|
{
|
||||||
bool value;
|
bool value;
|
||||||
|
|
||||||
SrsAmf0Boolean();
|
SrsAmf0Boolean(bool _value = false);
|
||||||
virtual ~SrsAmf0Boolean();
|
virtual ~SrsAmf0Boolean();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,7 +98,7 @@ struct SrsAmf0Number : public SrsAmf0Any
|
||||||
{
|
{
|
||||||
double value;
|
double value;
|
||||||
|
|
||||||
SrsAmf0Number();
|
SrsAmf0Number(double _value = 0.0);
|
||||||
virtual ~SrsAmf0Number();
|
virtual ~SrsAmf0Number();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,6 +132,25 @@ struct SrsAmf0Object : public SrsAmf0Any
|
||||||
virtual SrsAmf0Any* ensure_property_string(std::string name);
|
virtual SrsAmf0Any* ensure_property_string(std::string name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.10 ECMA Array Type
|
||||||
|
* ecma-array-type = associative-count *(object-property)
|
||||||
|
* associative-count = U32
|
||||||
|
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
|
||||||
|
*/
|
||||||
|
struct SrsASrsAmf0EcmaArray : public SrsAmf0Any
|
||||||
|
{
|
||||||
|
int32_t count;
|
||||||
|
std::map<std::string, SrsAmf0Any*> properties;
|
||||||
|
SrsAmf0ObjectEOF eof;
|
||||||
|
|
||||||
|
SrsASrsAmf0EcmaArray();
|
||||||
|
virtual ~SrsASrsAmf0EcmaArray();
|
||||||
|
|
||||||
|
virtual SrsAmf0Any* get_property(std::string name);
|
||||||
|
virtual SrsAmf0Any* ensure_property_string(std::string name);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* read amf0 utf8 string from stream.
|
* read amf0 utf8 string from stream.
|
||||||
* 1.3.1 Strings and UTF-8
|
* 1.3.1 Strings and UTF-8
|
||||||
|
@ -176,6 +196,16 @@ extern int srs_amf0_write_number(SrsStream* stream, double value);
|
||||||
extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value);
|
extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value);
|
||||||
extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value);
|
extern int srs_amf0_write_object(SrsStream* stream, SrsAmf0Object* value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read amf0 object from stream.
|
||||||
|
* 2.10 ECMA Array Type
|
||||||
|
* ecma-array-type = associative-count *(object-property)
|
||||||
|
* associative-count = U32
|
||||||
|
* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker)
|
||||||
|
*/
|
||||||
|
extern int srs_amf0_read_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray*& value);
|
||||||
|
extern int srs_amf0_write_ecma_array(SrsStream* stream, SrsASrsAmf0EcmaArray* value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get amf0 objects size.
|
* get amf0 objects size.
|
||||||
*/
|
*/
|
||||||
|
@ -184,7 +214,8 @@ extern int srs_amf0_get_string_size(std::string value);
|
||||||
extern int srs_amf0_get_number_size();
|
extern int srs_amf0_get_number_size();
|
||||||
extern int srs_amf0_get_boolean_size();
|
extern int srs_amf0_get_boolean_size();
|
||||||
extern int srs_amf0_get_object_size(SrsAmf0Object* obj);
|
extern int srs_amf0_get_object_size(SrsAmf0Object* obj);
|
||||||
|
extern int srs_amf0_get_ecma_array_size(SrsASrsAmf0EcmaArray* arr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convert the any to specified object.
|
* convert the any to specified object.
|
||||||
* @return T*, the converted object. never NULL.
|
* @return T*, the converted object. never NULL.
|
||||||
|
|
|
@ -92,6 +92,12 @@ int SrsClient::do_cycle()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
srs_verbose("set peer bandwidth success");
|
srs_verbose("set peer bandwidth success");
|
||||||
|
|
||||||
|
if ((ret = rtmp->response_connect_app()) != ERROR_SUCCESS) {
|
||||||
|
srs_error("response connect app failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_verbose("response connect app success");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1061,8 +1061,8 @@ SrsConnectAppResPacket::SrsConnectAppResPacket()
|
||||||
{
|
{
|
||||||
command_name = RTMP_AMF0_COMMAND_CONNECT;
|
command_name = RTMP_AMF0_COMMAND_CONNECT;
|
||||||
transaction_id = 1;
|
transaction_id = 1;
|
||||||
props = NULL;
|
props = new SrsAmf0Object();
|
||||||
info = NULL;
|
info = new SrsAmf0Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConnectAppResPacket::~SrsConnectAppResPacket()
|
SrsConnectAppResPacket::~SrsConnectAppResPacket()
|
||||||
|
|
|
@ -30,6 +30,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_core_auto_free.hpp>
|
#include <srs_core_auto_free.hpp>
|
||||||
#include <srs_core_amf0.hpp>
|
#include <srs_core_amf0.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the signature for packets to client.
|
||||||
|
*/
|
||||||
|
#define RTMP_SIG_FMS_VER "3,5,3,888"
|
||||||
|
#define RTMP_SIG_AMF0_VER 3
|
||||||
|
#define RTMP_SIG_SRS_NAME "srs(simple rtmp server)"
|
||||||
|
#define RTMP_SIG_SRS_URL "https://github.com/winlinvip/simple-rtmp-server"
|
||||||
|
#define RTMP_SIG_SRS_VERSION "0.1"
|
||||||
|
|
||||||
int SrsRequest::discovery_app()
|
int SrsRequest::discovery_app()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -205,3 +214,39 @@ int SrsRtmp::set_peer_bandwidth(int bandwidth, int type)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsRtmp::response_connect_app()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
SrsMessage* msg = new SrsMessage();
|
||||||
|
SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();
|
||||||
|
|
||||||
|
pkt->command_name = "_result";
|
||||||
|
|
||||||
|
pkt->props->properties["fmsVer"] = new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER);
|
||||||
|
pkt->props->properties["capabilities"] = new SrsAmf0Number(123);
|
||||||
|
pkt->props->properties["mode"] = new SrsAmf0Number(1);
|
||||||
|
|
||||||
|
pkt->info->properties["level"] = new SrsAmf0String("status");
|
||||||
|
pkt->info->properties["code"] = new SrsAmf0String("NetConnection.Connect.Success");
|
||||||
|
pkt->info->properties["description"] = new SrsAmf0String("Connection succeeded");
|
||||||
|
pkt->info->properties["objectEncoding"] = new SrsAmf0Number(RTMP_SIG_AMF0_VER);
|
||||||
|
SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray();
|
||||||
|
pkt->info->properties["data"] = data;
|
||||||
|
|
||||||
|
data->properties["version"] = new SrsAmf0String(RTMP_SIG_FMS_VER);
|
||||||
|
data->properties["server"] = new SrsAmf0String(RTMP_SIG_SRS_NAME);
|
||||||
|
data->properties["srs_url"] = new SrsAmf0String(RTMP_SIG_SRS_URL);
|
||||||
|
data->properties["srs_version"] = new SrsAmf0String(RTMP_SIG_SRS_VERSION);
|
||||||
|
|
||||||
|
msg->set_packet(pkt);
|
||||||
|
|
||||||
|
if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("send connect app response message failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_info("send connect app response message success.");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
* using the Limit type field.
|
* using the Limit type field.
|
||||||
*/
|
*/
|
||||||
virtual int set_peer_bandwidth(int bandwidth, int type);
|
virtual int set_peer_bandwidth(int bandwidth, int type);
|
||||||
|
virtual int response_connect_app();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue