winlin

srs-librtmp: implements the publish and play.

@@ -35,7 +35,7 @@ int main(int argc, char** argv) @@ -35,7 +35,7 @@ int main(int argc, char** argv)
35 printf("srs(simple-rtmp-server) client librtmp library.\n"); 35 printf("srs(simple-rtmp-server) client librtmp library.\n");
36 printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); 36 printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
37 37
38 - rtmp = srs_rtmp_create("rtmp://127.0.0.1:1936/live/livestream"); 38 + rtmp = srs_rtmp_create("rtmp://127.0.0.1:1935/live/livestream");
39 39
40 if (srs_simple_handshake(rtmp) != 0) { 40 if (srs_simple_handshake(rtmp) != 0) {
41 printf("simple handshake failed.\n"); 41 printf("simple handshake failed.\n");
@@ -230,7 +230,8 @@ int SrsClient::stream_service_cycle() @@ -230,7 +230,8 @@ int SrsClient::stream_service_cycle()
230 return ret; 230 return ret;
231 } 231 }
232 req->strip(); 232 req->strip();
233 - srs_trace("identify client success. type=%d, stream_name=%s", type, req->stream.c_str()); 233 + srs_trace("identify client success. type=%s, stream_name=%s",
  234 + srs_client_type_string(type).c_str(), req->stream.c_str());
234 235
235 // client is identified, set the timeout to service timeout. 236 // client is identified, set the timeout to service timeout.
236 rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US); 237 rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_US);
@@ -249,6 +249,10 @@ int srs_publish_stream(srs_rtmp_t rtmp) @@ -249,6 +249,10 @@ int srs_publish_stream(srs_rtmp_t rtmp)
249 srs_assert(rtmp != NULL); 249 srs_assert(rtmp != NULL);
250 Context* context = (Context*)rtmp; 250 Context* context = (Context*)rtmp;
251 251
  252 + if ((ret = context->rtmp->fmle_publish(context->stream, context->stream_id)) != ERROR_SUCCESS) {
  253 + return ret;
  254 + }
  255 +
252 return ret; 256 return ret;
253 } 257 }
254 258
@@ -176,6 +176,17 @@ SrsResponse::~SrsResponse() @@ -176,6 +176,17 @@ SrsResponse::~SrsResponse()
176 { 176 {
177 } 177 }
178 178
  179 +string srs_client_type_string(SrsClientType type)
  180 +{
  181 + switch (type) {
  182 + case SrsClientPlay: return "Play";
  183 + case SrsClientFlashPublish: return "FlashPublish";
  184 + case SrsClientFMLEPublish: return "FMLEPublish";
  185 + default: return "Unknown";
  186 + }
  187 + return "Unknown";
  188 +}
  189 +
