正在显示
5 个修改的文件
包含
234 行增加
和
80 行删除
| @@ -28,15 +28,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -28,15 +28,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 28 | #include <srs_core_error.hpp> | 28 | #include <srs_core_error.hpp> |
| 29 | #include <srs_core_log.hpp> | 29 | #include <srs_core_log.hpp> |
| 30 | #include <srs_core_rtmp.hpp> | 30 | #include <srs_core_rtmp.hpp> |
| 31 | - | ||
| 32 | -// default stream id for response the createStream request. | ||
| 33 | -#define SRS_DEFAULT_SID 1 | 31 | +#include <srs_core_protocol.hpp> |
| 32 | +#include <srs_core_auto_free.hpp> | ||
| 34 | 33 | ||
| 35 | SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) | 34 | SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) |
| 36 | : SrsConnection(srs_server, client_stfd) | 35 | : SrsConnection(srs_server, client_stfd) |
| 37 | { | 36 | { |
| 38 | ip = NULL; | 37 | ip = NULL; |
| 39 | req = new SrsRequest(); | 38 | req = new SrsRequest(); |
| 39 | + res = new SrsResponse(); | ||
| 40 | rtmp = new SrsRtmp(client_stfd); | 40 | rtmp = new SrsRtmp(client_stfd); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| @@ -44,6 +44,7 @@ SrsClient::~SrsClient() | @@ -44,6 +44,7 @@ SrsClient::~SrsClient() | ||
| 44 | { | 44 | { |
| 45 | srs_freepa(ip); | 45 | srs_freepa(ip); |
| 46 | srs_freep(req); | 46 | srs_freep(req); |
| 47 | + srs_freep(res); | ||
| 47 | srs_freep(rtmp); | 48 | srs_freep(rtmp); |
| 48 | } | 49 | } |
| 49 | 50 | ||
| @@ -97,14 +98,13 @@ int SrsClient::do_cycle() | @@ -97,14 +98,13 @@ int SrsClient::do_cycle() | ||
| 97 | } | 98 | } |
| 98 | srs_verbose("on_bw_done success"); | 99 | srs_verbose("on_bw_done success"); |
| 99 | 100 | ||
| 100 | - int stream_id = SRS_DEFAULT_SID; | ||
| 101 | SrsClientType type; | 101 | SrsClientType type; |
| 102 | - if ((ret = rtmp->identify_client(stream_id, type, req->stream)) != ERROR_SUCCESS) { | 102 | + if ((ret = rtmp->identify_client(res->stream_id, type, req->stream)) != ERROR_SUCCESS) { |
| 103 | srs_error("identify client failed. ret=%d", ret); | 103 | srs_error("identify client failed. ret=%d", ret); |
| 104 | return ret; | 104 | return ret; |
| 105 | } | 105 | } |
| 106 | srs_verbose("identify client success. type=%d, stream_name=%s", type, req->stream.c_str()); | 106 | srs_verbose("identify client success. type=%d, stream_name=%s", type, req->stream.c_str()); |
| 107 | - | 107 | + |
| 108 | // TODO: read from config. | 108 | // TODO: read from config. |
| 109 | int chunk_size = 4096; | 109 | int chunk_size = 4096; |
| 110 | if ((ret = rtmp->set_chunk_size(chunk_size)) != ERROR_SUCCESS) { | 110 | if ((ret = rtmp->set_chunk_size(chunk_size)) != ERROR_SUCCESS) { |
| @@ -117,13 +117,23 @@ int SrsClient::do_cycle() | @@ -117,13 +117,23 @@ int SrsClient::do_cycle() | ||
| 117 | case SrsClientPlay: { | 117 | case SrsClientPlay: { |
| 118 | srs_verbose("start to play stream %s.", req->stream.c_str()); | 118 | srs_verbose("start to play stream %s.", req->stream.c_str()); |
| 119 | 119 | ||
| 120 | - if ((ret = rtmp->start_play(stream_id)) != ERROR_SUCCESS) { | 120 | + if ((ret = rtmp->start_play(res->stream_id)) != ERROR_SUCCESS) { |
| 121 | srs_error("start to play stream failed. ret=%d", ret); | 121 | srs_error("start to play stream failed. ret=%d", ret); |
| 122 | return ret; | 122 | return ret; |
| 123 | } | 123 | } |
| 124 | srs_info("start to play stream %s success", req->stream.c_str()); | 124 | srs_info("start to play stream %s success", req->stream.c_str()); |
| 125 | return streaming_play(); | 125 | return streaming_play(); |
| 126 | } | 126 | } |
| 127 | + case SrsClientPublish: { | ||
| 128 | + srs_verbose("start to publish stream %s.", req->stream.c_str()); | ||
| 129 | + | ||
| 130 | + if ((ret = rtmp->start_publish(res->stream_id)) != ERROR_SUCCESS) { | ||
| 131 | + srs_error("start to publish stream failed. ret=%d", ret); | ||
| 132 | + return ret; | ||
| 133 | + } | ||
| 134 | + srs_info("start to publish stream %s success", req->stream.c_str()); | ||
| 135 | + return streaming_publish(); | ||
| 136 | + } | ||
| 127 | default: { | 137 | default: { |
| 128 | ret = ERROR_SYSTEM_CLIENT_INVALID; | 138 | ret = ERROR_SYSTEM_CLIENT_INVALID; |
| 129 | srs_info("invalid client type=%d. ret=%d", type, ret); | 139 | srs_info("invalid client type=%d. ret=%d", type, ret); |
| @@ -140,6 +150,39 @@ int SrsClient::streaming_play() | @@ -140,6 +150,39 @@ int SrsClient::streaming_play() | ||
| 140 | return ret; | 150 | return ret; |
| 141 | } | 151 | } |
| 142 | 152 | ||
| 153 | +int SrsClient::streaming_publish() | ||
| 154 | +{ | ||
| 155 | + int ret = ERROR_SUCCESS; | ||
| 156 | + | ||
| 157 | + while (true) { | ||
| 158 | + SrsMessage* msg = NULL; | ||
| 159 | + if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) { | ||
| 160 | + srs_error("recv identify client message failed. ret=%d", ret); | ||
| 161 | + return ret; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + SrsAutoFree(SrsMessage, msg, false); | ||
| 165 | + | ||
| 166 | + // process UnPublish event. | ||
| 167 | + if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) { | ||
| 168 | + if ((ret = msg->decode_packet()) != ERROR_SUCCESS) { | ||
| 169 | + srs_error("decode unpublish message failed. ret=%d", ret); | ||
| 170 | + return ret; | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + SrsPacket* pkt = msg->get_packet(); | ||
| 174 | + if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { | ||
| 175 | + SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt); | ||
| 176 | + return rtmp->fmle_unpublish(res->stream_id, unpublish->transaction_id); | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + srs_trace("ignore AMF0/AMF3 command message."); | ||
| 180 | + } | ||
| 181 | + } | ||
| 182 | + | ||
| 183 | + return ret; | ||
| 184 | +} | ||
| 185 | + | ||
| 143 | int SrsClient::get_peer_ip() | 186 | int SrsClient::get_peer_ip() |
| 144 | { | 187 | { |
| 145 | int ret = ERROR_SUCCESS; | 188 | int ret = ERROR_SUCCESS; |
| @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 34 | 34 | ||
| 35 | class SrsRtmp; | 35 | class SrsRtmp; |
| 36 | class SrsRequest; | 36 | class SrsRequest; |
| 37 | +class SrsResponse; | ||
| 37 | 38 | ||
| 38 | /** | 39 | /** |
| 39 | * the client provides the main logic control for RTMP clients. | 40 | * the client provides the main logic control for RTMP clients. |
| @@ -43,6 +44,7 @@ class SrsClient : public SrsConnection | @@ -43,6 +44,7 @@ class SrsClient : public SrsConnection | ||
| 43 | private: | 44 | private: |
| 44 | char* ip; | 45 | char* ip; |
| 45 | SrsRequest* req; | 46 | SrsRequest* req; |
| 47 | + SrsResponse* res; | ||
| 46 | SrsRtmp* rtmp; | 48 | SrsRtmp* rtmp; |
| 47 | public: | 49 | public: |
| 48 | SrsClient(SrsServer* srs_server, st_netfd_t client_stfd); | 50 | SrsClient(SrsServer* srs_server, st_netfd_t client_stfd); |
| @@ -51,6 +53,7 @@ protected: | @@ -51,6 +53,7 @@ protected: | ||
| 51 | virtual int do_cycle(); | 53 | virtual int do_cycle(); |
| 52 | private: | 54 | private: |
| 53 | virtual int streaming_play(); | 55 | virtual int streaming_play(); |
| 56 | + virtual int streaming_publish(); | ||
| 54 | virtual int get_peer_ip(); | 57 | virtual int get_peer_ip(); |
| 55 | }; | 58 | }; |
| 56 | 59 |
| @@ -199,6 +199,7 @@ messages. | @@ -199,6 +199,7 @@ messages. | ||
| 199 | #define RTMP_AMF0_COMMAND_RESULT "_result" | 199 | #define RTMP_AMF0_COMMAND_RESULT "_result" |
| 200 | #define RTMP_AMF0_COMMAND_RELEASE_STREAM "releaseStream" | 200 | #define RTMP_AMF0_COMMAND_RELEASE_STREAM "releaseStream" |
| 201 | #define RTMP_AMF0_COMMAND_FC_PUBLISH "FCPublish" | 201 | #define RTMP_AMF0_COMMAND_FC_PUBLISH "FCPublish" |
| 202 | +#define RTMP_AMF0_COMMAND_UNPUBLISH "FCUnpublish" | ||
| 202 | #define RTMP_AMF0_COMMAND_PUBLISH "publish" | 203 | #define RTMP_AMF0_COMMAND_PUBLISH "publish" |
| 203 | #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess" | 204 | #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess" |
| 204 | 205 | ||
| @@ -979,6 +980,10 @@ int SrsMessage::decode_packet() | @@ -979,6 +980,10 @@ int SrsMessage::decode_packet() | ||
| 979 | srs_info("decode the AMF0/AMF3 command(publish message)."); | 980 | srs_info("decode the AMF0/AMF3 command(publish message)."); |
| 980 | packet = new SrsPublishPacket(); | 981 | packet = new SrsPublishPacket(); |
| 981 | return packet->decode(stream); | 982 | return packet->decode(stream); |
| 983 | + } else if(command == RTMP_AMF0_COMMAND_UNPUBLISH) { | ||
| 984 | + srs_info("decode the AMF0/AMF3 command(unpublish message)."); | ||
| 985 | + packet = new SrsFMLEStartPacket(); | ||
| 986 | + return packet->decode(stream); | ||
| 982 | } | 987 | } |
| 983 | 988 | ||
| 984 | // default packet to drop message. | 989 | // default packet to drop message. |
| @@ -1383,7 +1388,8 @@ int SrsFMLEStartPacket::decode(SrsStream* stream) | @@ -1383,7 +1388,8 @@ int SrsFMLEStartPacket::decode(SrsStream* stream) | ||
| 1383 | } | 1388 | } |
| 1384 | if (command_name.empty() | 1389 | if (command_name.empty() |
| 1385 | || (command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM | 1390 | || (command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM |
| 1386 | - && command_name != RTMP_AMF0_COMMAND_FC_PUBLISH) | 1391 | + && command_name != RTMP_AMF0_COMMAND_FC_PUBLISH |
| 1392 | + && command_name != RTMP_AMF0_COMMAND_UNPUBLISH) | ||
| 1387 | ) { | 1393 | ) { |
| 1388 | ret = ERROR_RTMP_AMF0_DECODE; | 1394 | ret = ERROR_RTMP_AMF0_DECODE; |
| 1389 | srs_error("amf0 decode FMLE start command_name failed. " | 1395 | srs_error("amf0 decode FMLE start command_name failed. " |
| @@ -53,9 +53,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -53,9 +53,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 53 | #define StatusCodeStreamStart "NetStream.Play.Start" | 53 | #define StatusCodeStreamStart "NetStream.Play.Start" |
| 54 | #define StatusCodePublishStart "NetStream.Publish.Start" | 54 | #define StatusCodePublishStart "NetStream.Publish.Start" |
| 55 | #define StatusCodeDataStart "NetStream.Data.Start" | 55 | #define StatusCodeDataStart "NetStream.Data.Start" |
| 56 | +#define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success" | ||
| 56 | 57 | ||
| 57 | // FMLE | 58 | // FMLE |
| 58 | #define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish" | 59 | #define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish" |
| 60 | +#define RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH "onFCUnpublish" | ||
| 61 | + | ||
| 62 | +// default stream id for response the createStream request. | ||
| 63 | +#define SRS_DEFAULT_SID 1 | ||
| 59 | 64 | ||
| 60 | SrsRequest::SrsRequest() | 65 | SrsRequest::SrsRequest() |
| 61 | { | 66 | { |
| @@ -107,6 +112,15 @@ int SrsRequest::discovery_app() | @@ -107,6 +112,15 @@ int SrsRequest::discovery_app() | ||
| 107 | return ret; | 112 | return ret; |
| 108 | } | 113 | } |
| 109 | 114 | ||
| 115 | +SrsResponse::SrsResponse() | ||
| 116 | +{ | ||
| 117 | + stream_id = SRS_DEFAULT_SID; | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +SrsResponse::~SrsResponse() | ||
| 121 | +{ | ||
| 122 | +} | ||
| 123 | + | ||
| 110 | SrsRtmp::SrsRtmp(st_netfd_t client_stfd) | 124 | SrsRtmp::SrsRtmp(st_netfd_t client_stfd) |
| 111 | { | 125 | { |
| 112 | protocol = new SrsProtocol(client_stfd); | 126 | protocol = new SrsProtocol(client_stfd); |
| @@ -164,6 +178,11 @@ int SrsRtmp::handshake() | @@ -164,6 +178,11 @@ int SrsRtmp::handshake() | ||
| 164 | return ret; | 178 | return ret; |
| 165 | } | 179 | } |
| 166 | 180 | ||
| 181 | +int SrsRtmp::recv_message(SrsMessage** pmsg) | ||
| 182 | +{ | ||
| 183 | + return protocol->recv_message(pmsg); | ||
| 184 | +} | ||
| 185 | + | ||
| 167 | int SrsRtmp::connect_app(SrsRequest* req) | 186 | int SrsRtmp::connect_app(SrsRequest* req) |
| 168 | { | 187 | { |
| 169 | int ret = ERROR_SUCCESS; | 188 | int ret = ERROR_SUCCESS; |
| @@ -329,7 +348,7 @@ int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& st | @@ -329,7 +348,7 @@ int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& st | ||
| 329 | if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { | 348 | if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { |
| 330 | srs_info("identify client by releaseStream, fmle publish."); | 349 | srs_info("identify client by releaseStream, fmle publish."); |
| 331 | return identify_fmle_publish_client( | 350 | return identify_fmle_publish_client( |
| 332 | - dynamic_cast<SrsFMLEStartPacket*>(pkt), stream_id, type, stream_name); | 351 | + dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name); |
| 333 | } | 352 | } |
| 334 | 353 | ||
| 335 | srs_trace("ignore AMF0/AMF3 command message."); | 354 | srs_trace("ignore AMF0/AMF3 command message."); |
| @@ -452,79 +471,10 @@ int SrsRtmp::start_play(int stream_id) | @@ -452,79 +471,10 @@ int SrsRtmp::start_play(int stream_id) | ||
| 452 | return ret; | 471 | return ret; |
| 453 | } | 472 | } |
| 454 | 473 | ||
| 455 | -int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name) | ||
| 456 | -{ | ||
| 457 | - int ret = ERROR_SUCCESS; | ||
| 458 | - | ||
| 459 | - if (true) { | ||
| 460 | - SrsMessage* msg = new SrsMessage(); | ||
| 461 | - SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id); | ||
| 462 | - | ||
| 463 | - msg->set_packet(pkt, 0); | ||
| 464 | - | ||
| 465 | - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 466 | - srs_error("send createStream response message failed. ret=%d", ret); | ||
| 467 | - return ret; | ||
| 468 | - } | ||
| 469 | - srs_info("send createStream response message success."); | ||
| 470 | - } | ||
| 471 | - | ||
| 472 | - while (true) { | ||
| 473 | - SrsMessage* msg = NULL; | ||
| 474 | - if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) { | ||
| 475 | - srs_error("recv identify client message failed. ret=%d", ret); | ||
| 476 | - return ret; | ||
| 477 | - } | ||
| 478 | - | ||
| 479 | - SrsAutoFree(SrsMessage, msg, false); | ||
| 480 | - | ||
| 481 | - if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) { | ||
| 482 | - srs_trace("identify ignore messages except " | ||
| 483 | - "AMF0/AMF3 command message. type=%#x", msg->header.message_type); | ||
| 484 | - continue; | ||
| 485 | - } | ||
| 486 | - | ||
| 487 | - if ((ret = msg->decode_packet()) != ERROR_SUCCESS) { | ||
| 488 | - srs_error("identify decode message failed. ret=%d", ret); | ||
| 489 | - return ret; | ||
| 490 | - } | ||
| 491 | - | ||
| 492 | - SrsPacket* pkt = msg->get_packet(); | ||
| 493 | - if (dynamic_cast<SrsPlayPacket*>(pkt)) { | ||
| 494 | - SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt); | ||
| 495 | - type = SrsClientPlay; | ||
| 496 | - stream_name = play->stream_name; | ||
| 497 | - srs_trace("identity client type=play, stream_name=%s", stream_name.c_str()); | ||
| 498 | - return ret; | ||
| 499 | - } | ||
| 500 | - | ||
| 501 | - srs_trace("ignore AMF0/AMF3 command message."); | ||
| 502 | - } | ||
| 503 | - | ||
| 504 | - return ret; | ||
| 505 | -} | ||
| 506 | - | ||
| 507 | -int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id, SrsClientType& type, std::string& stream_name) | 474 | +int SrsRtmp::start_publish(int stream_id) |
| 508 | { | 475 | { |
| 509 | int ret = ERROR_SUCCESS; | 476 | int ret = ERROR_SUCCESS; |
| 510 | 477 | ||
| 511 | - type = SrsClientPublish; | ||
| 512 | - stream_name = req->stream_name; | ||
| 513 | - | ||
| 514 | - // createStream response | ||
| 515 | - if (true) { | ||
| 516 | - SrsMessage* msg = new SrsMessage(); | ||
| 517 | - SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id); | ||
| 518 | - | ||
| 519 | - msg->set_packet(pkt, 0); | ||
| 520 | - | ||
| 521 | - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 522 | - srs_error("send releaseStream response message failed. ret=%d", ret); | ||
| 523 | - return ret; | ||
| 524 | - } | ||
| 525 | - srs_info("send releaseStream response message success."); | ||
| 526 | - } | ||
| 527 | - | ||
| 528 | // FCPublish | 478 | // FCPublish |
| 529 | double fc_publish_tid = 0; | 479 | double fc_publish_tid = 0; |
| 530 | if (true) { | 480 | if (true) { |
| @@ -629,6 +579,84 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | @@ -629,6 +579,84 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | ||
| 629 | srs_info("send onStatus(NetStream.Publish.Start) message success."); | 579 | srs_info("send onStatus(NetStream.Publish.Start) message success."); |
| 630 | } | 580 | } |
| 631 | 581 | ||
| 582 | + return ret; | ||
| 583 | +} | ||
| 584 | + | ||
| 585 | +int SrsRtmp::fmle_unpublish(int stream_id, double unpublish_tid) | ||
| 586 | +{ | ||
| 587 | + int ret = ERROR_SUCCESS; | ||
| 588 | + | ||
| 589 | + // publish response onFCUnpublish(NetStream.unpublish.Success) | ||
| 590 | + if (true) { | ||
| 591 | + SrsMessage* msg = new SrsMessage(); | ||
| 592 | + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); | ||
| 593 | + | ||
| 594 | + pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH; | ||
| 595 | + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess)); | ||
| 596 | + pkt->data->set(StatusDescription, new SrsAmf0String("Stop publishing stream.")); | ||
| 597 | + | ||
| 598 | + msg->set_packet(pkt, stream_id); | ||
| 599 | + | ||
| 600 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 601 | + srs_error("send onFCUnpublish(NetStream.unpublish.Success) message failed. ret=%d", ret); | ||
| 602 | + return ret; | ||
| 603 | + } | ||
| 604 | + srs_info("send onFCUnpublish(NetStream.unpublish.Success) message success."); | ||
| 605 | + } | ||
| 606 | + // FCUnpublish response | ||
| 607 | + if (true) { | ||
| 608 | + SrsMessage* msg = new SrsMessage(); | ||
| 609 | + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(unpublish_tid); | ||
| 610 | + | ||
| 611 | + msg->set_packet(pkt, stream_id); | ||
| 612 | + | ||
| 613 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 614 | + srs_error("send FCUnpublish response message failed. ret=%d", ret); | ||
| 615 | + return ret; | ||
| 616 | + } | ||
| 617 | + srs_info("send FCUnpublish response message success."); | ||
| 618 | + } | ||
| 619 | + // publish response onStatus(NetStream.Unpublish.Success) | ||
| 620 | + if (true) { | ||
| 621 | + SrsMessage* msg = new SrsMessage(); | ||
| 622 | + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); | ||
| 623 | + | ||
| 624 | + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus)); | ||
| 625 | + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess)); | ||
| 626 | + pkt->data->set(StatusDescription, new SrsAmf0String("Stream is now unpublished")); | ||
| 627 | + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID)); | ||
| 628 | + | ||
| 629 | + msg->set_packet(pkt, stream_id); | ||
| 630 | + | ||
| 631 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 632 | + srs_error("send onStatus(NetStream.Unpublish.Success) message failed. ret=%d", ret); | ||
| 633 | + return ret; | ||
| 634 | + } | ||
| 635 | + srs_info("send onStatus(NetStream.Unpublish.Success) message success."); | ||
| 636 | + } | ||
| 637 | + | ||
| 638 | + srs_info("FMLE unpublish success."); | ||
| 639 | + | ||
| 640 | + return ret; | ||
| 641 | +} | ||
| 642 | + | ||
| 643 | +int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name) | ||
| 644 | +{ | ||
| 645 | + int ret = ERROR_SUCCESS; | ||
| 646 | + | ||
| 647 | + if (true) { | ||
| 648 | + SrsMessage* msg = new SrsMessage(); | ||
| 649 | + SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id); | ||
| 650 | + | ||
| 651 | + msg->set_packet(pkt, 0); | ||
| 652 | + | ||
| 653 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 654 | + srs_error("send createStream response message failed. ret=%d", ret); | ||
| 655 | + return ret; | ||
| 656 | + } | ||
| 657 | + srs_info("send createStream response message success."); | ||
| 658 | + } | ||
| 659 | + | ||
| 632 | while (true) { | 660 | while (true) { |
| 633 | SrsMessage* msg = NULL; | 661 | SrsMessage* msg = NULL; |
| 634 | if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) { | 662 | if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) { |
| @@ -637,6 +665,52 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | @@ -637,6 +665,52 @@ int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id | ||
| 637 | } | 665 | } |
| 638 | 666 | ||
| 639 | SrsAutoFree(SrsMessage, msg, false); | 667 | SrsAutoFree(SrsMessage, msg, false); |
| 668 | + | ||
| 669 | + if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) { | ||
| 670 | + srs_trace("identify ignore messages except " | ||
| 671 | + "AMF0/AMF3 command message. type=%#x", msg->header.message_type); | ||
| 672 | + continue; | ||
| 673 | + } | ||
| 674 | + | ||
| 675 | + if ((ret = msg->decode_packet()) != ERROR_SUCCESS) { | ||
| 676 | + srs_error("identify decode message failed. ret=%d", ret); | ||
| 677 | + return ret; | ||
| 678 | + } | ||
| 679 | + | ||
| 680 | + SrsPacket* pkt = msg->get_packet(); | ||
| 681 | + if (dynamic_cast<SrsPlayPacket*>(pkt)) { | ||
| 682 | + SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt); | ||
| 683 | + type = SrsClientPlay; | ||
| 684 | + stream_name = play->stream_name; | ||
| 685 | + srs_trace("identity client type=play, stream_name=%s", stream_name.c_str()); | ||
| 686 | + return ret; | ||
| 687 | + } | ||
| 688 | + | ||
| 689 | + srs_trace("ignore AMF0/AMF3 command message."); | ||
| 690 | + } | ||
| 691 | + | ||
| 692 | + return ret; | ||
| 693 | +} | ||
| 694 | + | ||
| 695 | +int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name) | ||
| 696 | +{ | ||
| 697 | + int ret = ERROR_SUCCESS; | ||
| 698 | + | ||
| 699 | + type = SrsClientPublish; | ||
| 700 | + stream_name = req->stream_name; | ||
| 701 | + | ||
| 702 | + // releaseStream response | ||
| 703 | + if (true) { | ||
| 704 | + SrsMessage* msg = new SrsMessage(); | ||
| 705 | + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id); | ||
| 706 | + | ||
| 707 | + msg->set_packet(pkt, 0); | ||
| 708 | + | ||
| 709 | + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { | ||
| 710 | + srs_error("send releaseStream response message failed. ret=%d", ret); | ||
| 711 | + return ret; | ||
| 712 | + } | ||
| 713 | + srs_info("send releaseStream response message success."); | ||
| 640 | } | 714 | } |
| 641 | 715 | ||
| 642 | return ret; | 716 | return ret; |
| @@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 35 | #include <st.h> | 35 | #include <st.h> |
| 36 | 36 | ||
| 37 | class SrsProtocol; | 37 | class SrsProtocol; |
| 38 | +class SrsMessage; | ||
| 38 | class SrsCreateStreamPacket; | 39 | class SrsCreateStreamPacket; |
| 39 | class SrsFMLEStartPacket; | 40 | class SrsFMLEStartPacket; |
| 40 | 41 | ||
| @@ -64,6 +65,17 @@ struct SrsRequest | @@ -64,6 +65,17 @@ struct SrsRequest | ||
| 64 | }; | 65 | }; |
| 65 | 66 | ||
| 66 | /** | 67 | /** |
| 68 | +* the response to client. | ||
| 69 | +*/ | ||
| 70 | +struct SrsResponse | ||
| 71 | +{ | ||
| 72 | + int stream_id; | ||
| 73 | + | ||
| 74 | + SrsResponse(); | ||
| 75 | + virtual ~SrsResponse(); | ||
| 76 | +}; | ||
| 77 | + | ||
| 78 | +/** | ||
| 67 | * the rtmp client type. | 79 | * the rtmp client type. |
| 68 | */ | 80 | */ |
| 69 | enum SrsClientType | 81 | enum SrsClientType |
| @@ -88,6 +100,7 @@ public: | @@ -88,6 +100,7 @@ public: | ||
| 88 | virtual ~SrsRtmp(); | 100 | virtual ~SrsRtmp(); |
| 89 | public: | 101 | public: |
| 90 | virtual int handshake(); | 102 | virtual int handshake(); |
| 103 | + virtual int recv_message(SrsMessage** pmsg); | ||
| 91 | virtual int connect_app(SrsRequest* req); | 104 | virtual int connect_app(SrsRequest* req); |
| 92 | virtual int set_window_ack_size(int ack_size); | 105 | virtual int set_window_ack_size(int ack_size); |
| 93 | /** | 106 | /** |
| @@ -116,9 +129,24 @@ public: | @@ -116,9 +129,24 @@ public: | ||
| 116 | * onStatus(NetStream.Data.Start). | 129 | * onStatus(NetStream.Data.Start). |
| 117 | */ | 130 | */ |
| 118 | virtual int start_play(int stream_id); | 131 | virtual int start_play(int stream_id); |
| 132 | + /** | ||
| 133 | + * when client type is publish, response with packets: | ||
| 134 | + * releaseStream response | ||
| 135 | + * FCPublish | ||
| 136 | + * FCPublish response | ||
| 137 | + * createStream response | ||
| 138 | + * onFCPublish(NetStream.Publish.Start) | ||
| 139 | + * onStatus(NetStream.Publish.Start) | ||
| 140 | + */ | ||
| 141 | + virtual int start_publish(int stream_id); | ||
| 142 | + /** | ||
| 143 | + * process the FMLE unpublish event. | ||
| 144 | + * @unpublish_tid the unpublish request transaction id. | ||
| 145 | + */ | ||
| 146 | + virtual int fmle_unpublish(int stream_id, double unpublish_tid); | ||
| 119 | private: | 147 | private: |
| 120 | virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name); | 148 | virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name); |
| 121 | - virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, int stream_id, SrsClientType& type, std::string& stream_name); | 149 | + virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name); |
| 122 | }; | 150 | }; |
| 123 | 151 | ||
| 124 | #endif | 152 | #endif |
-
请 注册 或 登录 后发表评论