正在显示
7 个修改的文件
包含
242 行增加
和
6 行删除
| @@ -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(); |
-
请 注册 或 登录 后发表评论