]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Making mod_rtmp compatible with Adobe Media Server
authorPaul Cuttler <paulcuttler@gmail.com>
Thu, 13 Aug 2015 20:06:43 +0000 (06:06 +1000)
committerPaul Cuttler <paulcuttler@gmail.com>
Thu, 13 Aug 2015 20:06:43 +0000 (06:06 +1000)
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
src/mod/endpoints/mod_rtmp/mod_rtmp.h
src/mod/endpoints/mod_rtmp/rtmp_sig.c

index d4e0c218c92f9ce2816cd9c72c8e5bfd1b3f3a64..4b060d270055275a9cc3e99d1e33b737867fd986 100644 (file)
@@ -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);
index 8c398d76d7a787ea6e73e631b6e8f56a0da1f672..d75410c3159e2eee7c52c83d48542c06c36d1a0f 100644 (file)
@@ -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);
index a526d8e1ea517b98abcf07a70420b1043ef63739..711d368736db5c9f2d5dda8689f409cb2a0c2b55 100644 (file)
@@ -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);