From: Paul Cuttler Date: Thu, 13 Aug 2015 20:06:43 +0000 (+1000) Subject: Making mod_rtmp compatible with Adobe Media Server X-Git-Tag: v1.6.4~1^2~33^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=53c37d23859357a7ab0727a34a4f640ad86a0e4e;p=thirdparty%2Ffreeswitch.git Making mod_rtmp compatible with Adobe Media Server Adobe Media Server connects differently to mod_rtmp than the way Flash player connects. The RTMP publish handler rtmp_i_publish message needs to match the RTMP specification, and a new initStream handler is required. This patch modifies the rtmp_i_publish handler to send an onStatus message to Adobe Media Server that includes an object with "level", "code" and "description" fields. The initStream message is sent by Adobe Media Server to notify Freeswitch of the stream ID for the publish stream. This cannot clash with the play stream ID so the initStream handler can simply increment the next_streamid field. The initStream message is undocumented in the RTMP specification. The transaction ID for onStatus messages has been modified to 0 instead of 1 to match with the RTMP specification. FS-7924 #resolve --- diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.c b/src/mod/endpoints/mod_rtmp/mod_rtmp.c index d4e0c218c9..4b060d2700 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.c +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.c @@ -1990,6 +1990,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rtmp_load) rtmp_register_invoke_function("connect", rtmp_i_connect); rtmp_register_invoke_function("createStream", rtmp_i_createStream); + rtmp_register_invoke_function("initStream", rtmp_i_initStream); rtmp_register_invoke_function("closeStream", rtmp_i_noop); rtmp_register_invoke_function("deleteStream", rtmp_i_noop); rtmp_register_invoke_function("play", rtmp_i_play); diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.h b/src/mod/endpoints/mod_rtmp/mod_rtmp.h index 8c398d76d7..d75410c315 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.h +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.h @@ -596,6 +596,7 @@ typedef enum { /* Invokable functions from flash */ RTMP_INVOKE_FUNCTION(rtmp_i_connect); RTMP_INVOKE_FUNCTION(rtmp_i_createStream); +RTMP_INVOKE_FUNCTION(rtmp_i_initStream); RTMP_INVOKE_FUNCTION(rtmp_i_noop); RTMP_INVOKE_FUNCTION(rtmp_i_play); RTMP_INVOKE_FUNCTION(rtmp_i_publish); diff --git a/src/mod/endpoints/mod_rtmp/rtmp_sig.c b/src/mod/endpoints/mod_rtmp/rtmp_sig.c index a526d8e1ea..711d368736 100644 --- a/src/mod/endpoints/mod_rtmp/rtmp_sig.c +++ b/src/mod/endpoints/mod_rtmp/rtmp_sig.c @@ -126,6 +126,15 @@ RTMP_INVOKE_FUNCTION(rtmp_i_connect) RTMP_INVOKE_FUNCTION(rtmp_i_createStream) +{ + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Replied to createStream (%u)\n", amf0_get_number(argv[1])); + + rsession->next_streamid++; + + return SWITCH_STATUS_SUCCESS; +} + +RTMP_INVOKE_FUNCTION(rtmp_i_initStream) { rtmp_send_invoke_free(rsession, amfnumber, 0, 0, amf0_str("_result"), @@ -134,7 +143,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_createStream) amf0_number_new(rsession->next_streamid), NULL); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Replied to createStream (%u)\n", rsession->next_streamid); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Received initStream (%u)\n", rsession->next_streamid); rsession->next_streamid++; @@ -222,7 +231,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_play) rtmp_send_invoke_free(rsession, RTMP_DEFAULT_STREAM_NOTIFY, 0, rsession->media_streamid, amf0_str("onStatus"), - amf0_number_new(1), + amf0_number_new(0), amf0_null_new(), object, NULL); @@ -236,7 +245,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_play) rtmp_send_invoke_free(rsession, RTMP_DEFAULT_STREAM_NOTIFY, 0, rsession->media_streamid, amf0_str("onStatus"), - amf0_number_new(1), + amf0_number_new(0), amf0_null_new(), object, NULL); @@ -256,6 +265,7 @@ RTMP_INVOKE_FUNCTION(rtmp_i_play) RTMP_INVOKE_FUNCTION(rtmp_i_publish) { + amf0_data *object = amf0_object_new(); unsigned char buf[] = { INT16(RTMP_CTRL_STREAM_BEGIN), @@ -264,12 +274,17 @@ RTMP_INVOKE_FUNCTION(rtmp_i_publish) rtmp_send_message(rsession, 2, 0, RTMP_TYPE_USERCTRL, 0, buf, sizeof(buf), 0); - rtmp_send_invoke_free(rsession, amfnumber, 0, 0, - amf0_str("_result"), - amf0_number_new(transaction_id), - amf0_null_new(), + amf0_object_add(object, "level", amf0_str("status")); + amf0_object_add(object, "code", amf0_str("NetStream.Publish.Start")); + amf0_object_add(object, "description", amf0_str("description")); + amf0_object_add(object, "details", amf0_str("details")); + amf0_object_add(object, "clientid", amf0_number_new(217834719)); + + rtmp_send_invoke_free(rsession, RTMP_DEFAULT_STREAM_NOTIFY, 0, state->stream_id, + amf0_str("onStatus"), + amf0_number_new(0), amf0_null_new(), - NULL); + object, NULL); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Got publish on stream %u.\n", state->stream_id);