This token sent to the server using a NetStream.Authenticate.UserToken
invoke call is required for strict servers like Justin.tv.
---
doc/protocols.texi | 3 +++
libavformat/rtmpproto.c | 31 +++++++++++++++++++++++++++++++
libavformat/version.h | 2 +-
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/doc/protocols.texi b/doc/protocols.texi
index bf67d89..89ef204 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -248,6 +248,9 @@ URL of the SWF player for the media. By default no value
will be sent.
@item rtmp_tcurl
URL of the target stream. Defaults to proto://host[:port]/app.
+@item rtmp_usher_token
+Authentication token for strict servers like Justin.tv.
+
@end table
For example to read with @command{avplay} a multimedia resource named
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 1db3152..6397869 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -101,6 +101,7 @@ typedef struct RTMPContext {
TrackedMethod*tracked_methods; ///< tracked methods buffer
int nb_tracked_methods; ///< number of tracked methods
int tracked_methods_size; ///< size of the tracked methods
buffer
+ char* usher_token; ///< authentication token for
strict servers like Justin.tv
} RTMPContext;
#define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for
first client digest signing
@@ -651,6 +652,28 @@ static int gen_bytes_read(URLContext *s, RTMPContext *rt,
uint32_t ts)
return rtmp_send_packet(rt, &pkt, 0);
}
+/**
+ * Generate usher token message and send it to the server.
+ */
+static int gen_usher_token(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, 49 + strlen(rt->usher_token))) < 0)
+ return ret;
+
+ p = pkt.data;
+ ff_amf_write_string(&p, "NetStream.Authenticate.UsherToken");
+ ff_amf_write_number(&p, ++rt->nb_invokes);
+ ff_amf_write_null(&p);
+ ff_amf_write_string(&p, rt->usher_token);
+
+ return rtmp_send_packet(rt, &pkt, 0);
+}
+
static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
const char *subscribe)
{
@@ -1096,6 +1119,13 @@ static int handle_invoke_result(URLContext *s,
RTMPPacket *pkt)
goto fail;
if (rt->is_input) {
+ if (rt->usher_token) {
+ /* Send the authentification token for strict servers
+ * like Justin.tv. */
+ if ((ret = gen_usher_token(s, rt)) < 0)
+ goto fail;
+ }
+
/* Send the FCSubscribe command when the name of live
* stream is defined by the user or if it's a live stream. */
if (rt->subscribe) {
@@ -1707,6 +1737,7 @@ static const AVOption rtmp_options[] = {
{"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to
rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,
DEC},
{"rtmp_swfurl", "URL of the SWF player. By default no value will be sent",
OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
{"rtmp_tcurl", "URL of the target stream. Defaults to
proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL },
0, 0, DEC|ENC},
+ {"rtmp_usher_token", "Authentication token for strict servers like
Justin.tv.", OFFSET(usher_token), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0,
DEC},
{ NULL },
};
diff --git a/libavformat/version.h b/libavformat/version.h
index e2cd0c7..54185fa 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 54
#define LIBAVFORMAT_VERSION_MINOR 13
-#define LIBAVFORMAT_VERSION_MICRO 2
+#define LIBAVFORMAT_VERSION_MICRO 3
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \
--
1.7.11.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel