Skip to content

Commit 0067166

Browse files
committed
feat: rtmp reconnect (enhanced rtmp v2)
1 parent 159a8ed commit 0067166

6 files changed

+47
-4
lines changed

librtmp/include/rtmp-internal.h

+7
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ struct rtmp_t
143143
int (*oneof)(void* param, uint32_t stream_id); // EOF event
144144
int (*onping)(void* param, uint32_t stream_id); // send pong
145145
int (*onbandwidth)(void* param); // send window acknowledgement size
146+
147+
// enhanced rtmp v2
148+
// 1. rtmp://foo.mydomain.com:1935/realtimeapp
149+
// 2. rtmp://127.0.0.1/realtimeapp
150+
// 3. //192.0.2.0/realtimeapp
151+
// 4. / realtimeapp
152+
int (*onreconnect)(void* param, const char* tcurl, const char* descritpion);
146153
} client;
147154
};
148155

librtmp/include/rtmp-netstream.h

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ uint8_t* rtmp_netstream_fcsubscribe(uint8_t* out, size_t bytes, double transacti
2222
uint8_t* rtmp_netstream_fcunsubscribe(uint8_t* out, size_t bytes, double transactionId, const char* stream_name);
2323

2424
uint8_t* rtmp_netstream_onstatus(uint8_t* out, size_t bytes, double transactionId, const char* level, const char* code, const char* description);
25+
uint8_t* rtmp_netstream_onreconnect(uint8_t* out, size_t bytes, double transactionId, const char* tcurl, const char* description);
2526

2627
uint8_t* rtmp_netstream_rtmpsampleaccess(uint8_t* out, size_t bytes);
2728

librtmp/include/rtmp-server.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ extern "C" {
1010

1111
#define RTMP_SERVER_ASYNC_START 0x12345678 // magic number, user call rtmp_server_start
1212

13+
#define RTMP_SERVER_START_RECONNECT 1 // use with RTMP_SERVER_ASYNC_START
14+
1315
typedef struct rtmp_server_t rtmp_server_t;
1416

1517
struct rtmp_server_handler_t
@@ -69,8 +71,8 @@ int rtmp_server_send_video(rtmp_server_t* rtmp, const void* data, size_t bytes,
6971
int rtmp_server_send_script(rtmp_server_t* rtmp, const void* data, size_t bytes, uint32_t timestamp);
7072

7173
/// [OPTIONAL] must call on onplay/onpublish return RTMP_SERVER_ASYNC_START
72-
/// @param[in] code 0-ok, other-error
73-
/// @param[in] msg error message
74+
/// @param[in] code 0-ok, RTMP_SERVER_START_RECONNECT-reconnect, other-error
75+
/// @param[in] msg error message, or tcurl if code == RTMP_SERVER_START_RECONNECT
7476
/// @return 0-ok, other-error
7577
int rtmp_server_start(rtmp_server_t* rtmp, int code, const char* msg);
7678

librtmp/source/rtmp-client-invoke-handler.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ struct rtmp_result_t
2525
// "NetConnection.Connect.InvalidApp",
2626
// "NetConnection.Connect.Rejected",
2727
//
28+
// "NetConnection.Connect.ReconnectRequest" // enhanced rtmp v2
29+
//
2830
// "NetStream.Failed",
2931
// "NetStream.Play.Failed",
3032
// "NetStream.Play.StreamNotFound",
@@ -143,13 +145,15 @@ static int rtmp_command_onerror(struct rtmp_t* rtmp, double transaction, const u
143145
// s -> c
144146
static int rtmp_command_onstatus(struct rtmp_t* rtmp, double transaction, const uint8_t* data, uint32_t bytes)
145147
{
148+
char tcurl[256];
146149
struct rtmp_result_t result;
147-
struct amf_object_item_t info[3];
150+
struct amf_object_item_t info[4];
148151
struct amf_object_item_t items[2];
149152

150153
AMF_OBJECT_ITEM_VALUE(info[0], AMF_STRING, "code", result.code, sizeof(result.code));
151154
AMF_OBJECT_ITEM_VALUE(info[1], AMF_STRING, "level", result.level, sizeof(result.level));
152155
AMF_OBJECT_ITEM_VALUE(info[2], AMF_STRING, "description", result.description, sizeof(result.description));
156+
AMF_OBJECT_ITEM_VALUE(info[3], AMF_STRING, "tcUrl", tcurl, sizeof(tcurl));
153157

154158
AMF_OBJECT_ITEM_VALUE(items[0], AMF_OBJECT, "command", NULL, 0); // Command object
155159
AMF_OBJECT_ITEM_VALUE(items[1], AMF_OBJECT, "information", info, sizeof(info) / sizeof(info[0])); // Information object
@@ -214,6 +218,11 @@ static int rtmp_command_onstatus(struct rtmp_t* rtmp, double transaction, const
214218
//rtmp->onerror(rtmp->param, -1, result.code);
215219
return -1;
216220
}
221+
else if (0 == strcasecmp(result.code, "NetConnection.Connect.ReconnectRequest"))
222+
{
223+
// enhanced rtmp v2
224+
rtmp->client.onreconnect ? rtmp->client.onreconnect(rtmp->param, tcurl, result.description) : 0;
225+
}
217226
else
218227
{
219228
assert(0);

librtmp/source/rtmp-netstream.c

+19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "rtmp-netstream.h"
2+
#include "rtmp-internal.h"
23
#include "amf0.h"
34
#include <stdlib.h>
45
#include <string.h>
@@ -225,6 +226,24 @@ uint8_t* rtmp_netstream_onstatus(uint8_t* out, size_t bytes, double transactionI
225226
return out;
226227
}
227228

229+
uint8_t* rtmp_netstream_onreconnect(uint8_t* out, size_t bytes, double transactionId, const char* tcurl, const char* description)
230+
{
231+
uint8_t* end = out + bytes;
232+
const char* command = "onStatus";
233+
234+
out = AMFWriteString(out, end, command, strlen(command)); // Command Name
235+
out = AMFWriteDouble(out, end, transactionId); // Transaction ID
236+
out = AMFWriteNull(out, end); // command object
237+
238+
out = AMFWriteObject(out, end);
239+
out = AMFWriteNamedString(out, end, "level", 5, RTMP_LEVEL_STATUS, strlen(RTMP_LEVEL_STATUS));
240+
out = AMFWriteNamedString(out, end, "code", 4, "NetConnection.Connect.ReconnectRequest", 39);
241+
out = AMFWriteNamedString(out, end, "description", 11, description?description:"", strlen(description ? description : ""));
242+
out = AMFWriteNamedString(out, end, "tcUrl", 5, tcurl?tcurl:"", strlen(tcurl ? tcurl : ""));
243+
out = AMFWriteObjectEnd(out, end);
244+
return out;
245+
}
246+
228247
uint8_t* rtmp_netstream_rtmpsampleaccess(uint8_t* out, size_t bytes)
229248
{
230249
uint8_t* end = out + bytes;

librtmp/source/rtmp-server.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,12 @@ int rtmp_server_input(struct rtmp_server_t* ctx, const uint8_t* data, size_t byt
528528

529529
int rtmp_server_start(rtmp_server_t* rtmp, int r, const char* msg)
530530
{
531-
if (RTMP_SERVER_ONPLAY == rtmp->start.play)
531+
if (RTMP_SERVER_START_RECONNECT == r)
532+
{
533+
r = (int)(rtmp_netstream_onreconnect(rtmp->payload, sizeof(rtmp->payload), 0, msg, "") - rtmp->payload);
534+
r = rtmp_server_send_control(&rtmp->rtmp, rtmp->payload, r, rtmp->stream_id);
535+
}
536+
else if (RTMP_SERVER_ONPLAY == rtmp->start.play)
532537
{
533538
if (0 == r)
534539
{

0 commit comments

Comments
 (0)