179 SrsRtmpClient::SrsRtmpClient(ISrsProtocolReaderWriter* skt) 190 SrsRtmpClient::SrsRtmpClient(ISrsProtocolReaderWriter* skt)
180 { 191 {
181 io = skt; 192 io = skt;
@@ -441,6 +452,87 @@ int SrsRtmpClient::publish(string stream, int stream_id) @@ -441,6 +452,87 @@ int SrsRtmpClient::publish(string stream, int stream_id)
441 return ret; 452 return ret;
442 } 453 }
443 454
  455 +int SrsRtmpClient::fmle_publish(string stream, int& stream_id)
  456 +{
  457 + stream_id = 0;
  458 +
  459 + int ret = ERROR_SUCCESS;
  460 +
  461 + // SrsFMLEStartPacket
  462 + if (true) {
  463 + SrsCommonMessage* msg = new SrsCommonMessage();
  464 + SrsFMLEStartPacket* pkt = SrsFMLEStartPacket::create_release_stream(stream);
  465 +
  466 + msg->set_packet(pkt, 0);
  467 +
  468 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  469 + srs_error("send FMLE publish "
  470 + "release stream failed. stream=%s, ret=%d", stream.c_str(), ret);
  471 + return ret;
  472 + }
  473 + }
  474 +
  475 + // FCPublish
  476 + if (true) {
  477 + SrsCommonMessage* msg = new SrsCommonMessage();
  478 + SrsFMLEStartPacket* pkt = SrsFMLEStartPacket::create_FC_publish(stream);
  479 +
  480 + msg->set_packet(pkt, 0);
  481 +
  482 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  483 + srs_error("send FMLE publish "
  484 + "FCPublish failed. stream=%s, ret=%d", stream.c_str(), ret);
  485 + return ret;
  486 + }
  487 + }
  488 +
  489 + // CreateStream
  490 + if (true) {
  491 + SrsCommonMessage* msg = new SrsCommonMessage();
  492 + SrsCreateStreamPacket* pkt = new SrsCreateStreamPacket();
  493 +
  494 + pkt->transaction_id = 4;
  495 + msg->set_packet(pkt, 0);
  496 +
  497 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  498 + srs_error("send FMLE publish "
  499 + "createStream failed. stream=%s, ret=%d", stream.c_str(), ret);
  500 + return ret;
  501 + }
  502 + }
  503 +
  504 + // expect result of CreateStream
  505 + if (true) {
  506 + SrsCommonMessage* msg = NULL;
  507 + SrsCreateStreamResPacket* pkt = NULL;
  508 + if ((ret = srs_rtmp_expect_message<SrsCreateStreamResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  509 + srs_error("expect create stream response message failed. ret=%d", ret);
  510 + return ret;
  511 + }
  512 + SrsAutoFree(SrsCommonMessage, msg, false);
  513 + srs_info("get create stream response message");
  514 +
  515 + stream_id = (int)pkt->stream_id;
  516 + }
  517 +
  518 + // publish(stream)
  519 + if (true) {
  520 + SrsCommonMessage* msg = new SrsCommonMessage();
  521 + SrsPublishPacket* pkt = new SrsPublishPacket();
  522 +
  523 + pkt->stream_name = stream;
  524 + msg->set_packet(pkt, stream_id);
  525 +
  526 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  527 + srs_error("send FMLE publish publish failed. "
  528 + "stream=%s, stream_id=%d, ret=%d", stream.c_str(), stream_id, ret);
  529 + return ret;
  530 + }
  531 + }
  532 +
  533 + return ret;
  534 +}
  535 +
444 SrsRtmpServer::SrsRtmpServer(ISrsProtocolReaderWriter* skt) 536 SrsRtmpServer::SrsRtmpServer(ISrsProtocolReaderWriter* skt)
445 { 537 {
446 io = skt; 538 io = skt;
@@ -106,6 +106,7 @@ enum SrsClientType @@ -106,6 +106,7 @@ enum SrsClientType
106 SrsClientFMLEPublish, 106 SrsClientFMLEPublish,
107 SrsClientFlashPublish, 107 SrsClientFlashPublish,
108 }; 108 };
  109 +std::string srs_client_type_string(SrsClientType type);
109 110
110 /** 111 /**
111 * implements the client role protocol. 112 * implements the client role protocol.
@@ -137,7 +138,12 @@ public: @@ -137,7 +138,12 @@ public:
137 virtual int connect_app(std::string app, std::string tc_url); 138 virtual int connect_app(std::string app, std::string tc_url);
138 virtual int create_stream(int& stream_id); 139 virtual int create_stream(int& stream_id);
139 virtual int play(std::string stream, int stream_id); 140 virtual int play(std::string stream, int stream_id);
  141 + // flash publish schema:
  142 + // connect-app => create-stream => flash-publish
140 virtual int publish(std::string stream, int stream_id); 143 virtual int publish(std::string stream, int stream_id);
  144 + // FMLE publish schema:
  145 + // connect-app => FMLE publish
  146 + virtual int fmle_publish(std::string stream, int& stream_id);
141 }; 147 };
142 148
143 /** 149 /**
@@ -676,7 +676,7 @@ int SrsProtocol::on_send_message(ISrsMessage* msg) @@ -676,7 +676,7 @@ int SrsProtocol::on_send_message(ISrsMessage* msg)
676 SrsConnectAppPacket* pkt = NULL; 676 SrsConnectAppPacket* pkt = NULL;
677 pkt = dynamic_cast<SrsConnectAppPacket*>(common_msg->get_packet()); 677 pkt = dynamic_cast<SrsConnectAppPacket*>(common_msg->get_packet());
678 if (pkt) { 678 if (pkt) {
679 - requests[pkt->transaction_id] = RTMP_AMF0_COMMAND_CONNECT; 679 + requests[pkt->transaction_id] = pkt->command_name;
680 break; 680 break;
681 } 681 }
682 } 682 }
@@ -684,7 +684,15 @@ int SrsProtocol::on_send_message(ISrsMessage* msg) @@ -684,7 +684,15 @@ int SrsProtocol::on_send_message(ISrsMessage* msg)
684 SrsCreateStreamPacket* pkt = NULL; 684 SrsCreateStreamPacket* pkt = NULL;
685 pkt = dynamic_cast<SrsCreateStreamPacket*>(common_msg->get_packet()); 685 pkt = dynamic_cast<SrsCreateStreamPacket*>(common_msg->get_packet());
686 if (pkt) { 686 if (pkt) {
687 - requests[pkt->transaction_id] = RTMP_AMF0_COMMAND_CREATE_STREAM; 687 + requests[pkt->transaction_id] = pkt->command_name;
  688 + break;
  689 + }
  690 + }
  691 + if (true) {
  692 + SrsFMLEStartPacket* pkt = NULL;
  693 + pkt = dynamic_cast<SrsFMLEStartPacket*>(common_msg->get_packet());
  694 + if (pkt) {
  695 + requests[pkt->transaction_id] = pkt->command_name;
688 break; 696 break;
689 } 697 }
690 } 698 }
@@ -1291,13 +1299,19 @@ int SrsCommonMessage::decode_packet(SrsProtocol* protocol) @@ -1291,13 +1299,19 @@ int SrsCommonMessage::decode_packet(SrsProtocol* protocol)
1291 srs_verbose("AMF0/AMF3 request parsed. request_name=%s", request_name.c_str()); 1299 srs_verbose("AMF0/AMF3 request parsed. request_name=%s", request_name.c_str());
1292 1300
1293 if (request_name == RTMP_AMF0_COMMAND_CONNECT) { 1301 if (request_name == RTMP_AMF0_COMMAND_CONNECT) {
1294 - srs_info("decode the AMF0/AMF3 response command(connect vhost/app message)."); 1302 + srs_info("decode the AMF0/AMF3 response command(%s message).", request_name.c_str());
1295 packet = new SrsConnectAppResPacket(); 1303 packet = new SrsConnectAppResPacket();
1296 return packet->decode(stream); 1304 return packet->decode(stream);
1297 } else if (request_name == RTMP_AMF0_COMMAND_CREATE_STREAM) { 1305 } else if (request_name == RTMP_AMF0_COMMAND_CREATE_STREAM) {
1298 - srs_info("decode the AMF0/AMF3 response command(createStream message)."); 1306 + srs_info("decode the AMF0/AMF3 response command(%s message).", request_name.c_str());
1299 packet = new SrsCreateStreamResPacket(0, 0); 1307 packet = new SrsCreateStreamResPacket(0, 0);
1300 return packet->decode(stream); 1308 return packet->decode(stream);
  1309 + } else if (request_name == RTMP_AMF0_COMMAND_RELEASE_STREAM
  1310 + || request_name == RTMP_AMF0_COMMAND_FC_PUBLISH
  1311 + || request_name == RTMP_AMF0_COMMAND_UNPUBLISH) {
  1312 + srs_info("decode the AMF0/AMF3 response command(%s message).", request_name.c_str());
  1313 + packet = new SrsFMLEStartResPacket(0);
  1314 + return packet->decode(stream);
1301 } else { 1315 } else {
1302 ret = ERROR_RTMP_NO_REQUEST; 1316 ret = ERROR_RTMP_NO_REQUEST;
1303 srs_error("decode AMF0/AMF3 request failed. " 1317 srs_error("decode AMF0/AMF3 request failed. "
@@ -2157,6 +2171,78 @@ int SrsFMLEStartPacket::decode(SrsStream* stream) @@ -2157,6 +2171,78 @@ int SrsFMLEStartPacket::decode(SrsStream* stream)
2157 return ret; 2171 return ret;
2158 } 2172 }
2159 2173
  2174 +int SrsFMLEStartPacket::get_perfer_cid()
  2175 +{
  2176 + return RTMP_CID_OverConnection;
  2177 +}
  2178 +
  2179 +int SrsFMLEStartPacket::get_message_type()
  2180 +{
  2181 + return RTMP_MSG_AMF0CommandMessage;
  2182 +}
  2183 +
  2184 +int SrsFMLEStartPacket::get_size()
  2185 +{
  2186 + return srs_amf0_get_string_size(command_name) + srs_amf0_get_number_size()
  2187 + + srs_amf0_get_null_size() + srs_amf0_get_string_size(stream_name);
  2188 +}
  2189 +
  2190 +int SrsFMLEStartPacket::encode_packet(SrsStream* stream)
  2191 +{
  2192 + int ret = ERROR_SUCCESS;
  2193 +
  2194 + if ((ret = srs_amf0_write_string(stream, command_name)) != ERROR_SUCCESS) {
  2195 + srs_error("encode command_name failed. ret=%d", ret);
  2196 + return ret;
  2197 + }
  2198 + srs_verbose("encode command_name success.");
  2199 +
  2200 + if ((ret = srs_amf0_write_number(stream, transaction_id)) != ERROR_SUCCESS) {
  2201 + srs_error("encode transaction_id failed. ret=%d", ret);
  2202 + return ret;
  2203 + }
  2204 + srs_verbose("encode transaction_id success.");
  2205 +
  2206 + if ((ret = srs_amf0_write_null(stream)) != ERROR_SUCCESS) {
  2207 + srs_error("encode command_object failed. ret=%d", ret);
  2208 + return ret;
  2209 + }
  2210 + srs_verbose("encode command_object success.");
  2211 +
  2212 + if ((ret = srs_amf0_write_string(stream, stream_name)) != ERROR_SUCCESS) {
  2213 + srs_error("encode stream_name failed. ret=%d", ret);
  2214 + return ret;
  2215 + }
  2216 + srs_verbose("encode stream_name success.");
  2217 +
  2218 +
  2219 + srs_info("encode FMLE start response packet success.");
  2220 +
  2221 + return ret;
  2222 +}
  2223 +
  2224 +SrsFMLEStartPacket* SrsFMLEStartPacket::create_release_stream(string stream)
  2225 +{
  2226 + SrsFMLEStartPacket* pkt = new SrsFMLEStartPacket();
  2227 +
  2228 + pkt->command_name = RTMP_AMF0_COMMAND_RELEASE_STREAM;
  2229 + pkt->transaction_id = 2;
  2230 + pkt->stream_name = stream;
  2231 +
  2232 + return pkt;
  2233 +}
  2234 +
  2235 +SrsFMLEStartPacket* SrsFMLEStartPacket::create_FC_publish(string stream)
  2236 +{
  2237 + SrsFMLEStartPacket* pkt = new SrsFMLEStartPacket();
  2238 +
  2239 + pkt->command_name = RTMP_AMF0_COMMAND_FC_PUBLISH;
  2240 + pkt->transaction_id = 3;
  2241 + pkt->stream_name = stream;
  2242 +
  2243 + return pkt;
  2244 +}
  2245 +
2160 SrsFMLEStartResPacket::SrsFMLEStartResPacket(double _transaction_id) 2246 SrsFMLEStartResPacket::SrsFMLEStartResPacket(double _transaction_id)
2161 { 2247 {
2162 command_name = RTMP_AMF0_COMMAND_RESULT; 2248 command_name = RTMP_AMF0_COMMAND_RESULT;
@@ -2171,6 +2257,41 @@ SrsFMLEStartResPacket::~SrsFMLEStartResPacket() @@ -2171,6 +2257,41 @@ SrsFMLEStartResPacket::~SrsFMLEStartResPacket()
2171 srs_freep(args); 2257 srs_freep(args);
2172 } 2258 }
2173 2259
  2260 +int SrsFMLEStartResPacket::decode(SrsStream* stream)
  2261 +{
  2262 + int ret = ERROR_SUCCESS;
  2263 +
  2264 + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) {
  2265 + srs_error("amf0 decode FMLE start response command_name failed. ret=%d", ret);
  2266 + return ret;
  2267 + }
  2268 + if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_RESULT) {
  2269 + ret = ERROR_RTMP_AMF0_DECODE;
  2270 + srs_error("amf0 decode FMLE start response command_name failed. "
  2271 + "command_name=%s, ret=%d", command_name.c_str(), ret);
  2272 + return ret;
  2273 + }
  2274 +
  2275 + if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) {
  2276 + srs_error("amf0 decode FMLE start response transaction_id failed. ret=%d", ret);
  2277 + return ret;
  2278 + }
  2279 +
  2280 + if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) {
  2281 + srs_error("amf0 decode FMLE start response command_object failed. ret=%d", ret);
  2282 + return ret;
  2283 + }
  2284 +
  2285 + if ((ret = srs_amf0_read_undefined(stream)) != ERROR_SUCCESS) {
  2286 + srs_error("amf0 decode FMLE start response stream_id failed. ret=%d", ret);
  2287 + return ret;
  2288 + }
  2289 +
  2290 + srs_info("amf0 decode FMLE start packet success");
  2291 +
  2292 + return ret;
  2293 +}
  2294 +
2174 int SrsFMLEStartResPacket::get_perfer_cid() 2295 int SrsFMLEStartResPacket::get_perfer_cid()
2175 { 2296 {
2176 return RTMP_CID_OverConnection; 2297 return RTMP_CID_OverConnection;
@@ -681,6 +681,16 @@ public: @@ -681,6 +681,16 @@ public:
681 virtual ~SrsFMLEStartPacket(); 681 virtual ~SrsFMLEStartPacket();
682 public: 682 public:
683 virtual int decode(SrsStream* stream); 683 virtual int decode(SrsStream* stream);
  684 +public:
  685 + virtual int get_perfer_cid();
  686 +public:
  687 + virtual int get_message_type();
  688 +protected:
  689 + virtual int get_size();
  690 + virtual int encode_packet(SrsStream* stream);
  691 +public:
  692 + static SrsFMLEStartPacket* create_release_stream(std::string stream);
  693 + static SrsFMLEStartPacket* create_FC_publish(std::string stream);
684 }; 694 };
685 /** 695 /**
686 * response for SrsFMLEStartPacket. 696 * response for SrsFMLEStartPacket.
@@ -703,6 +713,8 @@ public: @@ -703,6 +713,8 @@ public:
703 SrsFMLEStartResPacket(double _transaction_id); 713 SrsFMLEStartResPacket(double _transaction_id);
704 virtual ~SrsFMLEStartResPacket(); 714 virtual ~SrsFMLEStartResPacket();
705 public: 715 public:
  716 + virtual int decode(SrsStream* stream);
  717 +public:
706 virtual int get_perfer_cid(); 718 virtual int get_perfer_cid();
707 public: 719 public:
708 virtual int get_message_type(); 720 virtual int get_message_type();