From 53c37d23859357a7ab0727a34a4f640ad86a0e4e Mon Sep 17 00:00:00 2001 From: Paul Cuttler Date: Fri, 14 Aug 2015 06:06:43 +1000 Subject: [PATCH 1/2] 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 --- src/mod/endpoints/mod_rtmp/mod_rtmp.c | 1 + src/mod/endpoints/mod_rtmp/mod_rtmp.h | 1 + src/mod/endpoints/mod_rtmp/rtmp_sig.c | 31 ++++++++++++++++++++------- 3 files changed, 25 insertions(+), 8 deletions(-) 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_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(), - 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); From 86d849c54e26951e313d1dcb4b220055f79aacc0 Mon Sep 17 00:00:00 2001 From: Paul Cuttler Date: Wed, 7 Oct 2015 14:50:27 +1100 Subject: [PATCH 2/2] FS-7924: [mod_rtmp] Modify initStream & createStream responses Moved the response message mistakenly placed in the initStream handler to the createStream handler --- src/mod/endpoints/mod_rtmp/rtmp_sig.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mod/endpoints/mod_rtmp/rtmp_sig.c b/src/mod/endpoints/mod_rtmp/rtmp_sig.c index 711d368736..c319fc7881 100644 --- a/src/mod/endpoints/mod_rtmp/rtmp_sig.c +++ b/src/mod/endpoints/mod_rtmp/rtmp_sig.c @@ -127,6 +127,13 @@ RTMP_INVOKE_FUNCTION(rtmp_i_connect) RTMP_INVOKE_FUNCTION(rtmp_i_createStream) { + rtmp_send_invoke_free(rsession, amfnumber, 0, 0, + amf0_str("_result"), + amf0_number_new(transaction_id), + amf0_null_new(), + amf0_number_new(rsession->next_streamid), + NULL); + 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++; @@ -136,13 +143,6 @@ RTMP_INVOKE_FUNCTION(rtmp_i_createStream) RTMP_INVOKE_FUNCTION(rtmp_i_initStream) { - rtmp_send_invoke_free(rsession, amfnumber, 0, 0, - amf0_str("_result"), - amf0_number_new(transaction_id), - amf0_null_new(), - amf0_number_new(rsession->next_streamid), - NULL); - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rsession->uuid), SWITCH_LOG_INFO, "Received initStream (%u)\n", rsession->next_streamid); rsession->next_streamid++;