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
This commit is contained in:
parent
6813d6647b
commit
53c37d2385
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue