[rtmpdump] [PATCH] Handle RTMP redirect

Steven Penny svnpenn at gmail.com
Fri Sep 7 23:53:10 CEST 2012


This patch allows RtmpDump to follow RTMP URL redirects. Before this you could
run rtmpdump --verbose and see the redirect URL

DEBUG: Property: <Name:      redirect, STRING:     rtmp://46.19.140.146:190/vod>

This patch simply automates the following process. Taken from KSV patch file
http://github.com/downloads/K-S-V/Scripts/rtmpdump-2.4.zip
Tested on
http://datastreaming.altervista.org/LA7.html
---
 librtmp/rtmp.c |   48 +++++++++++++++++++++++++++++++++++++++++++++---
 librtmp/rtmp.h |    1 +
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index 52d0254..b76367a 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -2473,12 +2473,54 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
     }
   else if (AVMATCH(&method, &av__error))
     {
-      RTMP_Log(RTMP_LOGERROR, "rtmp server sent error");
+      double code = 0;
+      unsigned int parsedPort;
+      AMFObject obj2;
+      AMFObjectProperty p;
+      AVal redirect;
+      SAVC(ex);
+      SAVC(redirect);
+
+      AMFProp_GetObject(AMF_GetProp(&obj, NULL, 3), &obj2);
+      if (RTMP_FindFirstMatchingProperty(&obj2, &av_ex, &p))
+        {
+          AMFProp_GetObject(&p, &obj2);
+          if (RTMP_FindFirstMatchingProperty(&obj2, &av_code, &p))
+            code = AMFProp_GetNumber(&p);
+          if (code == 302 && RTMP_FindFirstMatchingProperty(&obj2, &av_redirect, &p))
+            {
+              AMFProp_GetString(&p, &redirect);
+              r->Link.redirected = TRUE;
+
+              char *url = malloc(redirect.av_len + sizeof ("/playpath"));
+              strncpy(url, redirect.av_val, redirect.av_len);
+              url[redirect.av_len] = '\0';
+              r->Link.tcUrl.av_val = url;
+              r->Link.tcUrl.av_len = redirect.av_len;
+              strcat(url, "/playpath");
+              RTMP_ParseURL(url, &r->Link.protocol, &r->Link.hostname, &parsedPort, &r->Link.playpath0, &r->Link.app);
+              r->Link.port = parsedPort;
+            }
+        }
+      if (r->Link.redirected)
+        RTMP_Log(RTMP_LOGINFO, "rtmp server sent redirect");
+      else
+        RTMP_Log(RTMP_LOGERROR, "rtmp server sent error");
     }
   else if (AVMATCH(&method, &av_close))
     {
-      RTMP_Log(RTMP_LOGERROR, "rtmp server requested close");
-      RTMP_Close(r);
+      if (r->Link.redirected)
+        {
+          RTMP_Log(RTMP_LOGINFO, "trying to connect with redirected url");
+          RTMP_Close(r);
+          r->Link.redirected = FALSE;
+          RTMP_Connect(r, NULL);
+        }
+      else
+        {
+          RTMP_Log(RTMP_LOGERROR, "rtmp server requested close");
+          RTMP_Close(r);
+        }
     }
   else if (AVMATCH(&method, &av_onStatus))
     {
diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
index 6b2ae5b..36d2bf6 100644
--- a/librtmp/rtmp.h
+++ b/librtmp/rtmp.h
@@ -174,6 +174,7 @@ extern "C"
     int swfAge;
 
     int protocol;
+    int redirected;
     int timeout;		/* connection timeout in seconds */
 
     unsigned short socksport;
-- 
1.7.9



More information about the rtmpdump mailing list