winlin

update the signature, when connect to server, parse the response.

@@ -90,7 +90,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; } @@ -90,7 +90,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; }
90 function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } 90 function srs_get_player_height() { return srs_get_player_width() * 9 / 19; }
91 91
92 // to query the swf anti cache. 92 // to query the swf anti cache.
93 -function srs_get_version_code() { return "1.0"; } 93 +function srs_get_version_code() { return "1.1"; }
94 94
95 /** 95 /**
96 * initialize the page. 96 * initialize the page.
@@ -293,6 +293,18 @@ package @@ -293,6 +293,18 @@ package
293 this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { 293 this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
294 trace ("NetConnection: code=" + evt.info.code); 294 trace ("NetConnection: code=" + evt.info.code);
295 295
  296 + if (evt.info.hasOwnProperty("data") && evt.info.data) {
  297 + // for context menu
  298 + var customItems:Array = [new ContextMenuItem("SrsPlayer")];
  299 + if (evt.info.data.hasOwnProperty("srs_server")) {
  300 + customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server));
  301 + }
  302 + if (evt.info.data.hasOwnProperty("srs_contributor")) {
  303 + customItems.push(new ContextMenuItem("Contributor: " + evt.info.data.srs_contributor));
  304 + }
  305 + contextMenu.customItems = customItems;
  306 + }
  307 +
296 // TODO: FIXME: failed event. 308 // TODO: FIXME: failed event.
297 if (evt.info.code != "NetConnection.Connect.Success") { 309 if (evt.info.code != "NetConnection.Connect.Success") {
298 return; 310 return;
@@ -14,6 +14,7 @@ package @@ -14,6 +14,7 @@ package
14 import flash.net.NetConnection; 14 import flash.net.NetConnection;
15 import flash.net.NetStream; 15 import flash.net.NetStream;
16 import flash.ui.ContextMenu; 16 import flash.ui.ContextMenu;
  17 + import flash.ui.ContextMenuItem;
17 import flash.utils.setTimeout; 18 import flash.utils.setTimeout;
18 19
19 public class srs_publisher extends Sprite 20 public class srs_publisher extends Sprite
@@ -159,6 +160,18 @@ package @@ -159,6 +160,18 @@ package
159 this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { 160 this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
160 trace ("NetConnection: code=" + evt.info.code); 161 trace ("NetConnection: code=" + evt.info.code);
161 162
  163 + if (evt.info.hasOwnProperty("data") && evt.info.data) {
  164 + // for context menu
  165 + var customItems:Array = [new ContextMenuItem("SrsPlayer")];
  166 + if (evt.info.data.hasOwnProperty("srs_server")) {
  167 + customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server));
  168 + }
  169 + if (evt.info.data.hasOwnProperty("srs_contributor")) {
  170 + customItems.push(new ContextMenuItem("Contributor: " + evt.info.data.srs_contributor));
  171 + }
  172 + contextMenu.customItems = customItems;
  173 + }
  174 +
162 // TODO: FIXME: failed event. 175 // TODO: FIXME: failed event.
163 if (evt.info.code != "NetConnection.Connect.Success") { 176 if (evt.info.code != "NetConnection.Connect.Success") {
164 return; 177 return;
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 winlin  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <srs_core_rtmp.hpp>  
25 -  
26 -#include <srs_core_log.hpp>  
27 -#include <srs_core_error.hpp>  
28 -#include <srs_core_socket.hpp>  
29 -#include <srs_core_protocol.hpp>  
30 -#include <srs_core_autofree.hpp>  
31 -#include <srs_core_amf0.hpp>  
32 -#include <srs_core_handshake.hpp>  
33 -#include <srs_core_config.hpp>  
34 -  
35 -using namespace std;  
36 -  
37 -/**  
38 -* the signature for packets to client.  
39 -*/  
40 -#define RTMP_SIG_FMS_VER "3,5,3,888"  
41 -#define RTMP_SIG_AMF0_VER 0  
42 -#define RTMP_SIG_CLIENT_ID "ASAICiss"  
43 -  
44 -/**  
45 -* onStatus consts.  
46 -*/  
47 -#define StatusLevel "level"  
48 -#define StatusCode "code"  
49 -#define StatusDescription "description"  
50 -#define StatusDetails "details"  
51 -#define StatusClientId "clientid"  
52 -// status value  
53 -#define StatusLevelStatus "status"  
54 -// code value  
55 -#define StatusCodeConnectSuccess "NetConnection.Connect.Success"  
56 -#define StatusCodeStreamReset "NetStream.Play.Reset"  
57 -#define StatusCodeStreamStart "NetStream.Play.Start"  
58 -#define StatusCodeStreamPause "NetStream.Pause.Notify"  
59 -#define StatusCodeStreamUnpause "NetStream.Unpause.Notify"  
60 -#define StatusCodePublishStart "NetStream.Publish.Start"  
61 -#define StatusCodeDataStart "NetStream.Data.Start"  
62 -#define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success"  
63 -  
64 -// FMLE  
65 -#define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish"  
66 -#define RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH "onFCUnpublish"  
67 -  
68 -// default stream id for response the createStream request.  
69 -#define SRS_DEFAULT_SID 1  
70 -  
71 -SrsRequest::SrsRequest()  
72 -{  
73 - objectEncoding = RTMP_SIG_AMF0_VER;  
74 -}  
75 -  
76 -SrsRequest::~SrsRequest()  
77 -{  
78 -}  
79 -  
80 -SrsRequest* SrsRequest::copy()  
81 -{  
82 - SrsRequest* cp = new SrsRequest();  
83 -  
84 - cp->app = app;  
85 - cp->objectEncoding = objectEncoding;  
86 - cp->pageUrl = pageUrl;  
87 - cp->port = port;  
88 - cp->schema = schema;  
89 - cp->stream = stream;  
90 - cp->swfUrl = swfUrl;  
91 - cp->tcUrl = tcUrl;  
92 - cp->vhost = vhost;  
93 -  
94 - return cp;  
95 -}  
96 -  
97 -int SrsRequest::discovery_app()  
98 -{  
99 - int ret = ERROR_SUCCESS;  
100 -  
101 - size_t pos = std::string::npos;  
102 - std::string url = tcUrl;  
103 -  
104 - if ((pos = url.find("://")) != std::string::npos) {  
105 - schema = url.substr(0, pos);  
106 - url = url.substr(schema.length() + 3);  
107 - srs_verbose("discovery schema=%s", schema.c_str());  
108 - }  
109 -  
110 - if ((pos = url.find("/")) != std::string::npos) {  
111 - vhost = url.substr(0, pos);  
112 - url = url.substr(vhost.length() + 1);  
113 - srs_verbose("discovery vhost=%s", vhost.c_str());  
114 - }  
115 -  
116 - port = RTMP_DEFAULT_PORTS;  
117 - if ((pos = vhost.find(":")) != std::string::npos) {  
118 - port = vhost.substr(pos + 1);  
119 - vhost = vhost.substr(0, pos);  
120 - srs_verbose("discovery vhost=%s, port=%s", vhost.c_str(), port.c_str());  
121 - }  
122 -  
123 - app = url;  
124 - srs_vhost_resolve(vhost, app);  
125 -  
126 - // resolve the vhost from config  
127 - SrsConfDirective* parsed_vhost = config->get_vhost(vhost);  
128 - if (parsed_vhost) {  
129 - vhost = parsed_vhost->arg0();  
130 - }  
131 -  
132 - // TODO: discovery the params of vhost.  
133 -  
134 - srs_info("discovery app success. schema=%s, vhost=%s, port=%s, app=%s",  
135 - schema.c_str(), vhost.c_str(), port.c_str(), app.c_str());  
136 -  
137 - if (schema.empty() || vhost.empty() || port.empty() || app.empty()) {  
138 - ret = ERROR_RTMP_REQ_TCURL;  
139 - srs_error("discovery tcUrl failed. "  
140 - "tcUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, ret=%d",  
141 - tcUrl.c_str(), schema.c_str(), vhost.c_str(), port.c_str(), app.c_str(), ret);  
142 - return ret;  
143 - }  
144 -  
145 - strip();  
146 -  
147 - return ret;  
148 -}  
149 -  
150 -string SrsRequest::get_stream_url()  
151 -{  
152 - std::string url = "";  
153 -  
154 - url += vhost;  
155 - url += "/";  
156 - url += app;  
157 - url += "/";  
158 - url += stream;  
159 -  
160 - return url;  
161 -}  
162 -  
163 -void SrsRequest::strip()  
164 -{  
165 - trim(vhost, "/ \n\r\t");  
166 - trim(app, "/ \n\r\t");  
167 - trim(stream, "/ \n\r\t");  
168 -}  
169 -  
170 -std::string& SrsRequest::trim(string& str, string chs)  
171 -{  
172 - for (int i = 0; i < (int)chs.length(); i++) {  
173 - char ch = chs.at(i);  
174 -  
175 - for (std::string::iterator it = str.begin(); it != str.end();) {  
176 - if (ch == *it) {  
177 - it = str.erase(it);  
178 - } else {  
179 - ++it;  
180 - }  
181 - }  
182 - }  
183 -  
184 - return str;  
185 -}  
186 -  
187 -SrsResponse::SrsResponse()  
188 -{  
189 - stream_id = SRS_DEFAULT_SID;  
190 -}  
191 -  
192 -SrsResponse::~SrsResponse()  
193 -{  
194 -}  
195 -  
196 -SrsRtmpClient::SrsRtmpClient(st_netfd_t _stfd)  
197 -{  
198 - stfd = _stfd;  
199 - protocol = new SrsProtocol(stfd);  
200 -}  
201 -  
202 -SrsRtmpClient::~SrsRtmpClient()  
203 -{  
204 - srs_freep(protocol);  
205 -}  
206 -  
207 -void SrsRtmpClient::set_recv_timeout(int64_t timeout_us)  
208 -{  
209 - protocol->set_recv_timeout(timeout_us);  
210 -}  
211 -  
212 -void SrsRtmpClient::set_send_timeout(int64_t timeout_us)  
213 -{  
214 - protocol->set_send_timeout(timeout_us);  
215 -}  
216 -  
217 -int64_t SrsRtmpClient::get_recv_bytes()  
218 -{  
219 - return protocol->get_recv_bytes();  
220 -}  
221 -  
222 -int64_t SrsRtmpClient::get_send_bytes()  
223 -{  
224 - return protocol->get_send_bytes();  
225 -}  
226 -  
227 -int SrsRtmpClient::get_recv_kbps()  
228 -{  
229 - return protocol->get_recv_kbps();  
230 -}  
231 -  
232 -int SrsRtmpClient::get_send_kbps()  
233 -{  
234 - return protocol->get_send_kbps();  
235 -}  
236 -  
237 -int SrsRtmpClient::recv_message(SrsCommonMessage** pmsg)  
238 -{  
239 - return protocol->recv_message(pmsg);  
240 -}  
241 -  
242 -int SrsRtmpClient::send_message(ISrsMessage* msg)  
243 -{  
244 - return protocol->send_message(msg);  
245 -}  
246 -  
247 -int SrsRtmpClient::handshake()  
248 -{  
249 - int ret = ERROR_SUCCESS;  
250 -  
251 - SrsSocket skt(stfd);  
252 -  
253 - skt.set_recv_timeout(protocol->get_recv_timeout());  
254 - skt.set_send_timeout(protocol->get_send_timeout());  
255 -  
256 - SrsComplexHandshake complex_hs;  
257 - SrsSimpleHandshake simple_hs;  
258 - if ((ret = simple_hs.handshake_with_server(skt, complex_hs)) != ERROR_SUCCESS) {  
259 - return ret;  
260 - }  
261 -  
262 - return ret;  
263 -}  
264 -  
265 -int SrsRtmpClient::connect_app(string app, string tc_url)  
266 -{  
267 - int ret = ERROR_SUCCESS;  
268 -  
269 - // Connect(vhost, app)  
270 - if (true) {  
271 - SrsCommonMessage* msg = new SrsCommonMessage();  
272 - SrsConnectAppPacket* pkt = new SrsConnectAppPacket();  
273 - msg->set_packet(pkt, 0);  
274 -  
275 - pkt->command_object = new SrsAmf0Object();  
276 - pkt->command_object->set("app", new SrsAmf0String(app.c_str()));  
277 - pkt->command_object->set("swfUrl", new SrsAmf0String());  
278 - pkt->command_object->set("tcUrl", new SrsAmf0String(tc_url.c_str()));  
279 - pkt->command_object->set("fpad", new SrsAmf0Boolean(false));  
280 - pkt->command_object->set("capabilities", new SrsAmf0Number(239));  
281 - pkt->command_object->set("audioCodecs", new SrsAmf0Number(3575));  
282 - pkt->command_object->set("videoCodecs", new SrsAmf0Number(252));  
283 - pkt->command_object->set("videoFunction", new SrsAmf0Number(1));  
284 - pkt->command_object->set("pageUrl", new SrsAmf0String());  
285 - pkt->command_object->set("objectEncoding", new SrsAmf0Number(0));  
286 -  
287 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
288 - return ret;  
289 - }  
290 - }  
291 -  
292 - // Set Window Acknowledgement size(2500000)  
293 - if (true) {  
294 - SrsCommonMessage* msg = new SrsCommonMessage();  
295 - SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();  
296 -  
297 - pkt->ackowledgement_window_size = 2500000;  
298 - msg->set_packet(pkt, 0);  
299 -  
300 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
301 - return ret;  
302 - }  
303 - }  
304 -  
305 - // expect connect _result  
306 - SrsCommonMessage* msg = NULL;  
307 - SrsConnectAppResPacket* pkt = NULL;  
308 - if ((ret = srs_rtmp_expect_message<SrsConnectAppResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
309 - srs_error("expect connect app response message failed. ret=%d", ret);  
310 - return ret;  
311 - }  
312 - SrsAutoFree(SrsCommonMessage, msg, false);  
313 - srs_info("get connect app response message");  
314 -  
315 - return ret;  
316 -}  
317 -  
318 -int SrsRtmpClient::create_stream(int& stream_id)  
319 -{  
320 - int ret = ERROR_SUCCESS;  
321 -  
322 - // CreateStream  
323 - if (true) {  
324 - SrsCommonMessage* msg = new SrsCommonMessage();  
325 - SrsCreateStreamPacket* pkt = new SrsCreateStreamPacket();  
326 -  
327 - msg->set_packet(pkt, 0);  
328 -  
329 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
330 - return ret;  
331 - }  
332 - }  
333 -  
334 - // CreateStream _result.  
335 - if (true) {  
336 - SrsCommonMessage* msg = NULL;  
337 - SrsCreateStreamResPacket* pkt = NULL;  
338 - if ((ret = srs_rtmp_expect_message<SrsCreateStreamResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
339 - srs_error("expect create stream response message failed. ret=%d", ret);  
340 - return ret;  
341 - }  
342 - SrsAutoFree(SrsCommonMessage, msg, false);  
343 - srs_info("get create stream response message");  
344 -  
345 - stream_id = (int)pkt->stream_id;  
346 - }  
347 -  
348 - return ret;  
349 -}  
350 -  
351 -int SrsRtmpClient::play(string stream, int stream_id)  
352 -{  
353 - int ret = ERROR_SUCCESS;  
354 -  
355 - // Play(stream)  
356 - if (true) {  
357 - SrsCommonMessage* msg = new SrsCommonMessage();  
358 - SrsPlayPacket* pkt = new SrsPlayPacket();  
359 -  
360 - pkt->stream_name = stream;  
361 - msg->set_packet(pkt, stream_id);  
362 -  
363 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
364 - srs_error("send play stream failed. "  
365 - "stream=%s, stream_id=%d, ret=%d",  
366 - stream.c_str(), stream_id, ret);  
367 - return ret;  
368 - }  
369 - }  
370 -  
371 - // SetBufferLength(1000ms)  
372 - int buffer_length_ms = 1000;  
373 - if (true) {  
374 - SrsCommonMessage* msg = new SrsCommonMessage();  
375 - SrsUserControlPacket* pkt = new SrsUserControlPacket();  
376 -  
377 - pkt->event_type = SrcPCUCSetBufferLength;  
378 - pkt->event_data = stream_id;  
379 - pkt->extra_data = buffer_length_ms;  
380 - msg->set_packet(pkt, 0);  
381 -  
382 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
383 - srs_error("send set buffer length failed. "  
384 - "stream=%s, stream_id=%d, bufferLength=%d, ret=%d",  
385 - stream.c_str(), stream_id, buffer_length_ms, ret);  
386 - return ret;  
387 - }  
388 - }  
389 -  
390 - return ret;  
391 -}  
392 -  
393 -int SrsRtmpClient::publish(string stream, int stream_id)  
394 -{  
395 - int ret = ERROR_SUCCESS;  
396 -  
397 - // publish(stream)  
398 - if (true) {  
399 - SrsCommonMessage* msg = new SrsCommonMessage();  
400 - SrsPublishPacket* pkt = new SrsPublishPacket();  
401 -  
402 - pkt->stream_name = stream;  
403 - msg->set_packet(pkt, stream_id);  
404 -  
405 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
406 - srs_error("send publish message failed. "  
407 - "stream=%s, stream_id=%d, ret=%d",  
408 - stream.c_str(), stream_id, ret);  
409 - return ret;  
410 - }  
411 - }  
412 -  
413 - return ret;  
414 -}  
415 -  
416 -SrsRtmp::SrsRtmp(st_netfd_t client_stfd)  
417 -{  
418 - protocol = new SrsProtocol(client_stfd);  
419 - stfd = client_stfd;  
420 -}  
421 -  
422 -SrsRtmp::~SrsRtmp()  
423 -{  
424 - srs_freep(protocol);  
425 -}  
426 -  
427 -SrsProtocol* SrsRtmp::get_protocol()  
428 -{  
429 - return protocol;  
430 -}  
431 -  
432 -void SrsRtmp::set_recv_timeout(int64_t timeout_us)  
433 -{  
434 - protocol->set_recv_timeout(timeout_us);  
435 -}  
436 -  
437 -int64_t SrsRtmp::get_recv_timeout()  
438 -{  
439 - return protocol->get_recv_timeout();  
440 -}  
441 -  
442 -void SrsRtmp::set_send_timeout(int64_t timeout_us)  
443 -{  
444 - protocol->set_send_timeout(timeout_us);  
445 -}  
446 -  
447 -int64_t SrsRtmp::get_send_timeout()  
448 -{  
449 - return protocol->get_send_timeout();  
450 -}  
451 -  
452 -int64_t SrsRtmp::get_recv_bytes()  
453 -{  
454 - return protocol->get_recv_bytes();  
455 -}  
456 -  
457 -int64_t SrsRtmp::get_send_bytes()  
458 -{  
459 - return protocol->get_send_bytes();  
460 -}  
461 -  
462 -int SrsRtmp::get_recv_kbps()  
463 -{  
464 - return protocol->get_recv_kbps();  
465 -}  
466 -  
467 -int SrsRtmp::get_send_kbps()  
468 -{  
469 - return protocol->get_send_kbps();  
470 -}  
471 -  
472 -int SrsRtmp::recv_message(SrsCommonMessage** pmsg)  
473 -{  
474 - return protocol->recv_message(pmsg);  
475 -}  
476 -  
477 -int SrsRtmp::send_message(ISrsMessage* msg)  
478 -{  
479 - return protocol->send_message(msg);  
480 -}  
481 -  
482 -int SrsRtmp::handshake()  
483 -{  
484 - int ret = ERROR_SUCCESS;  
485 -  
486 - SrsSocket skt(stfd);  
487 -  
488 - skt.set_recv_timeout(protocol->get_recv_timeout());  
489 - skt.set_send_timeout(protocol->get_send_timeout());  
490 -  
491 - SrsComplexHandshake complex_hs;  
492 - SrsSimpleHandshake simple_hs;  
493 - if ((ret = simple_hs.handshake_with_client(skt, complex_hs)) != ERROR_SUCCESS) {  
494 - return ret;  
495 - }  
496 -  
497 - return ret;  
498 -}  
499 -  
500 -int SrsRtmp::connect_app(SrsRequest* req)  
501 -{  
502 - int ret = ERROR_SUCCESS;  
503 -  
504 - SrsCommonMessage* msg = NULL;  
505 - SrsConnectAppPacket* pkt = NULL;  
506 - if ((ret = srs_rtmp_expect_message<SrsConnectAppPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
507 - srs_error("expect connect app message failed. ret=%d", ret);  
508 - return ret;  
509 - }  
510 - SrsAutoFree(SrsCommonMessage, msg, false);  
511 - srs_info("get connect app message");  
512 -  
513 - SrsAmf0Any* prop = NULL;  
514 -  
515 - if ((prop = pkt->command_object->ensure_property_string("tcUrl")) == NULL) {  
516 - ret = ERROR_RTMP_REQ_CONNECT;  
517 - srs_error("invalid request, must specifies the tcUrl. ret=%d", ret);  
518 - return ret;  
519 - }  
520 - req->tcUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;  
521 -  
522 - if ((prop = pkt->command_object->ensure_property_string("pageUrl")) != NULL) {  
523 - req->pageUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;  
524 - }  
525 -  
526 - if ((prop = pkt->command_object->ensure_property_string("swfUrl")) != NULL) {  
527 - req->swfUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;  
528 - }  
529 -  
530 - if ((prop = pkt->command_object->ensure_property_number("objectEncoding")) != NULL) {  
531 - req->objectEncoding = srs_amf0_convert<SrsAmf0Number>(prop)->value;  
532 - }  
533 -  
534 - srs_info("get connect app message params success.");  
535 -  
536 - return req->discovery_app();  
537 -}  
538 -  
539 -int SrsRtmp::set_window_ack_size(int ack_size)  
540 -{  
541 - int ret = ERROR_SUCCESS;  
542 -  
543 - SrsCommonMessage* msg = new SrsCommonMessage();  
544 - SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();  
545 -  
546 - pkt->ackowledgement_window_size = ack_size;  
547 - msg->set_packet(pkt, 0);  
548 -  
549 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
550 - srs_error("send ack size message failed. ret=%d", ret);  
551 - return ret;  
552 - }  
553 - srs_info("send ack size message success. ack_size=%d", ack_size);  
554 -  
555 - return ret;  
556 -}  
557 -  
558 -int SrsRtmp::set_peer_bandwidth(int bandwidth, int type)  
559 -{  
560 - int ret = ERROR_SUCCESS;  
561 -  
562 - SrsCommonMessage* msg = new SrsCommonMessage();  
563 - SrsSetPeerBandwidthPacket* pkt = new SrsSetPeerBandwidthPacket();  
564 -  
565 - pkt->bandwidth = bandwidth;  
566 - pkt->type = type;  
567 - msg->set_packet(pkt, 0);  
568 -  
569 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
570 - srs_error("send set bandwidth message failed. ret=%d", ret);  
571 - return ret;  
572 - }  
573 - srs_info("send set bandwidth message "  
574 - "success. bandwidth=%d, type=%d", bandwidth, type);  
575 -  
576 - return ret;  
577 -}  
578 -  
579 -int SrsRtmp::response_connect_app(SrsRequest* req)  
580 -{  
581 - int ret = ERROR_SUCCESS;  
582 -  
583 - SrsCommonMessage* msg = new SrsCommonMessage();  
584 - SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();  
585 -  
586 - pkt->props->set("fmsVer", new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER));  
587 - pkt->props->set("capabilities", new SrsAmf0Number(127));  
588 - pkt->props->set("mode", new SrsAmf0Number(1));  
589 -  
590 - pkt->info->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
591 - pkt->info->set(StatusCode, new SrsAmf0String(StatusCodeConnectSuccess));  
592 - pkt->info->set(StatusDescription, new SrsAmf0String("Connection succeeded"));  
593 - pkt->info->set("objectEncoding", new SrsAmf0Number(req->objectEncoding));  
594 - SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray();  
595 - pkt->info->set("data", data);  
596 -  
597 - data->set("srs_version", new SrsAmf0String(RTMP_SIG_FMS_VER));  
598 - data->set("srs_server", new SrsAmf0String(RTMP_SIG_SRS_NAME));  
599 - data->set("srs_license", new SrsAmf0String(RTMP_SIG_SRS_LICENSE));  
600 - data->set("srs_role", new SrsAmf0String(RTMP_SIG_SRS_ROLE));  
601 - data->set("srs_url", new SrsAmf0String(RTMP_SIG_SRS_URL));  
602 - data->set("srs_version", new SrsAmf0String(RTMP_SIG_SRS_VERSION));  
603 - data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB));  
604 - data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL));  
605 - data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT));  
606 -  
607 - msg->set_packet(pkt, 0);  
608 -  
609 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
610 - srs_error("send connect app response message failed. ret=%d", ret);  
611 - return ret;  
612 - }  
613 - srs_info("send connect app response message success.");  
614 -  
615 - return ret;  
616 -}  
617 -  
618 -int SrsRtmp::on_bw_done()  
619 -{  
620 - int ret = ERROR_SUCCESS;  
621 -  
622 - SrsCommonMessage* msg = new SrsCommonMessage();  
623 - SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket();  
624 -  
625 - msg->set_packet(pkt, 0);  
626 -  
627 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
628 - srs_error("send onBWDone message failed. ret=%d", ret);  
629 - return ret;  
630 - }  
631 - srs_info("send onBWDone message success.");  
632 -  
633 - return ret;  
634 -}  
635 -  
636 -int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& stream_name)  
637 -{  
638 - type = SrsClientUnknown;  
639 - int ret = ERROR_SUCCESS;  
640 -  
641 - while (true) {  
642 - SrsCommonMessage* msg = NULL;  
643 - if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {  
644 - srs_error("recv identify client message failed. ret=%d", ret);  
645 - return ret;  
646 - }  
647 -  
648 - SrsAutoFree(SrsCommonMessage, msg, false);  
649 -  
650 - if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {  
651 - srs_trace("identify ignore messages except "  
652 - "AMF0/AMF3 command message. type=%#x", msg->header.message_type);  
653 - continue;  
654 - }  
655 -  
656 - if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {  
657 - srs_error("identify decode message failed. ret=%d", ret);  
658 - return ret;  
659 - }  
660 -  
661 - SrsPacket* pkt = msg->get_packet();  
662 - if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {  
663 - srs_info("identify client by create stream, play or flash publish.");  
664 - return identify_create_stream_client(  
665 - dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name);  
666 - }  
667 - if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {  
668 - srs_info("identify client by releaseStream, fmle publish.");  
669 - return identify_fmle_publish_client(  
670 - dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);  
671 - }  
672 -  
673 - srs_trace("ignore AMF0/AMF3 command message.");  
674 - }  
675 -  
676 - return ret;  
677 -}  
678 -  
679 -int SrsRtmp::set_chunk_size(int chunk_size)  
680 -{  
681 - int ret = ERROR_SUCCESS;  
682 -  
683 - SrsCommonMessage* msg = new SrsCommonMessage();  
684 - SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();  
685 -  
686 - pkt->chunk_size = chunk_size;  
687 - msg->set_packet(pkt, 0);  
688 -  
689 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
690 - srs_error("send set chunk size message failed. ret=%d", ret);  
691 - return ret;  
692 - }  
693 - srs_info("send set chunk size message success. chunk_size=%d", chunk_size);  
694 -  
695 - return ret;  
696 -}  
697 -  
698 -int SrsRtmp::start_play(int stream_id)  
699 -{  
700 - int ret = ERROR_SUCCESS;  
701 -  
702 - // StreamBegin  
703 - if (true) {  
704 - SrsCommonMessage* msg = new SrsCommonMessage();  
705 - SrsUserControlPacket* pkt = new SrsUserControlPacket();  
706 -  
707 - pkt->event_type = SrcPCUCStreamBegin;  
708 - pkt->event_data = stream_id;  
709 - msg->set_packet(pkt, 0);  
710 -  
711 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
712 - srs_error("send PCUC(StreamBegin) message failed. ret=%d", ret);  
713 - return ret;  
714 - }  
715 - srs_info("send PCUC(StreamBegin) message success.");  
716 - }  
717 -  
718 - // onStatus(NetStream.Play.Reset)  
719 - if (true) {  
720 - SrsCommonMessage* msg = new SrsCommonMessage();  
721 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
722 -  
723 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
724 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamReset));  
725 - pkt->data->set(StatusDescription, new SrsAmf0String("Playing and resetting stream."));  
726 - pkt->data->set(StatusDetails, new SrsAmf0String("stream"));  
727 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
728 -  
729 - msg->set_packet(pkt, stream_id);  
730 -  
731 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
732 - srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);  
733 - return ret;  
734 - }  
735 - srs_info("send onStatus(NetStream.Play.Reset) message success.");  
736 - }  
737 -  
738 - // onStatus(NetStream.Play.Start)  
739 - if (true) {  
740 - SrsCommonMessage* msg = new SrsCommonMessage();  
741 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
742 -  
743 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
744 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamStart));  
745 - pkt->data->set(StatusDescription, new SrsAmf0String("Started playing stream."));  
746 - pkt->data->set(StatusDetails, new SrsAmf0String("stream"));  
747 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
748 -  
749 - msg->set_packet(pkt, stream_id);  
750 -  
751 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
752 - srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);  
753 - return ret;  
754 - }  
755 - srs_info("send onStatus(NetStream.Play.Reset) message success.");  
756 - }  
757 -  
758 - // |RtmpSampleAccess(false, false)  
759 - if (true) {  
760 - SrsCommonMessage* msg = new SrsCommonMessage();  
761 - SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket();  
762 -  
763 - msg->set_packet(pkt, stream_id);  
764 -  
765 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
766 - srs_error("send |RtmpSampleAccess(false, false) message failed. ret=%d", ret);  
767 - return ret;  
768 - }  
769 - srs_info("send |RtmpSampleAccess(false, false) message success.");  
770 - }  
771 -  
772 - // onStatus(NetStream.Data.Start)  
773 - if (true) {  
774 - SrsCommonMessage* msg = new SrsCommonMessage();  
775 - SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket();  
776 -  
777 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeDataStart));  
778 -  
779 - msg->set_packet(pkt, stream_id);  
780 -  
781 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
782 - srs_error("send onStatus(NetStream.Data.Start) message failed. ret=%d", ret);  
783 - return ret;  
784 - }  
785 - srs_info("send onStatus(NetStream.Data.Start) message success.");  
786 - }  
787 -  
788 - srs_info("start play success.");  
789 -  
790 - return ret;  
791 -}  
792 -  
793 -int SrsRtmp::on_play_client_pause(int stream_id, bool is_pause)  
794 -{  
795 - int ret = ERROR_SUCCESS;  
796 -  
797 - if (is_pause) {  
798 - // onStatus(NetStream.Pause.Notify)  
799 - if (true) {  
800 - SrsCommonMessage* msg = new SrsCommonMessage();  
801 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
802 -  
803 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
804 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamPause));  
805 - pkt->data->set(StatusDescription, new SrsAmf0String("Paused stream."));  
806 -  
807 - msg->set_packet(pkt, stream_id);  
808 -  
809 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
810 - srs_error("send onStatus(NetStream.Pause.Notify) message failed. ret=%d", ret);  
811 - return ret;  
812 - }  
813 - srs_info("send onStatus(NetStream.Pause.Notify) message success.");  
814 - }  
815 - // StreamEOF  
816 - if (true) {  
817 - SrsCommonMessage* msg = new SrsCommonMessage();  
818 - SrsUserControlPacket* pkt = new SrsUserControlPacket();  
819 -  
820 - pkt->event_type = SrcPCUCStreamEOF;  
821 - pkt->event_data = stream_id;  
822 - msg->set_packet(pkt, 0);  
823 -  
824 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
825 - srs_error("send PCUC(StreamEOF) message failed. ret=%d", ret);  
826 - return ret;  
827 - }  
828 - srs_info("send PCUC(StreamEOF) message success.");  
829 - }  
830 - } else {  
831 - // onStatus(NetStream.Unpause.Notify)  
832 - if (true) {  
833 - SrsCommonMessage* msg = new SrsCommonMessage();  
834 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
835 -  
836 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
837 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamUnpause));  
838 - pkt->data->set(StatusDescription, new SrsAmf0String("Unpaused stream."));  
839 -  
840 - msg->set_packet(pkt, stream_id);  
841 -  
842 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
843 - srs_error("send onStatus(NetStream.Unpause.Notify) message failed. ret=%d", ret);  
844 - return ret;  
845 - }  
846 - srs_info("send onStatus(NetStream.Unpause.Notify) message success.");  
847 - }  
848 - // StreanBegin  
849 - if (true) {  
850 - SrsCommonMessage* msg = new SrsCommonMessage();  
851 - SrsUserControlPacket* pkt = new SrsUserControlPacket();  
852 -  
853 - pkt->event_type = SrcPCUCStreamBegin;  
854 - pkt->event_data = stream_id;  
855 - msg->set_packet(pkt, 0);  
856 -  
857 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
858 - srs_error("send PCUC(StreanBegin) message failed. ret=%d", ret);  
859 - return ret;  
860 - }  
861 - srs_info("send PCUC(StreanBegin) message success.");  
862 - }  
863 - }  
864 -  
865 - return ret;  
866 -}  
867 -  
868 -int SrsRtmp::start_fmle_publish(int stream_id)  
869 -{  
870 - int ret = ERROR_SUCCESS;  
871 -  
872 - // FCPublish  
873 - double fc_publish_tid = 0;  
874 - if (true) {  
875 - SrsCommonMessage* msg = NULL;  
876 - SrsFMLEStartPacket* pkt = NULL;  
877 - if ((ret = srs_rtmp_expect_message<SrsFMLEStartPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
878 - srs_error("recv FCPublish message failed. ret=%d", ret);  
879 - return ret;  
880 - }  
881 - srs_info("recv FCPublish request message success.");  
882 -  
883 - SrsAutoFree(SrsCommonMessage, msg, false);  
884 - fc_publish_tid = pkt->transaction_id;  
885 - }  
886 - // FCPublish response  
887 - if (true) {  
888 - SrsCommonMessage* msg = new SrsCommonMessage();  
889 - SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid);  
890 -  
891 - msg->set_packet(pkt, 0);  
892 -  
893 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
894 - srs_error("send FCPublish response message failed. ret=%d", ret);  
895 - return ret;  
896 - }  
897 - srs_info("send FCPublish response message success.");  
898 - }  
899 -  
900 - // createStream  
901 - double create_stream_tid = 0;  
902 - if (true) {  
903 - SrsCommonMessage* msg = NULL;  
904 - SrsCreateStreamPacket* pkt = NULL;  
905 - if ((ret = srs_rtmp_expect_message<SrsCreateStreamPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
906 - srs_error("recv createStream message failed. ret=%d", ret);  
907 - return ret;  
908 - }  
909 - srs_info("recv createStream request message success.");  
910 -  
911 - SrsAutoFree(SrsCommonMessage, msg, false);  
912 - create_stream_tid = pkt->transaction_id;  
913 - }  
914 - // createStream response  
915 - if (true) {  
916 - SrsCommonMessage* msg = new SrsCommonMessage();  
917 - SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id);  
918 -  
919 - msg->set_packet(pkt, 0);  
920 -  
921 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
922 - srs_error("send createStream response message failed. ret=%d", ret);  
923 - return ret;  
924 - }  
925 - srs_info("send createStream response message success.");  
926 - }  
927 -  
928 - // publish  
929 - if (true) {  
930 - SrsCommonMessage* msg = NULL;  
931 - SrsPublishPacket* pkt = NULL;  
932 - if ((ret = srs_rtmp_expect_message<SrsPublishPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {  
933 - srs_error("recv publish message failed. ret=%d", ret);  
934 - return ret;  
935 - }  
936 - srs_info("recv publish request message success.");  
937 -  
938 - SrsAutoFree(SrsCommonMessage, msg, false);  
939 - }  
940 - // publish response onFCPublish(NetStream.Publish.Start)  
941 - if (true) {  
942 - SrsCommonMessage* msg = new SrsCommonMessage();  
943 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
944 -  
945 - pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH;  
946 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));  
947 - pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));  
948 -  
949 - msg->set_packet(pkt, stream_id);  
950 -  
951 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
952 - srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret);  
953 - return ret;  
954 - }  
955 - srs_info("send onFCPublish(NetStream.Publish.Start) message success.");  
956 - }  
957 - // publish response onStatus(NetStream.Publish.Start)  
958 - if (true) {  
959 - SrsCommonMessage* msg = new SrsCommonMessage();  
960 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
961 -  
962 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
963 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));  
964 - pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));  
965 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
966 -  
967 - msg->set_packet(pkt, stream_id);  
968 -  
969 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
970 - srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);  
971 - return ret;  
972 - }  
973 - srs_info("send onStatus(NetStream.Publish.Start) message success.");  
974 - }  
975 -  
976 - srs_info("FMLE publish success.");  
977 -  
978 - return ret;  
979 -}  
980 -  
981 -int SrsRtmp::fmle_unpublish(int stream_id, double unpublish_tid)  
982 -{  
983 - int ret = ERROR_SUCCESS;  
984 -  
985 - // publish response onFCUnpublish(NetStream.unpublish.Success)  
986 - if (true) {  
987 - SrsCommonMessage* msg = new SrsCommonMessage();  
988 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
989 -  
990 - pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH;  
991 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));  
992 - pkt->data->set(StatusDescription, new SrsAmf0String("Stop publishing stream."));  
993 -  
994 - msg->set_packet(pkt, stream_id);  
995 -  
996 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
997 - srs_error("send onFCUnpublish(NetStream.unpublish.Success) message failed. ret=%d", ret);  
998 - return ret;  
999 - }  
1000 - srs_info("send onFCUnpublish(NetStream.unpublish.Success) message success.");  
1001 - }  
1002 - // FCUnpublish response  
1003 - if (true) {  
1004 - SrsCommonMessage* msg = new SrsCommonMessage();  
1005 - SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(unpublish_tid);  
1006 -  
1007 - msg->set_packet(pkt, stream_id);  
1008 -  
1009 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
1010 - srs_error("send FCUnpublish response message failed. ret=%d", ret);  
1011 - return ret;  
1012 - }  
1013 - srs_info("send FCUnpublish response message success.");  
1014 - }  
1015 - // publish response onStatus(NetStream.Unpublish.Success)  
1016 - if (true) {  
1017 - SrsCommonMessage* msg = new SrsCommonMessage();  
1018 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
1019 -  
1020 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
1021 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));  
1022 - pkt->data->set(StatusDescription, new SrsAmf0String("Stream is now unpublished"));  
1023 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
1024 -  
1025 - msg->set_packet(pkt, stream_id);  
1026 -  
1027 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
1028 - srs_error("send onStatus(NetStream.Unpublish.Success) message failed. ret=%d", ret);  
1029 - return ret;  
1030 - }  
1031 - srs_info("send onStatus(NetStream.Unpublish.Success) message success.");  
1032 - }  
1033 -  
1034 - srs_info("FMLE unpublish success.");  
1035 -  
1036 - return ret;  
1037 -}  
1038 -  
1039 -int SrsRtmp::start_flash_publish(int stream_id)  
1040 -{  
1041 - int ret = ERROR_SUCCESS;  
1042 -  
1043 - // publish response onStatus(NetStream.Publish.Start)  
1044 - if (true) {  
1045 - SrsCommonMessage* msg = new SrsCommonMessage();  
1046 - SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();  
1047 -  
1048 - pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));  
1049 - pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));  
1050 - pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));  
1051 - pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));  
1052 -  
1053 - msg->set_packet(pkt, stream_id);  
1054 -  
1055 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
1056 - srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);  
1057 - return ret;  
1058 - }  
1059 - srs_info("send onStatus(NetStream.Publish.Start) message success.");  
1060 - }  
1061 -  
1062 - srs_info("flash publish success.");  
1063 -  
1064 - return ret;  
1065 -}  
1066 -  
1067 -int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, string& stream_name)  
1068 -{  
1069 - int ret = ERROR_SUCCESS;  
1070 -  
1071 - if (true) {  
1072 - SrsCommonMessage* msg = new SrsCommonMessage();  
1073 - SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id);  
1074 -  
1075 - msg->set_packet(pkt, 0);  
1076 -  
1077 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
1078 - srs_error("send createStream response message failed. ret=%d", ret);  
1079 - return ret;  
1080 - }  
1081 - srs_info("send createStream response message success.");  
1082 - }  
1083 -  
1084 - while (true) {  
1085 - SrsCommonMessage* msg = NULL;  
1086 - if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {  
1087 - srs_error("recv identify client message failed. ret=%d", ret);  
1088 - return ret;  
1089 - }  
1090 -  
1091 - SrsAutoFree(SrsCommonMessage, msg, false);  
1092 -  
1093 - if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {  
1094 - srs_trace("identify ignore messages except "  
1095 - "AMF0/AMF3 command message. type=%#x", msg->header.message_type);  
1096 - continue;  
1097 - }  
1098 -  
1099 - if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {  
1100 - srs_error("identify decode message failed. ret=%d", ret);  
1101 - return ret;  
1102 - }  
1103 -  
1104 - SrsPacket* pkt = msg->get_packet();  
1105 - if (dynamic_cast<SrsPlayPacket*>(pkt)) {  
1106 - SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt);  
1107 - type = SrsClientPlay;  
1108 - stream_name = play->stream_name;  
1109 - srs_trace("identity client type=play, stream_name=%s", stream_name.c_str());  
1110 - return ret;  
1111 - }  
1112 - if (dynamic_cast<SrsPublishPacket*>(pkt)) {  
1113 - srs_info("identify client by publish, falsh publish.");  
1114 - return identify_flash_publish_client(  
1115 - dynamic_cast<SrsPublishPacket*>(pkt), type, stream_name);  
1116 - }  
1117 -  
1118 - srs_trace("ignore AMF0/AMF3 command message.");  
1119 - }  
1120 -  
1121 - return ret;  
1122 -}  
1123 -  
1124 -int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, string& stream_name)  
1125 -{  
1126 - int ret = ERROR_SUCCESS;  
1127 -  
1128 - type = SrsClientFMLEPublish;  
1129 - stream_name = req->stream_name;  
1130 -  
1131 - // releaseStream response  
1132 - if (true) {  
1133 - SrsCommonMessage* msg = new SrsCommonMessage();  
1134 - SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);  
1135 -  
1136 - msg->set_packet(pkt, 0);  
1137 -  
1138 - if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {  
1139 - srs_error("send releaseStream response message failed. ret=%d", ret);  
1140 - return ret;  
1141 - }  
1142 - srs_info("send releaseStream response message success.");  
1143 - }  
1144 -  
1145 - return ret;  
1146 -}  
1147 -  
1148 -int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& type, string& stream_name)  
1149 -{  
1150 - int ret = ERROR_SUCCESS;  
1151 -  
1152 - type = SrsClientFlashPublish;  
1153 - stream_name = req->stream_name;  
1154 -  
1155 - return ret;  
1156 -}  
1157 - 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_rtmp.hpp>
  25 +
  26 +#include <srs_core_log.hpp>
  27 +#include <srs_core_error.hpp>
  28 +#include <srs_core_socket.hpp>
  29 +#include <srs_core_protocol.hpp>
  30 +#include <srs_core_autofree.hpp>
  31 +#include <srs_core_amf0.hpp>
  32 +#include <srs_core_handshake.hpp>
  33 +#include <srs_core_config.hpp>
  34 +
  35 +using namespace std;
  36 +
  37 +/**
  38 +* the signature for packets to client.
  39 +*/
  40 +#define RTMP_SIG_FMS_VER "3,5,3,888"
  41 +#define RTMP_SIG_AMF0_VER 0
  42 +#define RTMP_SIG_CLIENT_ID "ASAICiss"
  43 +
  44 +/**
  45 +* onStatus consts.
  46 +*/
  47 +#define StatusLevel "level"
  48 +#define StatusCode "code"
  49 +#define StatusDescription "description"
  50 +#define StatusDetails "details"
  51 +#define StatusClientId "clientid"
  52 +// status value
  53 +#define StatusLevelStatus "status"
  54 +// code value
  55 +#define StatusCodeConnectSuccess "NetConnection.Connect.Success"
  56 +#define StatusCodeStreamReset "NetStream.Play.Reset"
  57 +#define StatusCodeStreamStart "NetStream.Play.Start"
  58 +#define StatusCodeStreamPause "NetStream.Pause.Notify"
  59 +#define StatusCodeStreamUnpause "NetStream.Unpause.Notify"
  60 +#define StatusCodePublishStart "NetStream.Publish.Start"
  61 +#define StatusCodeDataStart "NetStream.Data.Start"
  62 +#define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success"
  63 +
  64 +// FMLE
  65 +#define RTMP_AMF0_COMMAND_ON_FC_PUBLISH "onFCPublish"
  66 +#define RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH "onFCUnpublish"
  67 +
  68 +// default stream id for response the createStream request.
  69 +#define SRS_DEFAULT_SID 1
  70 +
  71 +SrsRequest::SrsRequest()
  72 +{
  73 + objectEncoding = RTMP_SIG_AMF0_VER;
  74 +}
  75 +
  76 +SrsRequest::~SrsRequest()
  77 +{
  78 +}
  79 +
  80 +SrsRequest* SrsRequest::copy()
  81 +{
  82 + SrsRequest* cp = new SrsRequest();
  83 +
  84 + cp->app = app;
  85 + cp->objectEncoding = objectEncoding;
  86 + cp->pageUrl = pageUrl;
  87 + cp->port = port;
  88 + cp->schema = schema;
  89 + cp->stream = stream;
  90 + cp->swfUrl = swfUrl;
  91 + cp->tcUrl = tcUrl;
  92 + cp->vhost = vhost;
  93 +
  94 + return cp;
  95 +}
  96 +
  97 +int SrsRequest::discovery_app()
  98 +{
  99 + int ret = ERROR_SUCCESS;
  100 +
  101 + size_t pos = std::string::npos;
  102 + std::string url = tcUrl;
  103 +
  104 + if ((pos = url.find("://")) != std::string::npos) {
  105 + schema = url.substr(0, pos);
  106 + url = url.substr(schema.length() + 3);
  107 + srs_verbose("discovery schema=%s", schema.c_str());
  108 + }
  109 +
  110 + if ((pos = url.find("/")) != std::string::npos) {
  111 + vhost = url.substr(0, pos);
  112 + url = url.substr(vhost.length() + 1);
  113 + srs_verbose("discovery vhost=%s", vhost.c_str());
  114 + }
  115 +
  116 + port = RTMP_DEFAULT_PORTS;
  117 + if ((pos = vhost.find(":")) != std::string::npos) {
  118 + port = vhost.substr(pos + 1);
  119 + vhost = vhost.substr(0, pos);
  120 + srs_verbose("discovery vhost=%s, port=%s", vhost.c_str(), port.c_str());
  121 + }
  122 +
  123 + app = url;
  124 + srs_vhost_resolve(vhost, app);
  125 +
  126 + // resolve the vhost from config
  127 + SrsConfDirective* parsed_vhost = config->get_vhost(vhost);
  128 + if (parsed_vhost) {
  129 + vhost = parsed_vhost->arg0();
  130 + }
  131 +
  132 + // TODO: discovery the params of vhost.
  133 +
  134 + srs_info("discovery app success. schema=%s, vhost=%s, port=%s, app=%s",
  135 + schema.c_str(), vhost.c_str(), port.c_str(), app.c_str());
  136 +
  137 + if (schema.empty() || vhost.empty() || port.empty() || app.empty()) {
  138 + ret = ERROR_RTMP_REQ_TCURL;
  139 + srs_error("discovery tcUrl failed. "
  140 + "tcUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, ret=%d",
  141 + tcUrl.c_str(), schema.c_str(), vhost.c_str(), port.c_str(), app.c_str(), ret);
  142 + return ret;
  143 + }
  144 +
  145 + strip();
  146 +
  147 + return ret;
  148 +}
  149 +
  150 +string SrsRequest::get_stream_url()
  151 +{
  152 + std::string url = "";
  153 +
  154 + url += vhost;
  155 + url += "/";
  156 + url += app;
  157 + url += "/";
  158 + url += stream;
  159 +
  160 + return url;
  161 +}
  162 +
  163 +void SrsRequest::strip()
  164 +{
  165 + trim(vhost, "/ \n\r\t");
  166 + trim(app, "/ \n\r\t");
  167 + trim(stream, "/ \n\r\t");
  168 +}
  169 +
  170 +std::string& SrsRequest::trim(string& str, string chs)
  171 +{
  172 + for (int i = 0; i < (int)chs.length(); i++) {
  173 + char ch = chs.at(i);
  174 +
  175 + for (std::string::iterator it = str.begin(); it != str.end();) {
  176 + if (ch == *it) {
  177 + it = str.erase(it);
  178 + } else {
  179 + ++it;
  180 + }
  181 + }
  182 + }
  183 +
  184 + return str;
  185 +}
  186 +
  187 +SrsResponse::SrsResponse()
  188 +{
  189 + stream_id = SRS_DEFAULT_SID;
  190 +}
  191 +
  192 +SrsResponse::~SrsResponse()
  193 +{
  194 +}
  195 +
  196 +SrsRtmpClient::SrsRtmpClient(st_netfd_t _stfd)
  197 +{
  198 + stfd = _stfd;
  199 + protocol = new SrsProtocol(stfd);
  200 +}
  201 +
  202 +SrsRtmpClient::~SrsRtmpClient()
  203 +{
  204 + srs_freep(protocol);
  205 +}
  206 +
  207 +void SrsRtmpClient::set_recv_timeout(int64_t timeout_us)
  208 +{
  209 + protocol->set_recv_timeout(timeout_us);
  210 +}
  211 +
  212 +void SrsRtmpClient::set_send_timeout(int64_t timeout_us)
  213 +{
  214 + protocol->set_send_timeout(timeout_us);
  215 +}
  216 +
  217 +int64_t SrsRtmpClient::get_recv_bytes()
  218 +{
  219 + return protocol->get_recv_bytes();
  220 +}
  221 +
  222 +int64_t SrsRtmpClient::get_send_bytes()
  223 +{
  224 + return protocol->get_send_bytes();
  225 +}
  226 +
  227 +int SrsRtmpClient::get_recv_kbps()
  228 +{
  229 + return protocol->get_recv_kbps();
  230 +}
  231 +
  232 +int SrsRtmpClient::get_send_kbps()
  233 +{
  234 + return protocol->get_send_kbps();
  235 +}
  236 +
  237 +int SrsRtmpClient::recv_message(SrsCommonMessage** pmsg)
  238 +{
  239 + return protocol->recv_message(pmsg);
  240 +}
  241 +
  242 +int SrsRtmpClient::send_message(ISrsMessage* msg)
  243 +{
  244 + return protocol->send_message(msg);
  245 +}
  246 +
  247 +int SrsRtmpClient::handshake()
  248 +{
  249 + int ret = ERROR_SUCCESS;
  250 +
  251 + SrsSocket skt(stfd);
  252 +
  253 + skt.set_recv_timeout(protocol->get_recv_timeout());
  254 + skt.set_send_timeout(protocol->get_send_timeout());
  255 +
  256 + SrsComplexHandshake complex_hs;
  257 + SrsSimpleHandshake simple_hs;
  258 + if ((ret = simple_hs.handshake_with_server(skt, complex_hs)) != ERROR_SUCCESS) {
  259 + return ret;
  260 + }
  261 +
  262 + return ret;
  263 +}
  264 +
  265 +int SrsRtmpClient::connect_app(string app, string tc_url)
  266 +{
  267 + int ret = ERROR_SUCCESS;
  268 +
  269 + // Connect(vhost, app)
  270 + if (true) {
  271 + SrsCommonMessage* msg = new SrsCommonMessage();
  272 + SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
  273 + msg->set_packet(pkt, 0);
  274 +
  275 + pkt->command_object = new SrsAmf0Object();
  276 + pkt->command_object->set("app", new SrsAmf0String(app.c_str()));
  277 + pkt->command_object->set("swfUrl", new SrsAmf0String());
  278 + pkt->command_object->set("tcUrl", new SrsAmf0String(tc_url.c_str()));
  279 + pkt->command_object->set("fpad", new SrsAmf0Boolean(false));
  280 + pkt->command_object->set("capabilities", new SrsAmf0Number(239));
  281 + pkt->command_object->set("audioCodecs", new SrsAmf0Number(3575));
  282 + pkt->command_object->set("videoCodecs", new SrsAmf0Number(252));
  283 + pkt->command_object->set("videoFunction", new SrsAmf0Number(1));
  284 + pkt->command_object->set("pageUrl", new SrsAmf0String());
  285 + pkt->command_object->set("objectEncoding", new SrsAmf0Number(0));
  286 +
  287 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  288 + return ret;
  289 + }
  290 + }
  291 +
  292 + // Set Window Acknowledgement size(2500000)
  293 + if (true) {
  294 + SrsCommonMessage* msg = new SrsCommonMessage();
  295 + SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
  296 +
  297 + pkt->ackowledgement_window_size = 2500000;
  298 + msg->set_packet(pkt, 0);
  299 +
  300 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  301 + return ret;
  302 + }
  303 + }
  304 +
  305 + // expect connect _result
  306 + SrsCommonMessage* msg = NULL;
  307 + SrsConnectAppResPacket* pkt = NULL;
  308 + if ((ret = srs_rtmp_expect_message<SrsConnectAppResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  309 + srs_error("expect connect app response message failed. ret=%d", ret);
  310 + return ret;
  311 + }
  312 + SrsAutoFree(SrsCommonMessage, msg, false);
  313 + srs_info("get connect app response message");
  314 +
  315 + return ret;
  316 +}
  317 +
  318 +int SrsRtmpClient::create_stream(int& stream_id)
  319 +{
  320 + int ret = ERROR_SUCCESS;
  321 +
  322 + // CreateStream
  323 + if (true) {
  324 + SrsCommonMessage* msg = new SrsCommonMessage();
  325 + SrsCreateStreamPacket* pkt = new SrsCreateStreamPacket();
  326 +
  327 + msg->set_packet(pkt, 0);
  328 +
  329 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  330 + return ret;
  331 + }
  332 + }
  333 +
  334 + // CreateStream _result.
  335 + if (true) {
  336 + SrsCommonMessage* msg = NULL;
  337 + SrsCreateStreamResPacket* pkt = NULL;
  338 + if ((ret = srs_rtmp_expect_message<SrsCreateStreamResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  339 + srs_error("expect create stream response message failed. ret=%d", ret);
  340 + return ret;
  341 + }
  342 + SrsAutoFree(SrsCommonMessage, msg, false);
  343 + srs_info("get create stream response message");
  344 +
  345 + stream_id = (int)pkt->stream_id;
  346 + }
  347 +
  348 + return ret;
  349 +}
  350 +
  351 +int SrsRtmpClient::play(string stream, int stream_id)
  352 +{
  353 + int ret = ERROR_SUCCESS;
  354 +
  355 + // Play(stream)
  356 + if (true) {
  357 + SrsCommonMessage* msg = new SrsCommonMessage();
  358 + SrsPlayPacket* pkt = new SrsPlayPacket();
  359 +
  360 + pkt->stream_name = stream;
  361 + msg->set_packet(pkt, stream_id);
  362 +
  363 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  364 + srs_error("send play stream failed. "
  365 + "stream=%s, stream_id=%d, ret=%d",
  366 + stream.c_str(), stream_id, ret);
  367 + return ret;
  368 + }
  369 + }
  370 +
  371 + // SetBufferLength(1000ms)
  372 + int buffer_length_ms = 1000;
  373 + if (true) {
  374 + SrsCommonMessage* msg = new SrsCommonMessage();
  375 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  376 +
  377 + pkt->event_type = SrcPCUCSetBufferLength;
  378 + pkt->event_data = stream_id;
  379 + pkt->extra_data = buffer_length_ms;
  380 + msg->set_packet(pkt, 0);
  381 +
  382 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  383 + srs_error("send set buffer length failed. "
  384 + "stream=%s, stream_id=%d, bufferLength=%d, ret=%d",
  385 + stream.c_str(), stream_id, buffer_length_ms, ret);
  386 + return ret;
  387 + }
  388 + }
  389 +
  390 + return ret;
  391 +}
  392 +
  393 +int SrsRtmpClient::publish(string stream, int stream_id)
  394 +{
  395 + int ret = ERROR_SUCCESS;
  396 +
  397 + // publish(stream)
  398 + if (true) {
  399 + SrsCommonMessage* msg = new SrsCommonMessage();
  400 + SrsPublishPacket* pkt = new SrsPublishPacket();
  401 +
  402 + pkt->stream_name = stream;
  403 + msg->set_packet(pkt, stream_id);
  404 +
  405 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  406 + srs_error("send publish message failed. "
  407 + "stream=%s, stream_id=%d, ret=%d",
  408 + stream.c_str(), stream_id, ret);
  409 + return ret;
  410 + }
  411 + }
  412 +
  413 + return ret;
  414 +}
  415 +
  416 +SrsRtmp::SrsRtmp(st_netfd_t client_stfd)
  417 +{
  418 + protocol = new SrsProtocol(client_stfd);
  419 + stfd = client_stfd;
  420 +}
  421 +
  422 +SrsRtmp::~SrsRtmp()
  423 +{
  424 + srs_freep(protocol);
  425 +}
  426 +
  427 +SrsProtocol* SrsRtmp::get_protocol()
  428 +{
  429 + return protocol;
  430 +}
  431 +
  432 +void SrsRtmp::set_recv_timeout(int64_t timeout_us)
  433 +{
  434 + protocol->set_recv_timeout(timeout_us);
  435 +}
  436 +
  437 +int64_t SrsRtmp::get_recv_timeout()
  438 +{
  439 + return protocol->get_recv_timeout();
  440 +}
  441 +
  442 +void SrsRtmp::set_send_timeout(int64_t timeout_us)
  443 +{
  444 + protocol->set_send_timeout(timeout_us);
  445 +}
  446 +
  447 +int64_t SrsRtmp::get_send_timeout()
  448 +{
  449 + return protocol->get_send_timeout();
  450 +}
  451 +
  452 +int64_t SrsRtmp::get_recv_bytes()
  453 +{
  454 + return protocol->get_recv_bytes();
  455 +}
  456 +
  457 +int64_t SrsRtmp::get_send_bytes()
  458 +{
  459 + return protocol->get_send_bytes();
  460 +}
  461 +
  462 +int SrsRtmp::get_recv_kbps()
  463 +{
  464 + return protocol->get_recv_kbps();
  465 +}
  466 +
  467 +int SrsRtmp::get_send_kbps()
  468 +{
  469 + return protocol->get_send_kbps();
  470 +}
  471 +
  472 +int SrsRtmp::recv_message(SrsCommonMessage** pmsg)
  473 +{
  474 + return protocol->recv_message(pmsg);
  475 +}
  476 +
  477 +int SrsRtmp::send_message(ISrsMessage* msg)
  478 +{
  479 + return protocol->send_message(msg);
  480 +}
  481 +
  482 +int SrsRtmp::handshake()
  483 +{
  484 + int ret = ERROR_SUCCESS;
  485 +
  486 + SrsSocket skt(stfd);
  487 +
  488 + skt.set_recv_timeout(protocol->get_recv_timeout());
  489 + skt.set_send_timeout(protocol->get_send_timeout());
  490 +
  491 + SrsComplexHandshake complex_hs;
  492 + SrsSimpleHandshake simple_hs;
  493 + if ((ret = simple_hs.handshake_with_client(skt, complex_hs)) != ERROR_SUCCESS) {
  494 + return ret;
  495 + }
  496 +
  497 + return ret;
  498 +}
  499 +
  500 +int SrsRtmp::connect_app(SrsRequest* req)
  501 +{
  502 + int ret = ERROR_SUCCESS;
  503 +
  504 + SrsCommonMessage* msg = NULL;
  505 + SrsConnectAppPacket* pkt = NULL;
  506 + if ((ret = srs_rtmp_expect_message<SrsConnectAppPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  507 + srs_error("expect connect app message failed. ret=%d", ret);
  508 + return ret;
  509 + }
  510 + SrsAutoFree(SrsCommonMessage, msg, false);
  511 + srs_info("get connect app message");
  512 +
  513 + SrsAmf0Any* prop = NULL;
  514 +
  515 + if ((prop = pkt->command_object->ensure_property_string("tcUrl")) == NULL) {
  516 + ret = ERROR_RTMP_REQ_CONNECT;
  517 + srs_error("invalid request, must specifies the tcUrl. ret=%d", ret);
  518 + return ret;
  519 + }
  520 + req->tcUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;
  521 +
  522 + if ((prop = pkt->command_object->ensure_property_string("pageUrl")) != NULL) {
  523 + req->pageUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;
  524 + }
  525 +
  526 + if ((prop = pkt->command_object->ensure_property_string("swfUrl")) != NULL) {
  527 + req->swfUrl = srs_amf0_convert<SrsAmf0String>(prop)->value;
  528 + }
  529 +
  530 + if ((prop = pkt->command_object->ensure_property_number("objectEncoding")) != NULL) {
  531 + req->objectEncoding = srs_amf0_convert<SrsAmf0Number>(prop)->value;
  532 + }
  533 +
  534 + srs_info("get connect app message params success.");
  535 +
  536 + return req->discovery_app();
  537 +}
  538 +
  539 +int SrsRtmp::set_window_ack_size(int ack_size)
  540 +{
  541 + int ret = ERROR_SUCCESS;
  542 +
  543 + SrsCommonMessage* msg = new SrsCommonMessage();
  544 + SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket();
  545 +
  546 + pkt->ackowledgement_window_size = ack_size;
  547 + msg->set_packet(pkt, 0);
  548 +
  549 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  550 + srs_error("send ack size message failed. ret=%d", ret);
  551 + return ret;
  552 + }
  553 + srs_info("send ack size message success. ack_size=%d", ack_size);
  554 +
  555 + return ret;
  556 +}
  557 +
  558 +int SrsRtmp::set_peer_bandwidth(int bandwidth, int type)
  559 +{
  560 + int ret = ERROR_SUCCESS;
  561 +
  562 + SrsCommonMessage* msg = new SrsCommonMessage();
  563 + SrsSetPeerBandwidthPacket* pkt = new SrsSetPeerBandwidthPacket();
  564 +
  565 + pkt->bandwidth = bandwidth;
  566 + pkt->type = type;
  567 + msg->set_packet(pkt, 0);
  568 +
  569 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  570 + srs_error("send set bandwidth message failed. ret=%d", ret);
  571 + return ret;
  572 + }
  573 + srs_info("send set bandwidth message "
  574 + "success. bandwidth=%d, type=%d", bandwidth, type);
  575 +
  576 + return ret;
  577 +}
  578 +
  579 +int SrsRtmp::response_connect_app(SrsRequest* req)
  580 +{
  581 + int ret = ERROR_SUCCESS;
  582 +
  583 + SrsCommonMessage* msg = new SrsCommonMessage();
  584 + SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();
  585 +
  586 + pkt->props->set("fmsVer", new SrsAmf0String("FMS/"RTMP_SIG_FMS_VER));
  587 + pkt->props->set("capabilities", new SrsAmf0Number(127));
  588 + pkt->props->set("mode", new SrsAmf0Number(1));
  589 +
  590 + pkt->info->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  591 + pkt->info->set(StatusCode, new SrsAmf0String(StatusCodeConnectSuccess));
  592 + pkt->info->set(StatusDescription, new SrsAmf0String("Connection succeeded"));
  593 + pkt->info->set("objectEncoding", new SrsAmf0Number(req->objectEncoding));
  594 + SrsASrsAmf0EcmaArray* data = new SrsASrsAmf0EcmaArray();
  595 + pkt->info->set("data", data);
  596 +
  597 + data->set("srs_version", new SrsAmf0String(RTMP_SIG_FMS_VER));
  598 + data->set("srs_server", new SrsAmf0String(RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")"));
  599 + data->set("srs_license", new SrsAmf0String(RTMP_SIG_SRS_LICENSE));
  600 + data->set("srs_role", new SrsAmf0String(RTMP_SIG_SRS_ROLE));
  601 + data->set("srs_url", new SrsAmf0String(RTMP_SIG_SRS_URL));
  602 + data->set("srs_version", new SrsAmf0String(RTMP_SIG_SRS_VERSION));
  603 + data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB));
  604 + data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL));
  605 + data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT));
  606 + data->set("srs_contributor", new SrsAmf0String(RTMP_SIG_SRS_CONTRIBUTOR));
  607 +
  608 + msg->set_packet(pkt, 0);
  609 +
  610 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  611 + srs_error("send connect app response message failed. ret=%d", ret);
  612 + return ret;
  613 + }
  614 + srs_info("send connect app response message success.");
  615 +
  616 + return ret;
  617 +}
  618 +
  619 +int SrsRtmp::on_bw_done()
  620 +{
  621 + int ret = ERROR_SUCCESS;
  622 +
  623 + SrsCommonMessage* msg = new SrsCommonMessage();
  624 + SrsOnBWDonePacket* pkt = new SrsOnBWDonePacket();
  625 +
  626 + msg->set_packet(pkt, 0);
  627 +
  628 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  629 + srs_error("send onBWDone message failed. ret=%d", ret);
  630 + return ret;
  631 + }
  632 + srs_info("send onBWDone message success.");
  633 +
  634 + return ret;
  635 +}
  636 +
  637 +int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& stream_name)
  638 +{
  639 + type = SrsClientUnknown;
  640 + int ret = ERROR_SUCCESS;
  641 +
  642 + while (true) {
  643 + SrsCommonMessage* msg = NULL;
  644 + if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {
  645 + srs_error("recv identify client message failed. ret=%d", ret);
  646 + return ret;
  647 + }
  648 +
  649 + SrsAutoFree(SrsCommonMessage, msg, false);
  650 +
  651 + if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
  652 + srs_trace("identify ignore messages except "
  653 + "AMF0/AMF3 command message. type=%#x", msg->header.message_type);
  654 + continue;
  655 + }
  656 +
  657 + if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {
  658 + srs_error("identify decode message failed. ret=%d", ret);
  659 + return ret;
  660 + }
  661 +
  662 + SrsPacket* pkt = msg->get_packet();
  663 + if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {
  664 + srs_info("identify client by create stream, play or flash publish.");
  665 + return identify_create_stream_client(
  666 + dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name);
  667 + }
  668 + if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
  669 + srs_info("identify client by releaseStream, fmle publish.");
  670 + return identify_fmle_publish_client(
  671 + dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
  672 + }
  673 +
  674 + srs_trace("ignore AMF0/AMF3 command message.");
  675 + }
  676 +
  677 + return ret;
  678 +}
  679 +
  680 +int SrsRtmp::set_chunk_size(int chunk_size)
  681 +{
  682 + int ret = ERROR_SUCCESS;
  683 +
  684 + SrsCommonMessage* msg = new SrsCommonMessage();
  685 + SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();
  686 +
  687 + pkt->chunk_size = chunk_size;
  688 + msg->set_packet(pkt, 0);
  689 +
  690 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  691 + srs_error("send set chunk size message failed. ret=%d", ret);
  692 + return ret;
  693 + }
  694 + srs_info("send set chunk size message success. chunk_size=%d", chunk_size);
  695 +
  696 + return ret;
  697 +}
  698 +
  699 +int SrsRtmp::start_play(int stream_id)
  700 +{
  701 + int ret = ERROR_SUCCESS;
  702 +
  703 + // StreamBegin
  704 + if (true) {
  705 + SrsCommonMessage* msg = new SrsCommonMessage();
  706 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  707 +
  708 + pkt->event_type = SrcPCUCStreamBegin;
  709 + pkt->event_data = stream_id;
  710 + msg->set_packet(pkt, 0);
  711 +
  712 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  713 + srs_error("send PCUC(StreamBegin) message failed. ret=%d", ret);
  714 + return ret;
  715 + }
  716 + srs_info("send PCUC(StreamBegin) message success.");
  717 + }
  718 +
  719 + // onStatus(NetStream.Play.Reset)
  720 + if (true) {
  721 + SrsCommonMessage* msg = new SrsCommonMessage();
  722 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  723 +
  724 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  725 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamReset));
  726 + pkt->data->set(StatusDescription, new SrsAmf0String("Playing and resetting stream."));
  727 + pkt->data->set(StatusDetails, new SrsAmf0String("stream"));
  728 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  729 +
  730 + msg->set_packet(pkt, stream_id);
  731 +
  732 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  733 + srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);
  734 + return ret;
  735 + }
  736 + srs_info("send onStatus(NetStream.Play.Reset) message success.");
  737 + }
  738 +
  739 + // onStatus(NetStream.Play.Start)
  740 + if (true) {
  741 + SrsCommonMessage* msg = new SrsCommonMessage();
  742 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  743 +
  744 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  745 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamStart));
  746 + pkt->data->set(StatusDescription, new SrsAmf0String("Started playing stream."));
  747 + pkt->data->set(StatusDetails, new SrsAmf0String("stream"));
  748 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  749 +
  750 + msg->set_packet(pkt, stream_id);
  751 +
  752 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  753 + srs_error("send onStatus(NetStream.Play.Reset) message failed. ret=%d", ret);
  754 + return ret;
  755 + }
  756 + srs_info("send onStatus(NetStream.Play.Reset) message success.");
  757 + }
  758 +
  759 + // |RtmpSampleAccess(false, false)
  760 + if (true) {
  761 + SrsCommonMessage* msg = new SrsCommonMessage();
  762 + SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket();
  763 +
  764 + msg->set_packet(pkt, stream_id);
  765 +
  766 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  767 + srs_error("send |RtmpSampleAccess(false, false) message failed. ret=%d", ret);
  768 + return ret;
  769 + }
  770 + srs_info("send |RtmpSampleAccess(false, false) message success.");
  771 + }
  772 +
  773 + // onStatus(NetStream.Data.Start)
  774 + if (true) {
  775 + SrsCommonMessage* msg = new SrsCommonMessage();
  776 + SrsOnStatusDataPacket* pkt = new SrsOnStatusDataPacket();
  777 +
  778 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeDataStart));
  779 +
  780 + msg->set_packet(pkt, stream_id);
  781 +
  782 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  783 + srs_error("send onStatus(NetStream.Data.Start) message failed. ret=%d", ret);
  784 + return ret;
  785 + }
  786 + srs_info("send onStatus(NetStream.Data.Start) message success.");
  787 + }
  788 +
  789 + srs_info("start play success.");
  790 +
  791 + return ret;
  792 +}
  793 +
  794 +int SrsRtmp::on_play_client_pause(int stream_id, bool is_pause)
  795 +{
  796 + int ret = ERROR_SUCCESS;
  797 +
  798 + if (is_pause) {
  799 + // onStatus(NetStream.Pause.Notify)
  800 + if (true) {
  801 + SrsCommonMessage* msg = new SrsCommonMessage();
  802 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  803 +
  804 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  805 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamPause));
  806 + pkt->data->set(StatusDescription, new SrsAmf0String("Paused stream."));
  807 +
  808 + msg->set_packet(pkt, stream_id);
  809 +
  810 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  811 + srs_error("send onStatus(NetStream.Pause.Notify) message failed. ret=%d", ret);
  812 + return ret;
  813 + }
  814 + srs_info("send onStatus(NetStream.Pause.Notify) message success.");
  815 + }
  816 + // StreamEOF
  817 + if (true) {
  818 + SrsCommonMessage* msg = new SrsCommonMessage();
  819 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  820 +
  821 + pkt->event_type = SrcPCUCStreamEOF;
  822 + pkt->event_data = stream_id;
  823 + msg->set_packet(pkt, 0);
  824 +
  825 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  826 + srs_error("send PCUC(StreamEOF) message failed. ret=%d", ret);
  827 + return ret;
  828 + }
  829 + srs_info("send PCUC(StreamEOF) message success.");
  830 + }
  831 + } else {
  832 + // onStatus(NetStream.Unpause.Notify)
  833 + if (true) {
  834 + SrsCommonMessage* msg = new SrsCommonMessage();
  835 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  836 +
  837 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  838 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeStreamUnpause));
  839 + pkt->data->set(StatusDescription, new SrsAmf0String("Unpaused stream."));
  840 +
  841 + msg->set_packet(pkt, stream_id);
  842 +
  843 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  844 + srs_error("send onStatus(NetStream.Unpause.Notify) message failed. ret=%d", ret);
  845 + return ret;
  846 + }
  847 + srs_info("send onStatus(NetStream.Unpause.Notify) message success.");
  848 + }
  849 + // StreanBegin
  850 + if (true) {
  851 + SrsCommonMessage* msg = new SrsCommonMessage();
  852 + SrsUserControlPacket* pkt = new SrsUserControlPacket();
  853 +
  854 + pkt->event_type = SrcPCUCStreamBegin;
  855 + pkt->event_data = stream_id;
  856 + msg->set_packet(pkt, 0);
  857 +
  858 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  859 + srs_error("send PCUC(StreanBegin) message failed. ret=%d", ret);
  860 + return ret;
  861 + }
  862 + srs_info("send PCUC(StreanBegin) message success.");
  863 + }
  864 + }
  865 +
  866 + return ret;
  867 +}
  868 +
  869 +int SrsRtmp::start_fmle_publish(int stream_id)
  870 +{
  871 + int ret = ERROR_SUCCESS;
  872 +
  873 + // FCPublish
  874 + double fc_publish_tid = 0;
  875 + if (true) {
  876 + SrsCommonMessage* msg = NULL;
  877 + SrsFMLEStartPacket* pkt = NULL;
  878 + if ((ret = srs_rtmp_expect_message<SrsFMLEStartPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  879 + srs_error("recv FCPublish message failed. ret=%d", ret);
  880 + return ret;
  881 + }
  882 + srs_info("recv FCPublish request message success.");
  883 +
  884 + SrsAutoFree(SrsCommonMessage, msg, false);
  885 + fc_publish_tid = pkt->transaction_id;
  886 + }
  887 + // FCPublish response
  888 + if (true) {
  889 + SrsCommonMessage* msg = new SrsCommonMessage();
  890 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid);
  891 +
  892 + msg->set_packet(pkt, 0);
  893 +
  894 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  895 + srs_error("send FCPublish response message failed. ret=%d", ret);
  896 + return ret;
  897 + }
  898 + srs_info("send FCPublish response message success.");
  899 + }
  900 +
  901 + // createStream
  902 + double create_stream_tid = 0;
  903 + if (true) {
  904 + SrsCommonMessage* msg = NULL;
  905 + SrsCreateStreamPacket* pkt = NULL;
  906 + if ((ret = srs_rtmp_expect_message<SrsCreateStreamPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  907 + srs_error("recv createStream message failed. ret=%d", ret);
  908 + return ret;
  909 + }
  910 + srs_info("recv createStream request message success.");
  911 +
  912 + SrsAutoFree(SrsCommonMessage, msg, false);
  913 + create_stream_tid = pkt->transaction_id;
  914 + }
  915 + // createStream response
  916 + if (true) {
  917 + SrsCommonMessage* msg = new SrsCommonMessage();
  918 + SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id);
  919 +
  920 + msg->set_packet(pkt, 0);
  921 +
  922 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  923 + srs_error("send createStream response message failed. ret=%d", ret);
  924 + return ret;
  925 + }
  926 + srs_info("send createStream response message success.");
  927 + }
  928 +
  929 + // publish
  930 + if (true) {
  931 + SrsCommonMessage* msg = NULL;
  932 + SrsPublishPacket* pkt = NULL;
  933 + if ((ret = srs_rtmp_expect_message<SrsPublishPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  934 + srs_error("recv publish message failed. ret=%d", ret);
  935 + return ret;
  936 + }
  937 + srs_info("recv publish request message success.");
  938 +
  939 + SrsAutoFree(SrsCommonMessage, msg, false);
  940 + }
  941 + // publish response onFCPublish(NetStream.Publish.Start)
  942 + if (true) {
  943 + SrsCommonMessage* msg = new SrsCommonMessage();
  944 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  945 +
  946 + pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH;
  947 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));
  948 + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));
  949 +
  950 + msg->set_packet(pkt, stream_id);
  951 +
  952 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  953 + srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret);
  954 + return ret;
  955 + }
  956 + srs_info("send onFCPublish(NetStream.Publish.Start) message success.");
  957 + }
  958 + // publish response onStatus(NetStream.Publish.Start)
  959 + if (true) {
  960 + SrsCommonMessage* msg = new SrsCommonMessage();
  961 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  962 +
  963 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  964 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));
  965 + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));
  966 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  967 +
  968 + msg->set_packet(pkt, stream_id);
  969 +
  970 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  971 + srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
  972 + return ret;
  973 + }
  974 + srs_info("send onStatus(NetStream.Publish.Start) message success.");
  975 + }
  976 +
  977 + srs_info("FMLE publish success.");
  978 +
  979 + return ret;
  980 +}
  981 +
  982 +int SrsRtmp::fmle_unpublish(int stream_id, double unpublish_tid)
  983 +{
  984 + int ret = ERROR_SUCCESS;
  985 +
  986 + // publish response onFCUnpublish(NetStream.unpublish.Success)
  987 + if (true) {
  988 + SrsCommonMessage* msg = new SrsCommonMessage();
  989 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  990 +
  991 + pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_UNPUBLISH;
  992 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));
  993 + pkt->data->set(StatusDescription, new SrsAmf0String("Stop publishing stream."));
  994 +
  995 + msg->set_packet(pkt, stream_id);
  996 +
  997 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  998 + srs_error("send onFCUnpublish(NetStream.unpublish.Success) message failed. ret=%d", ret);
  999 + return ret;
  1000 + }
  1001 + srs_info("send onFCUnpublish(NetStream.unpublish.Success) message success.");
  1002 + }
  1003 + // FCUnpublish response
  1004 + if (true) {
  1005 + SrsCommonMessage* msg = new SrsCommonMessage();
  1006 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(unpublish_tid);
  1007 +
  1008 + msg->set_packet(pkt, stream_id);
  1009 +
  1010 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  1011 + srs_error("send FCUnpublish response message failed. ret=%d", ret);
  1012 + return ret;
  1013 + }
  1014 + srs_info("send FCUnpublish response message success.");
  1015 + }
  1016 + // publish response onStatus(NetStream.Unpublish.Success)
  1017 + if (true) {
  1018 + SrsCommonMessage* msg = new SrsCommonMessage();
  1019 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  1020 +
  1021 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  1022 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodeUnpublishSuccess));
  1023 + pkt->data->set(StatusDescription, new SrsAmf0String("Stream is now unpublished"));
  1024 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  1025 +
  1026 + msg->set_packet(pkt, stream_id);
  1027 +
  1028 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  1029 + srs_error("send onStatus(NetStream.Unpublish.Success) message failed. ret=%d", ret);
  1030 + return ret;
  1031 + }
  1032 + srs_info("send onStatus(NetStream.Unpublish.Success) message success.");
  1033 + }
  1034 +
  1035 + srs_info("FMLE unpublish success.");
  1036 +
  1037 + return ret;
  1038 +}
  1039 +
  1040 +int SrsRtmp::start_flash_publish(int stream_id)
  1041 +{
  1042 + int ret = ERROR_SUCCESS;
  1043 +
  1044 + // publish response onStatus(NetStream.Publish.Start)
  1045 + if (true) {
  1046 + SrsCommonMessage* msg = new SrsCommonMessage();
  1047 + SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket();
  1048 +
  1049 + pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus));
  1050 + pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart));
  1051 + pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream."));
  1052 + pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID));
  1053 +
  1054 + msg->set_packet(pkt, stream_id);
  1055 +
  1056 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  1057 + srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret);
  1058 + return ret;
  1059 + }
  1060 + srs_info("send onStatus(NetStream.Publish.Start) message success.");
  1061 + }
  1062 +
  1063 + srs_info("flash publish success.");
  1064 +
  1065 + return ret;
  1066 +}
  1067 +
  1068 +int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, string& stream_name)
  1069 +{
  1070 + int ret = ERROR_SUCCESS;
  1071 +
  1072 + if (true) {
  1073 + SrsCommonMessage* msg = new SrsCommonMessage();
  1074 + SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id);
  1075 +
  1076 + msg->set_packet(pkt, 0);
  1077 +
  1078 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  1079 + srs_error("send createStream response message failed. ret=%d", ret);
  1080 + return ret;
  1081 + }
  1082 + srs_info("send createStream response message success.");
  1083 + }
  1084 +
  1085 + while (true) {
  1086 + SrsCommonMessage* msg = NULL;
  1087 + if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) {
  1088 + srs_error("recv identify client message failed. ret=%d", ret);
  1089 + return ret;
  1090 + }
  1091 +
  1092 + SrsAutoFree(SrsCommonMessage, msg, false);
  1093 +
  1094 + if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) {
  1095 + srs_trace("identify ignore messages except "
  1096 + "AMF0/AMF3 command message. type=%#x", msg->header.message_type);
  1097 + continue;
  1098 + }
  1099 +
  1100 + if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {
  1101 + srs_error("identify decode message failed. ret=%d", ret);
  1102 + return ret;
  1103 + }
  1104 +
  1105 + SrsPacket* pkt = msg->get_packet();
  1106 + if (dynamic_cast<SrsPlayPacket*>(pkt)) {
  1107 + SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt);
  1108 + type = SrsClientPlay;
  1109 + stream_name = play->stream_name;
  1110 + srs_trace("identity client type=play, stream_name=%s", stream_name.c_str());
  1111 + return ret;
  1112 + }
  1113 + if (dynamic_cast<SrsPublishPacket*>(pkt)) {
  1114 + srs_info("identify client by publish, falsh publish.");
  1115 + return identify_flash_publish_client(
  1116 + dynamic_cast<SrsPublishPacket*>(pkt), type, stream_name);
  1117 + }
  1118 +
  1119 + srs_trace("ignore AMF0/AMF3 command message.");
  1120 + }
  1121 +
  1122 + return ret;
  1123 +}
  1124 +
  1125 +int SrsRtmp::identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, string& stream_name)
  1126 +{
  1127 + int ret = ERROR_SUCCESS;
  1128 +
  1129 + type = SrsClientFMLEPublish;
  1130 + stream_name = req->stream_name;
  1131 +
  1132 + // releaseStream response
  1133 + if (true) {
  1134 + SrsCommonMessage* msg = new SrsCommonMessage();
  1135 + SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(req->transaction_id);
  1136 +
  1137 + msg->set_packet(pkt, 0);
  1138 +
  1139 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  1140 + srs_error("send releaseStream response message failed. ret=%d", ret);
  1141 + return ret;
  1142 + }
  1143 + srs_info("send releaseStream response message success.");
  1144 + }
  1145 +
  1146 + return ret;
  1147 +}
  1148 +
  1149 +int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& type, string& stream_name)
  1150 +{
  1151 + int ret = ERROR_SUCCESS;
  1152 +
  1153 + type = SrsClientFlashPublish;
  1154 + stream_name = req->stream_name;
  1155 +
  1156 + return ret;
  1157 +}
  1158 +