aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>2012-08-07 21:51:46 +0200
committerMartin Storsjö <martin@martin.st>2012-08-07 23:35:39 +0300
commitf9e77c1762c6904828550326dbbb2b36905eca1a (patch)
treedae723951c7f9ebbf1beb761f5d36abf0389f5ee
parent12127b65b095d36f528ac477e1c995d1b3742852 (diff)
downloadffmpeg-f9e77c1762c6904828550326dbbb2b36905eca1a.tar.gz
rtmp: Add support for subscribing live streams
When streaming live streams using the Akamai, Edgecast or Limelight CDN, players cannot simply connect to the live stream. Instead, they have to subscribe to it, by sending an FC Subscribe call to the server. Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r--libavformat/rtmpproto.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 1a6b5c1903..d21ffead7f 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -604,6 +604,29 @@ static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
return ret;
}
+static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt)
+{
+ RTMPPacket pkt;
+ uint8_t *p;
+ int ret;
+
+ if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
+ 0, 27 + strlen(rt->playpath))) < 0)
+ return ret;
+
+ p = pkt.data;
+ ff_amf_write_string(&p, "FCSubscribe");
+ ff_amf_write_number(&p, ++rt->nb_invokes);
+ ff_amf_write_null(&p);
+ ff_amf_write_string(&p, rt->playpath);
+
+ ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
+ rt->prev_pkt[1]);
+ ff_rtmp_packet_destroy(&pkt);
+
+ return ret;
+}
+
int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
const uint8_t *key, int keylen, uint8_t *dst)
{
@@ -1011,6 +1034,14 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt)
}
if ((ret = gen_create_stream(s, rt)) < 0)
return ret;
+
+ if (rt->is_input) {
+ /* Send the FCSubscribe command if live stream. */
+ if (rt->live == -1) {
+ if ((ret = gen_fcsubscribe_stream(s, rt)) < 0)
+ return ret;
+ }
+ }
break;
case STATE_FCPUBLISH:
rt->state = STATE_CONNECTING;