2 * RTMP network protocol
3 * Copyright (c) 2009 Kostya Shishkov
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "libavcodec/bytestream.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/base64.h"
30 #include "libavutil/intfloat.h"
31 #include "libavutil/lfg.h"
32 #include "libavutil/md5.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/random_seed.h"
35 #include "libavutil/sha.h"
43 #include "rtmpcrypt.h"
51 #define APP_MAX_LENGTH 1024
52 #define PLAYPATH_MAX_LENGTH 256
53 #define TCURL_MAX_LENGTH 512
54 #define FLASHVER_MAX_LENGTH 64
55 #define RTMP_PKTDATA_DEFAULT_SIZE 4096
57 /** RTMP protocol handler state */
59 STATE_START, ///< client has not done anything yet
60 STATE_HANDSHAKED, ///< client has performed handshake
61 STATE_FCPUBLISH, ///< client FCPublishing stream (for output)
62 STATE_PLAYING, ///< client has started receiving multimedia data from server
63 STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
64 STATE_RECEIVING, ///< received a publish command (for input)
65 STATE_STOPPED, ///< the broadcast has been stopped
68 typedef struct TrackedMethod {
73 /** protocol handler context */
74 typedef struct RTMPContext {
76 URLContext* stream; ///< TCP stream used in interactions with RTMP server
77 RTMPPacket prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets
78 int in_chunk_size; ///< size of the chunks incoming RTMP packets are divided into
79 int out_chunk_size; ///< size of the chunks outgoing RTMP packets are divided into
80 int is_input; ///< input/output flag
81 char *playpath; ///< stream identifier to play (with possible "mp4:" prefix)
82 int live; ///< 0: recorded, -1: live, -2: both
83 char *app; ///< name of application
84 char *conn; ///< append arbitrary AMF data to the Connect message
85 ClientState state; ///< current state
86 int main_channel_id; ///< an additional channel ID which is used for some invocations
87 uint8_t* flv_data; ///< buffer with data for demuxer
88 int flv_size; ///< current buffer size
89 int flv_off; ///< number of bytes read from current buffer
90 int flv_nb_packets; ///< number of flv packets published
91 RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output)
92 uint32_t client_report_size; ///< number of bytes after which client should report to server
93 uint32_t bytes_read; ///< number of bytes read from server
94 uint32_t last_bytes_read; ///< number of bytes read last reported to server
95 int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call
96 uint8_t flv_header[11]; ///< partial incoming flv packet header
97 int flv_header_bytes; ///< number of initialized bytes in flv_header
98 int nb_invokes; ///< keeps track of invoke messages
99 char* tcurl; ///< url of the target stream
100 char* flashver; ///< version of the flash plugin
101 char* swfhash; ///< SHA256 hash of the decompressed SWF file (32 bytes)
102 int swfhash_len; ///< length of the SHA256 hash
103 int swfsize; ///< size of the decompressed SWF file
104 char* swfurl; ///< url of the swf player
105 char* swfverify; ///< URL to player swf file, compute hash/size automatically
106 char swfverification[42]; ///< hash of the SWF verification
107 char* pageurl; ///< url of the web page
108 char* subscribe; ///< name of live stream to subscribe
109 int server_bw; ///< server bandwidth
110 int client_buffer_time; ///< client buffer time in ms
111 int flush_interval; ///< number of packets flushed in the same request (RTMPT only)
112 int encrypted; ///< use an encrypted connection (RTMPE only)
113 TrackedMethod*tracked_methods; ///< tracked methods buffer
114 int nb_tracked_methods; ///< number of tracked methods
115 int tracked_methods_size; ///< size of the tracked methods buffer
116 int listen; ///< listen mode flag
117 int listen_timeout; ///< listen timeout to wait for new connections
118 int nb_streamid; ///< The next stream id to return on createStream calls
121 char auth_params[500];
126 #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
127 /** Client key used for digest signing */
128 static const uint8_t rtmp_player_key[] = {
129 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
130 'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
132 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
133 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
134 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
137 #define SERVER_KEY_OPEN_PART_LEN 36 ///< length of partial key used for first server digest signing
138 /** Key used for RTMP server digest signing */
139 static const uint8_t rtmp_server_key[] = {
140 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
141 'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
142 'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
144 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
145 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
146 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
149 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
153 if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
154 rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
155 ptr = av_realloc(rt->tracked_methods,
156 rt->tracked_methods_size * sizeof(*rt->tracked_methods));
158 return AVERROR(ENOMEM);
159 rt->tracked_methods = ptr;
162 rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
163 if (!rt->tracked_methods[rt->nb_tracked_methods].name)
164 return AVERROR(ENOMEM);
165 rt->tracked_methods[rt->nb_tracked_methods].id = id;
166 rt->nb_tracked_methods++;
171 static void del_tracked_method(RTMPContext *rt, int index)
173 memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
174 sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
175 rt->nb_tracked_methods--;
178 static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
179 char **tracked_method)
181 RTMPContext *rt = s->priv_data;
187 bytestream2_init(&gbc, pkt->data + offset, pkt->data_size - offset);
188 if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
191 for (i = 0; i < rt->nb_tracked_methods; i++) {
192 if (rt->tracked_methods[i].id != pkt_id)
195 *tracked_method = rt->tracked_methods[i].name;
196 del_tracked_method(rt, i);
203 static void free_tracked_methods(RTMPContext *rt)
207 for (i = 0; i < rt->nb_tracked_methods; i ++)
208 av_free(rt->tracked_methods[i].name);
209 av_free(rt->tracked_methods);
210 rt->tracked_methods = NULL;
211 rt->tracked_methods_size = 0;
212 rt->nb_tracked_methods = 0;
215 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
219 if (pkt->type == RTMP_PT_INVOKE && track) {
225 bytestream2_init(&gbc, pkt->data, pkt->data_size);
226 if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
229 if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
232 if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
236 ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
239 ff_rtmp_packet_destroy(pkt);
243 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
248 /* The type must be B for Boolean, N for number, S for string, O for
249 * object, or Z for null. For Booleans the data must be either 0 or 1 for
250 * FALSE or TRUE, respectively. Likewise for Objects the data must be
251 * 0 or 1 to end or begin an object, respectively. Data items in subobjects
252 * may be named, by prefixing the type with 'N' and specifying the name
253 * before the value (ie. NB:myFlag:1). This option may be used multiple times
254 * to construct arbitrary AMF sequences. */
255 if (param[0] && param[1] == ':') {
258 } else if (param[0] == 'N' && param[1] && param[2] == ':') {
261 value = strchr(field, ':');
267 ff_amf_write_field_name(p, field);
274 ff_amf_write_bool(p, value[0] != '0');
277 ff_amf_write_string(p, value);
280 ff_amf_write_number(p, strtod(value, NULL));
283 ff_amf_write_null(p);
287 ff_amf_write_object_start(p);
289 ff_amf_write_object_end(p);
299 av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
300 return AVERROR(EINVAL);
304 * Generate 'connect' call and send it to the server.
306 static int gen_connect(URLContext *s, RTMPContext *rt)
312 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
313 0, 4096 + APP_MAX_LENGTH)) < 0)
318 ff_amf_write_string(&p, "connect");
319 ff_amf_write_number(&p, ++rt->nb_invokes);
320 ff_amf_write_object_start(&p);
321 ff_amf_write_field_name(&p, "app");
322 ff_amf_write_string2(&p, rt->app, rt->auth_params);
325 ff_amf_write_field_name(&p, "type");
326 ff_amf_write_string(&p, "nonprivate");
328 ff_amf_write_field_name(&p, "flashVer");
329 ff_amf_write_string(&p, rt->flashver);
332 ff_amf_write_field_name(&p, "swfUrl");
333 ff_amf_write_string(&p, rt->swfurl);
336 ff_amf_write_field_name(&p, "tcUrl");
337 ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
339 ff_amf_write_field_name(&p, "fpad");
340 ff_amf_write_bool(&p, 0);
341 ff_amf_write_field_name(&p, "capabilities");
342 ff_amf_write_number(&p, 15.0);
344 /* Tell the server we support all the audio codecs except
345 * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
346 * which are unused in the RTMP protocol implementation. */
347 ff_amf_write_field_name(&p, "audioCodecs");
348 ff_amf_write_number(&p, 4071.0);
349 ff_amf_write_field_name(&p, "videoCodecs");
350 ff_amf_write_number(&p, 252.0);
351 ff_amf_write_field_name(&p, "videoFunction");
352 ff_amf_write_number(&p, 1.0);
355 ff_amf_write_field_name(&p, "pageUrl");
356 ff_amf_write_string(&p, rt->pageurl);
359 ff_amf_write_object_end(&p);
362 char *param = rt->conn;
364 // Write arbitrary AMF data to the Connect message.
365 while (param != NULL) {
367 param += strspn(param, " ");
370 sep = strchr(param, ' ');
373 if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
374 // Invalid AMF parameter.
375 ff_rtmp_packet_destroy(&pkt);
386 pkt.data_size = p - pkt.data;
388 return rtmp_send_packet(rt, &pkt, 1);
391 static int read_connect(URLContext *s, RTMPContext *rt)
393 RTMPPacket pkt = { 0 };
403 if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
404 rt->prev_pkt[1])) < 0)
407 bytestream2_init(&gbc, cp, pkt.data_size);
408 if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
409 av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
410 ff_rtmp_packet_destroy(&pkt);
411 return AVERROR_INVALIDDATA;
413 if (strcmp(command, "connect")) {
414 av_log(s, AV_LOG_ERROR, "Expecting connect, got %s\n", command);
415 ff_rtmp_packet_destroy(&pkt);
416 return AVERROR_INVALIDDATA;
418 ret = ff_amf_read_number(&gbc, &seqnum);
420 av_log(s, AV_LOG_WARNING, "SeqNum not found\n");
421 /* Here one could parse an AMF Object with data as flashVers and others. */
422 ret = ff_amf_get_field_value(gbc.buffer,
423 gbc.buffer + bytestream2_get_bytes_left(&gbc),
424 "app", tmpstr, sizeof(tmpstr));
426 av_log(s, AV_LOG_WARNING, "App field not found in connect\n");
427 if (!ret && strcmp(tmpstr, rt->app))
428 av_log(s, AV_LOG_WARNING, "App field don't match up: %s <-> %s\n",
430 ff_rtmp_packet_destroy(&pkt);
432 // Send Window Acknowledgement Size (as defined in speficication)
433 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
434 RTMP_PT_SERVER_BW, 0, 4)) < 0)
437 bytestream_put_be32(&p, rt->server_bw);
438 pkt.data_size = p - pkt.data;
439 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
441 ff_rtmp_packet_destroy(&pkt);
444 // Send Peer Bandwidth
445 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
446 RTMP_PT_CLIENT_BW, 0, 5)) < 0)
449 bytestream_put_be32(&p, rt->server_bw);
450 bytestream_put_byte(&p, 2); // dynamic
451 pkt.data_size = p - pkt.data;
452 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
454 ff_rtmp_packet_destroy(&pkt);
459 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
460 RTMP_PT_PING, 0, 6)) < 0)
464 bytestream_put_be16(&p, 0); // 0 -> Stream Begin
465 bytestream_put_be32(&p, 0);
466 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
468 ff_rtmp_packet_destroy(&pkt);
473 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
474 RTMP_PT_CHUNK_SIZE, 0, 4)) < 0)
478 bytestream_put_be32(&p, rt->out_chunk_size);
479 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
481 ff_rtmp_packet_destroy(&pkt);
485 // Send result_ NetConnection.Connect.Success to connect
486 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
488 RTMP_PKTDATA_DEFAULT_SIZE)) < 0)
492 ff_amf_write_string(&p, "_result");
493 ff_amf_write_number(&p, seqnum);
495 ff_amf_write_object_start(&p);
496 ff_amf_write_field_name(&p, "fmsVer");
497 ff_amf_write_string(&p, "FMS/3,0,1,123");
498 ff_amf_write_field_name(&p, "capabilities");
499 ff_amf_write_number(&p, 31);
500 ff_amf_write_object_end(&p);
502 ff_amf_write_object_start(&p);
503 ff_amf_write_field_name(&p, "level");
504 ff_amf_write_string(&p, "status");
505 ff_amf_write_field_name(&p, "code");
506 ff_amf_write_string(&p, "NetConnection.Connect.Success");
507 ff_amf_write_field_name(&p, "description");
508 ff_amf_write_string(&p, "Connection succeeded.");
509 ff_amf_write_field_name(&p, "objectEncoding");
510 ff_amf_write_number(&p, 0);
511 ff_amf_write_object_end(&p);
513 pkt.data_size = p - pkt.data;
514 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
516 ff_rtmp_packet_destroy(&pkt);
520 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
521 RTMP_PT_INVOKE, 0, 30)) < 0)
524 ff_amf_write_string(&p, "onBWDone");
525 ff_amf_write_number(&p, 0);
526 ff_amf_write_null(&p);
527 ff_amf_write_number(&p, 8192);
528 pkt.data_size = p - pkt.data;
529 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
531 ff_rtmp_packet_destroy(&pkt);
537 * Generate 'releaseStream' call and send it to the server. It should make
538 * the server release some channel for media streams.
540 static int gen_release_stream(URLContext *s, RTMPContext *rt)
546 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
547 0, 29 + strlen(rt->playpath))) < 0)
550 av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
552 ff_amf_write_string(&p, "releaseStream");
553 ff_amf_write_number(&p, ++rt->nb_invokes);
554 ff_amf_write_null(&p);
555 ff_amf_write_string(&p, rt->playpath);
557 return rtmp_send_packet(rt, &pkt, 1);
561 * Generate 'FCPublish' call and send it to the server. It should make
562 * the server preapare for receiving media streams.
564 static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
570 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
571 0, 25 + strlen(rt->playpath))) < 0)
574 av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
576 ff_amf_write_string(&p, "FCPublish");
577 ff_amf_write_number(&p, ++rt->nb_invokes);
578 ff_amf_write_null(&p);
579 ff_amf_write_string(&p, rt->playpath);
581 return rtmp_send_packet(rt, &pkt, 1);
585 * Generate 'FCUnpublish' call and send it to the server. It should make
586 * the server destroy stream.
588 static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
594 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
595 0, 27 + strlen(rt->playpath))) < 0)
598 av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
600 ff_amf_write_string(&p, "FCUnpublish");
601 ff_amf_write_number(&p, ++rt->nb_invokes);
602 ff_amf_write_null(&p);
603 ff_amf_write_string(&p, rt->playpath);
605 return rtmp_send_packet(rt, &pkt, 0);
609 * Generate 'createStream' call and send it to the server. It should make
610 * the server allocate some channel for media streams.
612 static int gen_create_stream(URLContext *s, RTMPContext *rt)
618 av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
620 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
625 ff_amf_write_string(&p, "createStream");
626 ff_amf_write_number(&p, ++rt->nb_invokes);
627 ff_amf_write_null(&p);
629 return rtmp_send_packet(rt, &pkt, 1);
634 * Generate 'deleteStream' call and send it to the server. It should make
635 * the server remove some channel for media streams.
637 static int gen_delete_stream(URLContext *s, RTMPContext *rt)
643 av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
645 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
650 ff_amf_write_string(&p, "deleteStream");
651 ff_amf_write_number(&p, ++rt->nb_invokes);
652 ff_amf_write_null(&p);
653 ff_amf_write_number(&p, rt->main_channel_id);
655 return rtmp_send_packet(rt, &pkt, 0);
659 * Generate client buffer time and send it to the server.
661 static int gen_buffer_time(URLContext *s, RTMPContext *rt)
667 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
672 bytestream_put_be16(&p, 3);
673 bytestream_put_be32(&p, rt->main_channel_id);
674 bytestream_put_be32(&p, rt->client_buffer_time);
676 return rtmp_send_packet(rt, &pkt, 0);
680 * Generate 'play' call and send it to the server, then ping the server
681 * to start actual playing.
683 static int gen_play(URLContext *s, RTMPContext *rt)
689 av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
691 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE,
692 0, 29 + strlen(rt->playpath))) < 0)
695 pkt.extra = rt->main_channel_id;
698 ff_amf_write_string(&p, "play");
699 ff_amf_write_number(&p, ++rt->nb_invokes);
700 ff_amf_write_null(&p);
701 ff_amf_write_string(&p, rt->playpath);
702 ff_amf_write_number(&p, rt->live);
704 return rtmp_send_packet(rt, &pkt, 1);
708 * Generate 'publish' call and send it to the server.
710 static int gen_publish(URLContext *s, RTMPContext *rt)
716 av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
718 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
719 0, 30 + strlen(rt->playpath))) < 0)
722 pkt.extra = rt->main_channel_id;
725 ff_amf_write_string(&p, "publish");
726 ff_amf_write_number(&p, ++rt->nb_invokes);
727 ff_amf_write_null(&p);
728 ff_amf_write_string(&p, rt->playpath);
729 ff_amf_write_string(&p, "live");
731 return rtmp_send_packet(rt, &pkt, 1);
735 * Generate ping reply and send it to the server.
737 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
743 if (ppkt->data_size < 6) {
744 av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
746 return AVERROR_INVALIDDATA;
749 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
750 ppkt->timestamp + 1, 6)) < 0)
754 bytestream_put_be16(&p, 7);
755 bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
757 return rtmp_send_packet(rt, &pkt, 0);
761 * Generate SWF verification message and send it to the server.
763 static int gen_swf_verification(URLContext *s, RTMPContext *rt)
769 av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
770 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
775 bytestream_put_be16(&p, 27);
776 memcpy(p, rt->swfverification, 42);
778 return rtmp_send_packet(rt, &pkt, 0);
782 * Generate server bandwidth message and send it to the server.
784 static int gen_server_bw(URLContext *s, RTMPContext *rt)
790 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW,
795 bytestream_put_be32(&p, rt->server_bw);
797 return rtmp_send_packet(rt, &pkt, 0);
801 * Generate check bandwidth message and send it to the server.
803 static int gen_check_bw(URLContext *s, RTMPContext *rt)
809 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
814 ff_amf_write_string(&p, "_checkbw");
815 ff_amf_write_number(&p, ++rt->nb_invokes);
816 ff_amf_write_null(&p);
818 return rtmp_send_packet(rt, &pkt, 1);
822 * Generate report on bytes read so far and send it to the server.
824 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
830 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
835 bytestream_put_be32(&p, rt->bytes_read);
837 return rtmp_send_packet(rt, &pkt, 0);
840 static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
841 const char *subscribe)
847 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
848 0, 27 + strlen(subscribe))) < 0)
852 ff_amf_write_string(&p, "FCSubscribe");
853 ff_amf_write_number(&p, ++rt->nb_invokes);
854 ff_amf_write_null(&p);
855 ff_amf_write_string(&p, subscribe);
857 return rtmp_send_packet(rt, &pkt, 1);
860 int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
861 const uint8_t *key, int keylen, uint8_t *dst)
864 uint8_t hmac_buf[64+32] = {0};
867 sha = av_sha_alloc();
869 return AVERROR(ENOMEM);
872 memcpy(hmac_buf, key, keylen);
874 av_sha_init(sha, 256);
875 av_sha_update(sha,key, keylen);
876 av_sha_final(sha, hmac_buf);
878 for (i = 0; i < 64; i++)
879 hmac_buf[i] ^= HMAC_IPAD_VAL;
881 av_sha_init(sha, 256);
882 av_sha_update(sha, hmac_buf, 64);
884 av_sha_update(sha, src, len);
885 } else { //skip 32 bytes used for storing digest
886 av_sha_update(sha, src, gap);
887 av_sha_update(sha, src + gap + 32, len - gap - 32);
889 av_sha_final(sha, hmac_buf + 64);
891 for (i = 0; i < 64; i++)
892 hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
893 av_sha_init(sha, 256);
894 av_sha_update(sha, hmac_buf, 64+32);
895 av_sha_final(sha, dst);
902 int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
905 int i, digest_pos = 0;
907 for (i = 0; i < 4; i++)
908 digest_pos += buf[i + off];
909 digest_pos = digest_pos % mod_val + add_val;
915 * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
916 * will be stored) into that packet.
918 * @param buf handshake data (1536 bytes)
919 * @param encrypted use an encrypted connection (RTMPE)
920 * @return offset to the digest inside input data
922 static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
927 digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
929 digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
931 ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
932 rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
941 * Verify that the received server response has the expected digest value.
943 * @param buf handshake data received from the server (1536 bytes)
944 * @param off position to search digest offset from
945 * @return 0 if digest is valid, digest position otherwise
947 static int rtmp_validate_digest(uint8_t *buf, int off)
952 digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
954 ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
955 rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
960 if (!memcmp(digest, buf + digest_pos, 32))
965 static int rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt,
971 if (rt->swfhash_len != 32) {
972 av_log(s, AV_LOG_ERROR,
973 "Hash of the decompressed SWF file is not 32 bytes long.\n");
974 return AVERROR(EINVAL);
977 p = &rt->swfverification[0];
978 bytestream_put_byte(&p, 1);
979 bytestream_put_byte(&p, 1);
980 bytestream_put_be32(&p, rt->swfsize);
981 bytestream_put_be32(&p, rt->swfsize);
983 if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
990 static int rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size,
991 uint8_t **out_data, int64_t *out_size)
998 zs.avail_in = in_size;
999 zs.next_in = in_data;
1000 ret = inflateInit(&zs);
1002 return AVERROR_UNKNOWN;
1005 uint8_t tmp_buf[16384];
1007 zs.avail_out = sizeof(tmp_buf);
1008 zs.next_out = tmp_buf;
1010 ret = inflate(&zs, Z_NO_FLUSH);
1011 if (ret != Z_OK && ret != Z_STREAM_END) {
1012 ret = AVERROR_UNKNOWN;
1016 size = sizeof(tmp_buf) - zs.avail_out;
1017 if (!(ptr = av_realloc(*out_data, *out_size + size))) {
1018 ret = AVERROR(ENOMEM);
1023 memcpy(*out_data + *out_size, tmp_buf, size);
1025 } while (zs.avail_out == 0);
1033 static int rtmp_calc_swfhash(URLContext *s)
1035 RTMPContext *rt = s->priv_data;
1036 uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
1037 int64_t in_size, out_size;
1043 /* Get the SWF player file. */
1044 if ((ret = ffurl_open(&stream, rt->swfverify, AVIO_FLAG_READ,
1045 &s->interrupt_callback, NULL)) < 0) {
1046 av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1050 if ((in_size = ffurl_seek(stream, 0, AVSEEK_SIZE)) < 0) {
1055 if (!(in_data = av_malloc(in_size))) {
1056 ret = AVERROR(ENOMEM);
1060 if ((ret = ffurl_read_complete(stream, in_data, in_size)) < 0)
1064 ret = AVERROR_INVALIDDATA;
1068 if (!memcmp(in_data, "CWS", 3)) {
1069 /* Decompress the SWF player file using Zlib. */
1070 if (!(out_data = av_malloc(8))) {
1071 ret = AVERROR(ENOMEM);
1074 *in_data = 'F'; // magic stuff
1075 memcpy(out_data, in_data, 8);
1079 if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
1080 &out_data, &out_size)) < 0)
1083 av_log(s, AV_LOG_ERROR,
1084 "Zlib is required for decompressing the SWF player file.\n");
1085 ret = AVERROR(EINVAL);
1095 /* Compute the SHA256 hash of the SWF player file. */
1096 if ((ret = ff_rtmp_calc_digest(swfdata, swfsize, 0,
1097 "Genuine Adobe Flash Player 001", 30,
1101 /* Set SWFVerification parameters. */
1102 av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1103 rt->swfsize = swfsize;
1107 av_freep(&out_data);
1108 ffurl_close(stream);
1113 * Perform handshake with the server by means of exchanging pseudorandom data
1114 * signed with HMAC-SHA2 digest.
1116 * @return 0 if handshake succeeds, negative value otherwise
1118 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
1121 uint8_t tosend [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
1122 3, // unencrypted data
1123 0, 0, 0, 0, // client uptime
1129 uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
1130 uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
1132 int server_pos, client_pos;
1133 uint8_t digest[32], signature[32];
1136 av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
1138 av_lfg_init(&rnd, 0xDEADC0DE);
1139 // generate handshake packet - 1536 bytes of pseudorandom data
1140 for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
1141 tosend[i] = av_lfg_get(&rnd) >> 24;
1143 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1144 /* When the client wants to use RTMPE, we have to change the command
1145 * byte to 0x06 which means to use encrypted data and we have to set
1146 * the flash version to at least 9.0.115.0. */
1153 /* Initialize the Diffie-Hellmann context and generate the public key
1154 * to send to the server. */
1155 if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1159 client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1163 if ((ret = ffurl_write(rt->stream, tosend,
1164 RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1165 av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
1169 if ((ret = ffurl_read_complete(rt->stream, serverdata,
1170 RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1171 av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1175 if ((ret = ffurl_read_complete(rt->stream, clientdata,
1176 RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
1177 av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1181 av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
1182 av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
1183 serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
1185 if (rt->is_input && serverdata[5] >= 3) {
1186 server_pos = rtmp_validate_digest(serverdata + 1, 772);
1192 server_pos = rtmp_validate_digest(serverdata + 1, 8);
1197 av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
1198 return AVERROR(EIO);
1202 /* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
1203 * key are the last 32 bytes of the server handshake. */
1205 if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1206 RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
1210 ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
1211 rtmp_server_key, sizeof(rtmp_server_key),
1216 ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
1217 0, digest, 32, signature);
1221 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1222 /* Compute the shared secret key sent by the server and initialize
1223 * the RC4 encryption. */
1224 if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1225 tosend + 1, type)) < 0)
1228 /* Encrypt the signature received by the server. */
1229 ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1232 if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
1233 av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
1234 return AVERROR(EIO);
1237 for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
1238 tosend[i] = av_lfg_get(&rnd) >> 24;
1239 ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
1240 rtmp_player_key, sizeof(rtmp_player_key),
1245 ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
1247 tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
1251 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1252 /* Encrypt the signature to be send to the server. */
1253 ff_rtmpe_encrypt_sig(rt->stream, tosend +
1254 RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
1258 // write reply back to the server
1259 if ((ret = ffurl_write(rt->stream, tosend,
1260 RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1263 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1264 /* Set RC4 keys for encryption and update the keystreams. */
1265 if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1269 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1270 /* Compute the shared secret key sent by the server and initialize
1271 * the RC4 encryption. */
1272 if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1273 tosend + 1, 1)) < 0)
1276 if (serverdata[0] == 9) {
1277 /* Encrypt the signature received by the server. */
1278 ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1283 if ((ret = ffurl_write(rt->stream, serverdata + 1,
1284 RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1287 if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1288 /* Set RC4 keys for encryption and update the keystreams. */
1289 if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1297 static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1298 uint32_t *second_int, char *arraydata,
1303 inoutsize = ffurl_read_complete(rt->stream, arraydata,
1304 RTMP_HANDSHAKE_PACKET_SIZE);
1306 return AVERROR(EIO);
1307 if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1308 av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1309 " not following standard\n", (int)inoutsize);
1310 return AVERROR(EINVAL);
1313 *first_int = AV_RB32(arraydata);
1314 *second_int = AV_RB32(arraydata + 4);
1318 static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1319 uint32_t second_int, char *arraydata, int size)
1323 AV_WB32(arraydata, first_int);
1324 AV_WB32(arraydata + 4, first_int);
1325 inoutsize = ffurl_write(rt->stream, arraydata,
1326 RTMP_HANDSHAKE_PACKET_SIZE);
1327 if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1328 av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1329 return AVERROR(EIO);
1336 * rtmp handshake server side
1338 static int rtmp_server_handshake(URLContext *s, RTMPContext *rt)
1340 uint8_t buffer[RTMP_HANDSHAKE_PACKET_SIZE];
1342 uint32_t hs_my_epoch;
1343 uint8_t hs_c1[RTMP_HANDSHAKE_PACKET_SIZE];
1344 uint8_t hs_s1[RTMP_HANDSHAKE_PACKET_SIZE];
1351 inoutsize = ffurl_read_complete(rt->stream, buffer, 1); // Receive C0
1352 if (inoutsize <= 0) {
1353 av_log(s, AV_LOG_ERROR, "Unable to read handshake\n");
1354 return AVERROR(EIO);
1357 if (buffer[0] != 3) {
1358 av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n");
1359 return AVERROR(EIO);
1361 if (ffurl_write(rt->stream, buffer, 1) <= 0) { // Send S0
1362 av_log(s, AV_LOG_ERROR,
1363 "Unable to write answer - RTMP S0\n");
1364 return AVERROR(EIO);
1367 ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1368 RTMP_HANDSHAKE_PACKET_SIZE);
1370 av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
1374 av_log(s, AV_LOG_WARNING, "Erroneous C1 Message zero != 0\n");
1376 /* By now same epoch will be sent */
1377 hs_my_epoch = hs_epoch;
1378 /* Generate random */
1379 for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE);
1381 AV_WB32(hs_s1 + randomidx, av_get_random_seed());
1383 ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1384 RTMP_HANDSHAKE_PACKET_SIZE);
1386 av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n");
1390 ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1391 RTMP_HANDSHAKE_PACKET_SIZE);
1393 av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n");
1397 ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1398 RTMP_HANDSHAKE_PACKET_SIZE);
1400 av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n");
1403 if (temp != hs_my_epoch)
1404 av_log(s, AV_LOG_WARNING,
1405 "Erroneous C2 Message epoch does not match up with C1 epoch\n");
1406 if (memcmp(buffer + 8, hs_s1 + 8,
1407 RTMP_HANDSHAKE_PACKET_SIZE - 8))
1408 av_log(s, AV_LOG_WARNING,
1409 "Erroneous C2 Message random does not match up\n");
1414 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
1416 RTMPContext *rt = s->priv_data;
1419 if (pkt->data_size < 4) {
1420 av_log(s, AV_LOG_ERROR,
1421 "Too short chunk size change packet (%d)\n",
1423 return AVERROR_INVALIDDATA;
1426 if (!rt->is_input) {
1427 /* Send the same chunk size change packet back to the server,
1428 * setting the outgoing chunk size to the same as the incoming one. */
1429 if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1430 rt->prev_pkt[1])) < 0)
1432 rt->out_chunk_size = AV_RB32(pkt->data);
1435 rt->in_chunk_size = AV_RB32(pkt->data);
1436 if (rt->in_chunk_size <= 0) {
1437 av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n",
1439 return AVERROR_INVALIDDATA;
1441 av_log(s, AV_LOG_DEBUG, "New incoming chunk size = %d\n",
1447 static int handle_ping(URLContext *s, RTMPPacket *pkt)
1449 RTMPContext *rt = s->priv_data;
1452 if (pkt->data_size < 2) {
1453 av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
1455 return AVERROR_INVALIDDATA;
1458 t = AV_RB16(pkt->data);
1460 if ((ret = gen_pong(s, rt, pkt)) < 0)
1462 } else if (t == 26) {
1464 if ((ret = gen_swf_verification(s, rt)) < 0)
1467 av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
1474 static int handle_client_bw(URLContext *s, RTMPPacket *pkt)
1476 RTMPContext *rt = s->priv_data;
1478 if (pkt->data_size < 4) {
1479 av_log(s, AV_LOG_ERROR,
1480 "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1482 return AVERROR_INVALIDDATA;
1485 rt->client_report_size = AV_RB32(pkt->data);
1486 if (rt->client_report_size <= 0) {
1487 av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
1488 rt->client_report_size);
1489 return AVERROR_INVALIDDATA;
1492 av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
1493 rt->client_report_size >>= 1;
1498 static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
1500 RTMPContext *rt = s->priv_data;
1502 if (pkt->data_size < 4) {
1503 av_log(s, AV_LOG_ERROR,
1504 "Too short server bandwidth report packet (%d)\n",
1506 return AVERROR_INVALIDDATA;
1509 rt->server_bw = AV_RB32(pkt->data);
1510 if (rt->server_bw <= 0) {
1511 av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
1513 return AVERROR_INVALIDDATA;
1515 av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
1520 static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1521 const char *opaque, const char *challenge)
1524 char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
1525 struct AVMD5 *md5 = av_md5_alloc();
1527 return AVERROR(ENOMEM);
1529 snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
1532 av_md5_update(md5, user, strlen(user));
1533 av_md5_update(md5, salt, strlen(salt));
1534 av_md5_update(md5, rt->password, strlen(rt->password));
1535 av_md5_final(md5, hash);
1536 av_base64_encode(hashstr, sizeof(hashstr), hash,
1539 av_md5_update(md5, hashstr, strlen(hashstr));
1541 av_md5_update(md5, opaque, strlen(opaque));
1543 av_md5_update(md5, challenge, strlen(challenge));
1544 av_md5_update(md5, challenge2, strlen(challenge2));
1545 av_md5_final(md5, hash);
1546 av_base64_encode(hashstr, sizeof(hashstr), hash,
1548 snprintf(rt->auth_params, sizeof(rt->auth_params),
1549 "?authmod=%s&user=%s&challenge=%s&response=%s",
1550 "adobe", user, challenge2, hashstr);
1552 av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1553 "&opaque=%s", opaque);
1559 static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1562 char hashstr1[33], hashstr2[33];
1563 const char *realm = "live";
1564 const char *method = "publish";
1565 const char *qop = "auth";
1566 const char *nc = "00000001";
1568 struct AVMD5 *md5 = av_md5_alloc();
1570 return AVERROR(ENOMEM);
1572 snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
1575 av_md5_update(md5, user, strlen(user));
1576 av_md5_update(md5, ":", 1);
1577 av_md5_update(md5, realm, strlen(realm));
1578 av_md5_update(md5, ":", 1);
1579 av_md5_update(md5, rt->password, strlen(rt->password));
1580 av_md5_final(md5, hash);
1581 ff_data_to_hex(hashstr1, hash, 16, 1);
1582 hashstr1[32] = '\0';
1585 av_md5_update(md5, method, strlen(method));
1586 av_md5_update(md5, ":/", 2);
1587 av_md5_update(md5, rt->app, strlen(rt->app));
1588 av_md5_final(md5, hash);
1589 ff_data_to_hex(hashstr2, hash, 16, 1);
1590 hashstr2[32] = '\0';
1593 av_md5_update(md5, hashstr1, strlen(hashstr1));
1594 av_md5_update(md5, ":", 1);
1596 av_md5_update(md5, nonce, strlen(nonce));
1597 av_md5_update(md5, ":", 1);
1598 av_md5_update(md5, nc, strlen(nc));
1599 av_md5_update(md5, ":", 1);
1600 av_md5_update(md5, cnonce, strlen(cnonce));
1601 av_md5_update(md5, ":", 1);
1602 av_md5_update(md5, qop, strlen(qop));
1603 av_md5_update(md5, ":", 1);
1604 av_md5_update(md5, hashstr2, strlen(hashstr2));
1605 av_md5_final(md5, hash);
1606 ff_data_to_hex(hashstr1, hash, 16, 1);
1608 snprintf(rt->auth_params, sizeof(rt->auth_params),
1609 "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
1610 "llnw", user, nonce, cnonce, nc, hashstr1);
1616 static int handle_connect_error(URLContext *s, const char *desc)
1618 RTMPContext *rt = s->priv_data;
1619 char buf[300], *ptr, authmod[15];
1621 const char *user = "", *salt = "", *opaque = NULL,
1622 *challenge = NULL, *cptr = NULL, *nonce = NULL;
1624 if (!(cptr = strstr(desc, "authmod=adobe")) &&
1625 !(cptr = strstr(desc, "authmod=llnw"))) {
1626 av_log(s, AV_LOG_ERROR,
1627 "Unknown connect error (unsupported authentication method?)\n");
1628 return AVERROR_UNKNOWN;
1630 cptr += strlen("authmod=");
1631 while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
1632 authmod[i++] = *cptr++;
1635 if (!rt->username[0] || !rt->password[0]) {
1636 av_log(s, AV_LOG_ERROR, "No credentials set\n");
1637 return AVERROR_UNKNOWN;
1640 if (strstr(desc, "?reason=authfailed")) {
1641 av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
1642 return AVERROR_UNKNOWN;
1643 } else if (strstr(desc, "?reason=nosuchuser")) {
1644 av_log(s, AV_LOG_ERROR, "Incorrect username\n");
1645 return AVERROR_UNKNOWN;
1648 if (rt->auth_tried) {
1649 av_log(s, AV_LOG_ERROR, "Authentication failed\n");
1650 return AVERROR_UNKNOWN;
1653 rt->auth_params[0] = '\0';
1655 if (strstr(desc, "code=403 need auth")) {
1656 snprintf(rt->auth_params, sizeof(rt->auth_params),
1657 "?authmod=%s&user=%s", authmod, rt->username);
1661 if (!(cptr = strstr(desc, "?reason=needauth"))) {
1662 av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
1663 return AVERROR_UNKNOWN;
1666 av_strlcpy(buf, cptr + 1, sizeof(buf));
1670 char *next = strchr(ptr, '&');
1671 char *value = strchr(ptr, '=');
1676 if (!strcmp(ptr, "user")) {
1678 } else if (!strcmp(ptr, "salt")) {
1680 } else if (!strcmp(ptr, "opaque")) {
1682 } else if (!strcmp(ptr, "challenge")) {
1684 } else if (!strcmp(ptr, "nonce")) {
1690 if (!strcmp(authmod, "adobe")) {
1691 if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
1694 if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1702 static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
1704 RTMPContext *rt = s->priv_data;
1705 const uint8_t *data_end = pkt->data + pkt->data_size;
1706 char *tracked_method = NULL;
1707 int level = AV_LOG_ERROR;
1708 uint8_t tmpstr[256];
1711 if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1714 if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1715 "description", tmpstr, sizeof(tmpstr))) {
1716 if (tracked_method && (!strcmp(tracked_method, "_checkbw") ||
1717 !strcmp(tracked_method, "releaseStream") ||
1718 !strcmp(tracked_method, "FCSubscribe") ||
1719 !strcmp(tracked_method, "FCPublish"))) {
1720 /* Gracefully ignore Adobe-specific historical artifact errors. */
1721 level = AV_LOG_WARNING;
1723 } else if (tracked_method && !strcmp(tracked_method, "connect")) {
1724 ret = handle_connect_error(s, tmpstr);
1726 rt->do_reconnect = 1;
1727 level = AV_LOG_VERBOSE;
1730 ret = AVERROR_UNKNOWN;
1731 av_log(s, level, "Server error: %s\n", tmpstr);
1734 av_free(tracked_method);
1738 static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
1740 RTMPContext *rt = s->priv_data;
1744 char statusmsg[128];
1747 const uint8_t *p = pkt->data;
1749 RTMPPacket spkt = { 0 };
1753 bytestream2_init(&gbc, p, pkt->data_size);
1754 if (ff_amf_read_string(&gbc, command, sizeof(command),
1756 av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1757 return AVERROR_INVALIDDATA;
1760 ret = ff_amf_read_number(&gbc, &seqnum);
1763 ret = ff_amf_read_null(&gbc);
1766 if (!strcmp(command, "FCPublish") ||
1767 !strcmp(command, "publish")) {
1768 ret = ff_amf_read_string(&gbc, filename,
1769 sizeof(filename), &stringlen);
1772 pchar = strrchr(s->filename, '/');
1774 av_log(s, AV_LOG_WARNING,
1775 "Unable to find / in url %s, bad format\n",
1777 pchar = s->filename;
1780 if (strcmp(pchar, filename))
1781 av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1782 " %s\n", filename, pchar);
1784 rt->state = STATE_RECEIVING;
1787 if (!strcmp(command, "FCPublish")) {
1788 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1790 RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1791 av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1795 ff_amf_write_string(&pp, "onFCPublish");
1796 } else if (!strcmp(command, "publish")) {
1798 // Send Stream Begin 1
1799 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1800 RTMP_PT_PING, 0, 6)) < 0) {
1801 av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1805 bytestream2_init_writer(&pbc, pp, spkt.data_size);
1806 bytestream2_put_be16(&pbc, 0); // 0 -> Stream Begin
1807 bytestream2_put_be32(&pbc, rt->nb_streamid);
1808 ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1810 ff_rtmp_packet_destroy(&spkt);
1814 // Send onStatus(NetStream.Publish.Start)
1815 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1817 RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1818 av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1821 spkt.extra = pkt->extra;
1823 ff_amf_write_string(&pp, "onStatus");
1824 ff_amf_write_number(&pp, 0);
1825 ff_amf_write_null(&pp);
1827 ff_amf_write_object_start(&pp);
1828 ff_amf_write_field_name(&pp, "level");
1829 ff_amf_write_string(&pp, "status");
1830 ff_amf_write_field_name(&pp, "code");
1831 ff_amf_write_string(&pp, "NetStream.Publish.Start");
1832 ff_amf_write_field_name(&pp, "description");
1833 snprintf(statusmsg, sizeof(statusmsg),
1834 "%s is now published", filename);
1835 ff_amf_write_string(&pp, statusmsg);
1836 ff_amf_write_field_name(&pp, "details");
1837 ff_amf_write_string(&pp, filename);
1838 ff_amf_write_field_name(&pp, "clientid");
1839 snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
1840 ff_amf_write_string(&pp, statusmsg);
1841 ff_amf_write_object_end(&pp);
1844 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1846 RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1847 av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1851 ff_amf_write_string(&pp, "_result");
1852 ff_amf_write_number(&pp, seqnum);
1853 ff_amf_write_null(&pp);
1854 if (!strcmp(command, "createStream")) {
1856 if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1857 rt->nb_streamid++; /* Values 0 and 2 are reserved */
1858 ff_amf_write_number(&pp, rt->nb_streamid);
1859 /* By now we don't control which streams are removed in
1860 * deleteStream. There is no stream creation control
1861 * if a client creates more than 2^32 - 2 streams. */
1864 spkt.data_size = pp - spkt.data;
1865 ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1867 ff_rtmp_packet_destroy(&spkt);
1871 static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
1873 RTMPContext *rt = s->priv_data;
1874 char *tracked_method = NULL;
1877 if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
1880 if (!tracked_method) {
1881 /* Ignore this reply when the current method is not tracked. */
1885 if (!memcmp(tracked_method, "connect", 7)) {
1886 if (!rt->is_input) {
1887 if ((ret = gen_release_stream(s, rt)) < 0)
1890 if ((ret = gen_fcpublish_stream(s, rt)) < 0)
1893 if ((ret = gen_server_bw(s, rt)) < 0)
1897 if ((ret = gen_create_stream(s, rt)) < 0)
1901 /* Send the FCSubscribe command when the name of live
1902 * stream is defined by the user or if it's a live stream. */
1903 if (rt->subscribe) {
1904 if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
1906 } else if (rt->live == -1) {
1907 if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
1911 } else if (!memcmp(tracked_method, "createStream", 12)) {
1912 //extract a number from the result
1913 if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1914 av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1916 rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
1919 if (!rt->is_input) {
1920 if ((ret = gen_publish(s, rt)) < 0)
1923 if ((ret = gen_play(s, rt)) < 0)
1925 if ((ret = gen_buffer_time(s, rt)) < 0)
1931 av_free(tracked_method);
1935 static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
1937 RTMPContext *rt = s->priv_data;
1938 const uint8_t *data_end = pkt->data + pkt->data_size;
1939 const uint8_t *ptr = pkt->data + 11;
1940 uint8_t tmpstr[256];
1943 for (i = 0; i < 2; i++) {
1944 t = ff_amf_tag_size(ptr, data_end);
1950 t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
1951 if (!t && !strcmp(tmpstr, "error")) {
1952 if (!ff_amf_get_field_value(ptr, data_end,
1953 "description", tmpstr, sizeof(tmpstr)))
1954 av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
1958 t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
1959 if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
1960 if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
1961 if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
1962 if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
1967 static int handle_invoke(URLContext *s, RTMPPacket *pkt)
1969 RTMPContext *rt = s->priv_data;
1972 //TODO: check for the messages sent for wrong state?
1973 if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
1974 if ((ret = handle_invoke_error(s, pkt)) < 0)
1976 } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
1977 if ((ret = handle_invoke_result(s, pkt)) < 0)
1979 } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
1980 if ((ret = handle_invoke_status(s, pkt)) < 0)
1982 } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
1983 if ((ret = gen_check_bw(s, rt)) < 0)
1985 } else if (!memcmp(pkt->data, "\002\000\015releaseStream", 16) ||
1986 !memcmp(pkt->data, "\002\000\011FCPublish", 12) ||
1987 !memcmp(pkt->data, "\002\000\007publish", 10) ||
1988 !memcmp(pkt->data, "\002\000\010_checkbw", 11) ||
1989 !memcmp(pkt->data, "\002\000\014createStream", 15)) {
1990 if ((ret = send_invoke_response(s, pkt)) < 0)
1997 static int handle_notify(URLContext *s, RTMPPacket *pkt) {
1998 RTMPContext *rt = s->priv_data;
1999 const uint8_t *p = NULL;
2001 uint8_t commandbuffer[64];
2002 char statusmsg[128];
2008 const uint8_t *datatowrite;
2009 unsigned datatowritelength;
2012 bytestream2_init(&gbc, p, pkt->data_size);
2013 if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2015 return AVERROR_INVALIDDATA;
2016 if (!strcmp(commandbuffer, "@setDataFrame")) {
2017 datatowrite = gbc.buffer;
2018 datatowritelength = bytestream2_get_bytes_left(&gbc);
2019 if (ff_amf_read_string(&gbc, statusmsg,
2020 sizeof(statusmsg), &stringlen))
2021 return AVERROR_INVALIDDATA;
2022 if (strcmp(statusmsg, "onMetaData")) {
2023 av_log(s, AV_LOG_INFO, "Expecting onMetadata but got %s\n",
2028 /* Provide ECMAArray to flv */
2029 ts = pkt->timestamp;
2031 // generate packet header and put data into buffer for FLV demuxer
2032 if (rt->flv_off < rt->flv_size) {
2033 old_flv_size = rt->flv_size;
2034 rt->flv_size += datatowritelength + 15;
2037 rt->flv_size = datatowritelength + 15;
2041 cp = av_realloc(rt->flv_data, rt->flv_size);
2043 return AVERROR(ENOMEM);
2045 bytestream2_init_writer(&pbc, cp, rt->flv_size);
2046 bytestream2_skip_p(&pbc, old_flv_size);
2047 bytestream2_put_byte(&pbc, pkt->type);
2048 bytestream2_put_be24(&pbc, datatowritelength);
2049 bytestream2_put_be24(&pbc, ts);
2050 bytestream2_put_byte(&pbc, ts >> 24);
2051 bytestream2_put_be24(&pbc, 0);
2052 bytestream2_put_buffer(&pbc, datatowrite, datatowritelength);
2053 bytestream2_put_be32(&pbc, 0);
2059 * Parse received packet and possibly perform some action depending on
2060 * the packet contents.
2061 * @return 0 for no errors, negative values for serious errors which prevent
2062 * further communications, positive values for uncritical errors
2064 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
2069 ff_rtmp_packet_dump(s, pkt);
2072 switch (pkt->type) {
2073 case RTMP_PT_BYTES_READ:
2074 av_dlog(s, "received bytes read report\n");
2076 case RTMP_PT_CHUNK_SIZE:
2077 if ((ret = handle_chunk_size(s, pkt)) < 0)
2081 if ((ret = handle_ping(s, pkt)) < 0)
2084 case RTMP_PT_CLIENT_BW:
2085 if ((ret = handle_client_bw(s, pkt)) < 0)
2088 case RTMP_PT_SERVER_BW:
2089 if ((ret = handle_server_bw(s, pkt)) < 0)
2092 case RTMP_PT_INVOKE:
2093 if ((ret = handle_invoke(s, pkt)) < 0)
2098 case RTMP_PT_METADATA:
2099 case RTMP_PT_NOTIFY:
2100 /* Audio, Video and Metadata packets are parsed in get_packet() */
2103 av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2110 * Interact with the server by receiving and sending RTMP packets until
2111 * there is some significant data (media data or expected status notification).
2113 * @param s reading context
2114 * @param for_header non-zero value tells function to work until it
2115 * gets notification from the server that playing has been started,
2116 * otherwise function will work until some media data is received (or
2118 * @return 0 for successful operation, negative value in case of error
2120 static int get_packet(URLContext *s, int for_header)
2122 RTMPContext *rt = s->priv_data;
2125 const uint8_t *next;
2127 uint32_t ts, cts, pts=0;
2129 if (rt->state == STATE_STOPPED)
2133 RTMPPacket rpkt = { 0 };
2134 if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2135 rt->in_chunk_size, rt->prev_pkt[0])) <= 0) {
2137 return AVERROR(EAGAIN);
2139 return AVERROR(EIO);
2142 rt->bytes_read += ret;
2143 if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
2144 av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2145 if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
2147 rt->last_bytes_read = rt->bytes_read;
2150 ret = rtmp_parse_result(s, rt, &rpkt);
2151 if (ret < 0) {//serious error in current packet
2152 ff_rtmp_packet_destroy(&rpkt);
2155 if (rt->do_reconnect && for_header) {
2156 ff_rtmp_packet_destroy(&rpkt);
2159 if (rt->state == STATE_STOPPED) {
2160 ff_rtmp_packet_destroy(&rpkt);
2163 if (for_header && (rt->state == STATE_PLAYING ||
2164 rt->state == STATE_PUBLISHING ||
2165 rt->state == STATE_RECEIVING)) {
2166 ff_rtmp_packet_destroy(&rpkt);
2169 if (!rpkt.data_size || !rt->is_input) {
2170 ff_rtmp_packet_destroy(&rpkt);
2173 if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
2174 (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
2175 ts = rpkt.timestamp;
2177 // generate packet header and put data into buffer for FLV demuxer
2179 rt->flv_size = rpkt.data_size + 15;
2180 rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
2181 bytestream_put_byte(&p, rpkt.type);
2182 bytestream_put_be24(&p, rpkt.data_size);
2183 bytestream_put_be24(&p, ts);
2184 bytestream_put_byte(&p, ts >> 24);
2185 bytestream_put_be24(&p, 0);
2186 bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
2187 bytestream_put_be32(&p, 0);
2188 ff_rtmp_packet_destroy(&rpkt);
2190 } else if (rpkt.type == RTMP_PT_NOTIFY) {
2191 ret = handle_notify(s, &rpkt);
2192 ff_rtmp_packet_destroy(&rpkt);
2194 av_log(s, AV_LOG_ERROR, "Handle notify error\n");
2198 } else if (rpkt.type == RTMP_PT_METADATA) {
2199 // we got raw FLV data, make it available for FLV demuxer
2201 rt->flv_size = rpkt.data_size;
2202 rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
2203 /* rewrite timestamps */
2205 ts = rpkt.timestamp;
2206 while (next - rpkt.data < rpkt.data_size - 11) {
2208 data_size = bytestream_get_be24(&next);
2210 cts = bytestream_get_be24(&next);
2211 cts |= bytestream_get_byte(&next) << 24;
2216 bytestream_put_be24(&p, ts);
2217 bytestream_put_byte(&p, ts >> 24);
2218 next += data_size + 3 + 4;
2220 memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
2221 ff_rtmp_packet_destroy(&rpkt);
2224 ff_rtmp_packet_destroy(&rpkt);
2228 static int rtmp_close(URLContext *h)
2230 RTMPContext *rt = h->priv_data;
2233 if (!rt->is_input) {
2234 rt->flv_data = NULL;
2235 if (rt->out_pkt.data_size)
2236 ff_rtmp_packet_destroy(&rt->out_pkt);
2237 if (rt->state > STATE_FCPUBLISH)
2238 ret = gen_fcunpublish_stream(h, rt);
2240 if (rt->state > STATE_HANDSHAKED)
2241 ret = gen_delete_stream(h, rt);
2243 free_tracked_methods(rt);
2244 av_freep(&rt->flv_data);
2245 ffurl_close(rt->stream);
2250 * Open RTMP connection and verify that the stream can be played.
2252 * URL syntax: rtmp://server[:port][/app][/playpath]
2253 * where 'app' is first one or two directories in the path
2254 * (e.g. /ondemand/, /flash/live/, etc.)
2255 * and 'playpath' is a file name (the rest of the path,
2256 * may be prefixed with "mp4:")
2258 static int rtmp_open(URLContext *s, const char *uri, int flags)
2260 RTMPContext *rt = s->priv_data;
2261 char proto[8], hostname[256], path[1024], auth[100], *fname;
2265 AVDictionary *opts = NULL;
2268 if (rt->listen_timeout > 0)
2271 rt->is_input = !(flags & AVIO_FLAG_WRITE);
2273 av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2274 hostname, sizeof(hostname), &port,
2275 path, sizeof(path), s->filename);
2278 char *ptr = strchr(auth, ':');
2281 av_strlcpy(rt->username, auth, sizeof(rt->username));
2282 av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2286 if (rt->listen && strcmp(proto, "rtmp")) {
2287 av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2289 return AVERROR(EINVAL);
2291 if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2292 if (!strcmp(proto, "rtmpts"))
2293 av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2295 /* open the http tunneling connection */
2296 ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2297 } else if (!strcmp(proto, "rtmps")) {
2298 /* open the tls connection */
2300 port = RTMPS_DEFAULT_PORT;
2301 ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2302 } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2303 if (!strcmp(proto, "rtmpte"))
2304 av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2306 /* open the encrypted connection */
2307 ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2310 /* open the tcp connection */
2312 port = RTMP_DEFAULT_PORT;
2314 ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2315 "?listen&listen_timeout=%d",
2316 rt->listen_timeout * 1000);
2318 ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2322 if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2323 &s->interrupt_callback, &opts)) < 0) {
2324 av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2328 if (rt->swfverify) {
2329 if ((ret = rtmp_calc_swfhash(s)) < 0)
2333 rt->state = STATE_START;
2334 if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2336 if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2339 rt->out_chunk_size = 128;
2340 rt->in_chunk_size = 128; // Probably overwritten later
2341 rt->state = STATE_HANDSHAKED;
2343 // Keep the application name when it has been defined by the user.
2346 rt->app = av_malloc(APP_MAX_LENGTH);
2348 ret = AVERROR(ENOMEM);
2352 //extract "app" part from path
2353 if (!strncmp(path, "/ondemand/", 10)) {
2355 memcpy(rt->app, "ondemand", 9);
2357 char *next = *path ? path + 1 : path;
2358 char *p = strchr(next, '/');
2363 // make sure we do not mismatch a playpath for an application instance
2364 char *c = strchr(p + 1, ':');
2365 fname = strchr(p + 1, '/');
2366 if (!fname || (c && c < fname)) {
2368 av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
2371 av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
2377 // The name of application has been defined by the user, override it.
2378 if (strlen(old_app) >= APP_MAX_LENGTH) {
2379 ret = AVERROR(EINVAL);
2386 if (!rt->playpath) {
2387 int len = strlen(fname);
2389 rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
2390 if (!rt->playpath) {
2391 ret = AVERROR(ENOMEM);
2395 if (!strchr(fname, ':') && len >= 4 &&
2396 (!strcmp(fname + len - 4, ".f4v") ||
2397 !strcmp(fname + len - 4, ".mp4"))) {
2398 memcpy(rt->playpath, "mp4:", 5);
2399 } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
2400 fname[len - 4] = '\0';
2402 rt->playpath[0] = 0;
2404 av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
2408 rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
2410 ret = AVERROR(ENOMEM);
2413 ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2414 port, "/%s", rt->app);
2417 if (!rt->flashver) {
2418 rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
2419 if (!rt->flashver) {
2420 ret = AVERROR(ENOMEM);
2424 snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2425 RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
2426 RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
2428 snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2429 "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2433 rt->client_report_size = 1048576;
2435 rt->last_bytes_read = 0;
2436 rt->server_bw = 2500000;
2438 av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2439 proto, path, rt->app, rt->playpath);
2441 if ((ret = gen_connect(s, rt)) < 0)
2444 if (read_connect(s, s->priv_data) < 0)
2450 ret = get_packet(s, 1);
2451 } while (ret == EAGAIN);
2455 if (rt->do_reconnect) {
2456 ffurl_close(rt->stream);
2458 rt->do_reconnect = 0;
2460 memset(rt->prev_pkt, 0, sizeof(rt->prev_pkt));
2461 free_tracked_methods(rt);
2466 // generate FLV header for demuxer
2468 rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
2470 memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
2473 rt->flv_data = NULL;
2475 rt->skip_bytes = 13;
2478 s->max_packet_size = rt->stream->max_packet_size;
2483 av_dict_free(&opts);
2488 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2490 RTMPContext *rt = s->priv_data;
2491 int orig_size = size;
2495 int data_left = rt->flv_size - rt->flv_off;
2497 if (data_left >= size) {
2498 memcpy(buf, rt->flv_data + rt->flv_off, size);
2499 rt->flv_off += size;
2502 if (data_left > 0) {
2503 memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2506 rt->flv_off = rt->flv_size;
2509 if ((ret = get_packet(s, 0)) < 0)
2515 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2517 RTMPContext *rt = s->priv_data;
2518 int size_temp = size;
2519 int pktsize, pkttype;
2521 const uint8_t *buf_temp = buf;
2526 if (rt->skip_bytes) {
2527 int skip = FFMIN(rt->skip_bytes, size_temp);
2530 rt->skip_bytes -= skip;
2534 if (rt->flv_header_bytes < 11) {
2535 const uint8_t *header = rt->flv_header;
2536 int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
2537 bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2538 rt->flv_header_bytes += copy;
2540 if (rt->flv_header_bytes < 11)
2543 pkttype = bytestream_get_byte(&header);
2544 pktsize = bytestream_get_be24(&header);
2545 ts = bytestream_get_be24(&header);
2546 ts |= bytestream_get_byte(&header) << 24;
2547 bytestream_get_be24(&header);
2548 rt->flv_size = pktsize;
2550 //force 12bytes header
2551 if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2552 pkttype == RTMP_PT_NOTIFY) {
2553 if (pkttype == RTMP_PT_NOTIFY)
2555 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
2558 //this can be a big packet, it's better to send it right here
2559 if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
2560 pkttype, ts, pktsize)) < 0)
2563 rt->out_pkt.extra = rt->main_channel_id;
2564 rt->flv_data = rt->out_pkt.data;
2566 if (pkttype == RTMP_PT_NOTIFY)
2567 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
2570 if (rt->flv_size - rt->flv_off > size_temp) {
2571 bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
2572 rt->flv_off += size_temp;
2575 bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
2576 size_temp -= rt->flv_size - rt->flv_off;
2577 rt->flv_off += rt->flv_size - rt->flv_off;
2580 if (rt->flv_off == rt->flv_size) {
2583 if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
2587 rt->flv_header_bytes = 0;
2588 rt->flv_nb_packets++;
2590 } while (buf_temp - buf < size);
2592 if (rt->flv_nb_packets < rt->flush_interval)
2594 rt->flv_nb_packets = 0;
2596 /* set stream into nonblocking mode */
2597 rt->stream->flags |= AVIO_FLAG_NONBLOCK;
2599 /* try to read one byte from the stream */
2600 ret = ffurl_read(rt->stream, &c, 1);
2602 /* switch the stream back into blocking mode */
2603 rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
2605 if (ret == AVERROR(EAGAIN)) {
2606 /* no incoming data to handle */
2608 } else if (ret < 0) {
2610 } else if (ret == 1) {
2611 RTMPPacket rpkt = { 0 };
2613 if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
2615 rt->prev_pkt[0], c)) <= 0)
2618 if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
2621 ff_rtmp_packet_destroy(&rpkt);
2627 #define OFFSET(x) offsetof(RTMPContext, x)
2628 #define DEC AV_OPT_FLAG_DECODING_PARAM
2629 #define ENC AV_OPT_FLAG_ENCODING_PARAM
2631 static const AVOption rtmp_options[] = {
2632 {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2633 {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {.i64 = 3000}, 0, INT_MAX, DEC|ENC},
2634 {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2635 {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2636 {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {.i64 = 10}, 0, INT_MAX, ENC},
2637 {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {.i64 = -2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
2638 {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
2639 {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
2640 {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
2641 {"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2642 {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2643 {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2644 {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
2645 {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
2646 {"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},
2647 {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2648 {"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},
2649 {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2650 {"timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1", OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2654 #define RTMP_PROTOCOL(flavor) \
2655 static const AVClass flavor##_class = { \
2656 .class_name = #flavor, \
2657 .item_name = av_default_item_name, \
2658 .option = rtmp_options, \
2659 .version = LIBAVUTIL_VERSION_INT, \
2662 URLProtocol ff_##flavor##_protocol = { \
2664 .url_open = rtmp_open, \
2665 .url_read = rtmp_read, \
2666 .url_write = rtmp_write, \
2667 .url_close = rtmp_close, \
2668 .priv_data_size = sizeof(RTMPContext), \
2669 .flags = URL_PROTOCOL_FLAG_NETWORK, \
2670 .priv_data_class= &flavor##_class, \
2675 RTMP_PROTOCOL(rtmpe)
2676 RTMP_PROTOCOL(rtmps)
2677 RTMP_PROTOCOL(rtmpt)
2678 RTMP_PROTOCOL(rtmpte)
2679 RTMP_PROTOCOL(rtmpts)