正在显示
5 个修改的文件
包含
233 行增加
和
79 行删除
@@ -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,9 +98,8 @@ int SrsClient::do_cycle() | @@ -97,9 +98,8 @@ 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 | } |
@@ -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 |
-
请 注册 或 登录 后发表评论