Add support for set_playlist command
authorhyc <hyc@400ebc74-4327-4243-bc38-086b20814532>
Sat, 24 Apr 2010 12:04:34 +0000 (12:04 +0000)
committerhyc <hyc@400ebc74-4327-4243-bc38-086b20814532>
Sat, 24 Apr 2010 12:04:34 +0000 (12:04 +0000)
git-svn-id: svn://svn.mplayerhq.hu/rtmpdump/trunk@448 400ebc74-4327-4243-bc38-086b20814532

librtmp/rtmp.c
librtmp/rtmp.h
rtmpdump.c

index 0bebca4..070c42e 100644 (file)
@@ -447,6 +447,8 @@ static struct urlopt {
        "Append arbitrary AMF data to Connect message" },
   { AVC("playpath"),  OFF(Link.playpath),      OPT_STR, 0,
        "Path to target media on server" },
+  { AVC("playlist"),  OFF(Link.lFlags),        OPT_BOOL, RTMP_LF_PLST,
+       "Set playlist before play command" },
   { AVC("live"),      OFF(Link.lFlags),        OPT_BOOL, RTMP_LF_LIVE,
        "Stream is live, no seeking possible" },
   { AVC("subscribe"), OFF(Link.subscribepath), OPT_STR, 0,
@@ -1977,6 +1979,47 @@ SendPlay(RTMP *r)
   return RTMP_SendPacket(r, &packet, true);
 }
 
+SAVC(set_playlist);
+SAVC(0);
+
+static bool
+SendPlaylist(RTMP *r)
+{
+  RTMPPacket packet;
+  char pbuf[1024], *pend = pbuf + sizeof(pbuf);
+  char *enc;
+
+  packet.m_nChannel = 0x08;    /* we make 8 our stream channel */
+  packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
+  packet.m_packetType = 0x14;  /* INVOKE */
+  packet.m_nTimeStamp = 0;
+  packet.m_nInfoField2 = r->m_stream_id;       /*0x01000000; */
+  packet.m_hasAbsTimestamp = 0;
+  packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
+
+  enc = packet.m_body;
+  enc = AMF_EncodeString(enc, pend, &av_set_playlist);
+  enc = AMF_EncodeNumber(enc, pend, 0);
+  *enc++ = AMF_NULL;
+  *enc++ = AMF_ECMA_ARRAY;
+  *enc++ = 0;
+  *enc++ = 0;
+  *enc++ = 0;
+  *enc++ = AMF_OBJECT;
+  enc = AMF_EncodeNamedString(enc, pend, &av_0, &r->Link.playpath);
+  if (!enc)
+    return false;
+  if (enc + 3 >= pend)
+    return false;
+  *enc++ = 0;
+  *enc++ = 0;
+  *enc++ = AMF_OBJECT_END;
+
+  packet.m_nBodySize = enc - packet.m_body;
+
+  return RTMP_SendPacket(r, &packet, true);
+}
+
 static bool
 SendSecureTokenResponse(RTMP *r, AVal *resp)
 {
@@ -2127,6 +2170,7 @@ SAVC(close);
 SAVC(code);
 SAVC(level);
 SAVC(onStatus);
+SAVC(playlist_ready);
 static const AVal av_NetStream_Failed = AVC("NetStream.Failed");
 static const AVal av_NetStream_Play_Failed = AVC("NetStream.Play.Failed");
 static const AVal av_NetStream_Play_StreamNotFound =
@@ -2219,6 +2263,8 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
            }
          else
            {
+             if (r->Link.lFlags & RTMP_LF_PLST)
+               SendPlaylist(r);
              SendPlay(r);
              RTMP_SendCtrl(r, 3, r->m_stream_id, r->m_nBufferMS);
            }
@@ -2336,6 +2382,18 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
          }
        }
     }
+  else if (AVMATCH(&method, &av_playlist_ready))
+    {
+      int i;
+      for (i = 0; i < r->m_numCalls; i++)
+        {
+          if (AVMATCH(&r->m_methodCalls[i], &av_set_playlist))
+           {
+             AV_erase(r->m_methodCalls, &r->m_numCalls, i, true);
+             break;
+           }
+        }
+    }
   else
     {
 
index 0dfc01c..ef65cdb 100644 (file)
@@ -145,11 +145,7 @@ extern "C"
 #define RTMP_LF_SWFV   0x0004
 #define RTMP_LF_PLST   0x0008
     int lFlags;
-#if 0
-    bool authflag;
-    bool bLiveStream;
-    bool swfVfy;
-#endif
+
     int swfAge;
 
     int protocol;
index d230b4e..5e9972d 100644 (file)
@@ -125,6 +125,8 @@ static const AVal av_onMetaData = AVC("onMetaData");
 static const AVal av_duration = AVC("duration");
 static const AVal av_conn = AVC("conn");
 static const AVal av_token = AVC("token");
+static const AVal av_playlist = AVC("playlist");
+static const AVal av_true = AVC("true");
 
 int
 OpenResumeFile(const char *flvFile,    // file name [in]
@@ -640,9 +642,11 @@ void usage(char *prog)
          RTMP_LogPrintf
            ("--socks|-S host:port    Use the specified SOCKS proxy\n");
          RTMP_LogPrintf
-           ("--protocol|-l           Overrides the protocol in the rtmp url (0 - RTMP, 2 - RTMPE)\n");
+           ("--protocol|-l num       Overrides the protocol in the rtmp url (0 - RTMP, 2 - RTMPE)\n");
          RTMP_LogPrintf
-           ("--playpath|-y           Overrides the playpath parsed from rtmp url\n");
+           ("--playpath|-y path      Overrides the playpath parsed from rtmp url\n");
+         RTMP_LogPrintf
+           ("--playlist|-Y           Set playlist before playing\n");
          RTMP_LogPrintf("--swfUrl|-s url         URL to player swf file\n");
          RTMP_LogPrintf
            ("--tcUrl|-t url          URL to played stream (default: \"rtmp://host[:port]/app\")\n");
@@ -805,6 +809,7 @@ main(int argc, char **argv)
     {"socks", 1, NULL, 'S'},
     {"protocol", 1, NULL, 'l'},
     {"playpath", 1, NULL, 'y'},
+    {"playlist", 0, NULL, 'Y'},
     {"rtmp", 1, NULL, 'r'},
     {"swfUrl", 1, NULL, 's'},
     {"tcUrl", 1, NULL, 't'},
@@ -838,7 +843,7 @@ main(int argc, char **argv)
 
   while ((opt =
          getopt_long(argc, argv,
-                     "hVveqzr:s:t:p:a:b:f:o:u:C:n:c:l:y:m:k:d:A:B:T:w:x:W:X:S:#",
+                     "hVveqzr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#",
                      longopts, NULL)) != -1)
     {
       switch (opt)
@@ -943,6 +948,9 @@ main(int argc, char **argv)
        case 'y':
          STR2AVAL(playpath, optarg);
          break;
+       case 'Y':
+         RTMP_SetOpt(&rtmp, &av_playlist, (AVal *)&av_true);
+         break;
        case 'r':
          {
            AVal parsedHost, parsedApp, parsedPlaypath;