diff --git a/README.md b/README.md
index 930a8dd1f..dc95a7f4c 100755
--- a/README.md
+++ b/README.md
@@ -94,12 +94,8 @@ For previous versions, please read:
- [x] Support native HTTP server([CN][v3_CN_SampleHTTP], [EN][v3_EN_SampleHTTP]) for http api and http live streaming.
- [x] Support HTTP CORS for js in http api and http live streaming.
- [x] Support HTTP API([CN][v3_CN_HTTPApi], [EN][v3_EN_HTTPApi]) for system management.
-- [x] Support HTTP RAW API, please read [#459][bug #459], [#470][bug #470], [#319][bug #319].
- [x] Support HTTP callback([CN][v3_CN_HTTPCallback], [EN][v3_EN_HTTPCallback]) for authentication and integration.
-- [x] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp])
-- [x] Support Adobe FMS/AMS token traverse([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication.
- [x] Support DVR([CN][v3_CN_DVR], [EN][v3_EN_DVR]) to record live streaming to FLV file.
-- [x] Support DVR in MP4 format, read [#738][bug #738].
- [x] Support DVR control module like NGINX-RTMP, please read [#459][bug #459].
- [x] Support EXEC like NGINX-RTMP, please read [bug #367][bug #367].
- [x] Support security strategy including allow/deny publish/play IP([CN][v2_CN_Security], [EN][v2_EN_Security]).
@@ -107,7 +103,6 @@ For previous versions, please read:
- [x] Support gop-cache([CN][v3_CN_LowLatency2], [EN][v3_EN_LowLatency2]) for player fast startup.
- [x] Support Vhost([CN][v1_CN_RtmpUrlVhost], [EN][v1_EN_RtmpUrlVhost]) and \_\_defaultVhost\_\_.
- [x] Support reloading([CN][v1_CN_Reload], [EN][v1_EN_Reload]) to apply changes of config.
-- [x] Support bandwidth testing([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]) and flash client example.
- [x] Support listening at multiple ports.
- [x] Support forwarding([CN][v3_CN_Forward], [EN][v3_EN_Forward]) from master to slave server.
- [x] Support transcoding([CN][v3_CN_FFMPEG], [EN][v3_EN_FFMPEG]) live streaming by FFMPEG.
@@ -121,13 +116,19 @@ For previous versions, please read:
- [x] Support origin cluster, please read [#464][bug #464], [RTMP 302][bug #92].
- [x] Support listen at IPv4 and IPv6, read [#460][bug #460].
- [x] Support SO_REUSEPORT, to improve edge server performance, read [#775][bug #775].
-- [x] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]).
+- [x] [Experimental] Support docker by [srs-docker](https://github.com/ossrs/srs-docker).
+- [x] [Experimental] Support DVR in MP4 format, read [#738][bug #738].
- [x] [Experimental] Support MPEG-DASH, the future live streaming protocol, read [#299][bug #299].
- [x] [Experimental] Support pushing MPEG-TS over UDP, please read [bug #250][bug #250].
- [x] [Experimental] Support pushing RTSP, please read [bug #133][bug #133].
- [x] [Experimental] Support pushing FLV over HTTP POST, please read [wiki]([CN][v2_CN_Streamer2], [EN][v2_EN_Streamer2]).
- [x] [Experimental] Support multiple processes by [dolphin][srs-dolphin] or [oryx][oryx].
- [x] [Experimental] Support a simple [mgmt console][console], please read [srs-ngb][srs-ngb].
+- [x] [Experimental] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp])
+- [x] [Experimental] Support HTTP RAW API, please read [#459][bug #459], [#470][bug #470], [#319][bug #319].
+- [x] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]) and [#1535][bug #1535].
+- [x] [Deprecated] Support bandwidth testing([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]), please read [#1535][bug #1535].
+- [x] [Deprecated] Support Adobe FMS/AMS token traverse([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication, please read [#1535][bug #1535].
- [ ] Utest cover almost all kernel code.
- [ ] Enhanced forwarding with vhost and variables.
- [ ] Support source cleanup for idle streams.
@@ -147,6 +148,10 @@ For previous versions, please read:
## V3 changes
+* v3.0, 2019-12-23, Merge SRS2 for running srs-librtmp on Windows. 3.0.80
+* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate Adobe FMS/AMS edge token traversing([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication. 3.0.79
+* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate BWT(bandwidth testing)([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]). 3.0.78
+* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate Adobe HDS(f4m)([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]). 3.0.77
* v3.0, 2019-12-20, Fix [#1508][bug #1508], http-client support read chunked response. 3.0.76
* v3.0, 2019-12-20, For [#1508][bug #1508], refactor srs_is_digital, support all zeros.
* v3.0, 2019-12-19, [3.0 alpha5(3.0.75)][r3.0a5] released. 115362 lines.
@@ -248,6 +253,8 @@ For previous versions, please read:
## V2 changes
+* v2.0, 2019-12-23, Fix [srs-librtmp #22](https://github.com/ossrs/srs-librtmp/issues/22), parse vhost splited by single seperator. 2.0.268
+* v2.0, 2019-12-23, Fix [srs-librtmp #25](https://github.com/ossrs/srs-librtmp/issues/25), build srs-librtmp on windows. 2.0.267
* v2.0, 2019-12-13, Support openssl versions greater than 1.1.0. 2.0.266
* v2.0, 2019-11-29, [2.0 release7(2.0.265)][r2.0r7] released. 86994 lines.
* v2.0, 2019-11-29, For [srs-docker](https://github.com/ossrs/srs-docker/tree/master/2.0), install Cherrypy without sudo. 2.0.265
@@ -1546,6 +1553,7 @@ Winlin
[bug #1520]: https://github.com/ossrs/srs/issues/1520
[bug #1223]: https://github.com/ossrs/srs/issues/1223
[bug #1508]: https://github.com/ossrs/srs/issues/1508
+[bug #1535]: https://github.com/ossrs/srs/issues/1535
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
[bug #1111]: https://github.com/ossrs/srs/issues/1111
diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp
index ad70e2fa2..7ba2c3062 100644
--- a/trunk/src/core/srs_core.hpp
+++ b/trunk/src/core/srs_core.hpp
@@ -27,7 +27,7 @@
// The version config.
#define VERSION_MAJOR 3
#define VERSION_MINOR 0
-#define VERSION_REVISION 76
+#define VERSION_REVISION 80
// The macros generated by configure script.
#include
@@ -93,10 +93,13 @@
} \
(void)0
-// Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm
-// @reamrk To patch ST for arm, read https://github.com/ossrs/state-threads/issues/1
-#if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__)
- #error "only support i386/amd64/x86_64/arm cpu"
+// For librtmp, it is pure c++ and supports all OS.
+#ifndef SRS_EXPORT_LIBRTMP
+ // Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm
+ // @reamrk To patch ST for arm, read https://github.com/ossrs/state-threads/issues/1
+ #if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__)
+ #error "only support i386/amd64/x86_64/arm cpu"
+ #endif
#endif
// Error predefined for all modules.
diff --git a/trunk/src/kernel/srs_kernel_file.cpp b/trunk/src/kernel/srs_kernel_file.cpp
index 832b7727b..6ab9b6a54 100644
--- a/trunk/src/kernel/srs_kernel_file.cpp
+++ b/trunk/src/kernel/srs_kernel_file.cpp
@@ -129,7 +129,11 @@ srs_error_t SrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
ssize_t nwrite;
// TODO: FIXME: use st_write.
+#ifdef _WIN32
+ if ((nwrite = ::_write(fd, buf, (unsigned int)count)) < 0) {
+#else
if ((nwrite = _srs_write_fn(fd, buf, count)) < 0) {
+#endif
return srs_error_new(ERROR_SYSTEM_FILE_WRITE, "write to file %s failed", path.c_str());
}
@@ -269,7 +273,11 @@ srs_error_t SrsFileReader::read(void* buf, size_t count, ssize_t* pnread)
ssize_t nread;
// TODO: FIXME: use st_read.
+#ifdef _WIN32
+ if ((nread = _read(fd, buf, (unsigned int)count)) < 0) {
+#else
if ((nread = _srs_read_fn(fd, buf, count)) < 0) {
+#endif
return srs_error_new(ERROR_SYSTEM_FILE_READ, "read from file %s failed", path.c_str());
}
diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp
index b1f8a0cdd..4fab6985a 100644
--- a/trunk/src/kernel/srs_kernel_utility.cpp
+++ b/trunk/src/kernel/srs_kernel_utility.cpp
@@ -572,7 +572,7 @@ int srs_do_create_dir_recursively(string dir)
mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH;
if (::mkdir(dir.c_str(), mode) < 0) {
#else
- if (::mkdir(dir.c_str()) < 0) {
+ if (::_mkdir(dir.c_str()) < 0) {
#endif
if (errno == EEXIST) {
return ERROR_SYSTEM_DIR_EXISTS;
@@ -1102,9 +1102,9 @@ int srs_chunk_header_c0(int perfer_cid, uint32_t timestamp, int32_t payload_leng
*p++ = pp[1];
*p++ = pp[0];
} else {
- *p++ = 0xFF;
- *p++ = 0xFF;
- *p++ = 0xFF;
+ *p++ = (char)0xFF;
+ *p++ = (char)0xFF;
+ *p++ = (char)0xFF;
}
// message_length, 3bytes, big-endian
diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp
index 76dfe3bdc..fb3249cfc 100644
--- a/trunk/src/libs/srs_lib_simple_socket.cpp
+++ b/trunk/src/libs/srs_lib_simple_socket.cpp
@@ -92,7 +92,7 @@ struct SrsBlockSyncSocket
SOCKET_RESET(fd);
SOCKET_SETUP();
}
-
+
virtual ~SrsBlockSyncSocket() {
SOCKET_CLOSE(fd);
SOCKET_CLEANUP();
@@ -121,7 +121,7 @@ int srs_hijack_io_create_socket(srs_hijack_io_t ctx, srs_rtmp_t owner)
if (!SOCKET_VALID(skt->fd)) {
return ERROR_SOCKET_CREATE;
}
-
+
// No TCP cache.
int v = 1;
setsockopt(skt->fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
@@ -163,7 +163,7 @@ int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nre
if (nread) {
*nread = nb_read;
}
-
+
// On success a non-negative integer indicating the number of bytes actually read is returned
// (a value of 0 means the network connection is closed or end of file is reached).
if (nb_read <= 0) {
@@ -185,7 +185,15 @@ int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nre
int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
-
+
+#ifdef _WIN32
+ DWORD tv = (DWORD)(timeout_us/1000);
+
+ // To convert tv to const char* to make VS2015 happy.
+ if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
+ return SOCKET_ERRNO();
+ }
+#else
// The default for this option is zero,
// which indicates that a receive operation shall not time out.
int32_t sec = 0;
@@ -200,9 +208,10 @@ int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm)
if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
return SOCKET_ERRNO();
}
-
+#endif
+
skt->rtm = tm;
-
+
return ERROR_SUCCESS;
}
int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx)
@@ -218,21 +227,30 @@ int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx)
int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t tm)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
-
+
+#ifdef _WIN32
+ DWORD tv = (DWORD)(timeout_us/1000);
+
+ // To convert tv to const char* to make VS2015 happy.
+ if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
+ return SOCKET_ERRNO();
+ }
+#else
// The default for this option is zero,
// which indicates that a receive operation shall not time out.
int32_t sec = 0;
int32_t usec = 0;
-
+
if (tm != SRS_UTIME_NO_TIMEOUT) {
sec = (int32_t)(tm / 1000);
usec = (int32_t)((tm % 1000)*1000);
}
-
+
struct timeval tv = { sec , usec };
if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
return SOCKET_ERRNO();
}
+#endif
skt->stm = tm;
@@ -271,7 +289,7 @@ int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ss
return ERROR_SOCKET_WRITE;
}
-
+
skt->sbytes += nb_write;
return ret;
diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp
index d8430188f..143dc426e 100644
--- a/trunk/src/libs/srs_librtmp.hpp
+++ b/trunk/src/libs/srs_librtmp.hpp
@@ -44,21 +44,24 @@
*************************************************************/
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifdef _WIN32
+// To disable some security warnings.
+#define _CRT_SECURE_NO_WARNINGS
// include windows first.
#include
// the type used by this header for windows.
+#if defined(_MSC_VER)
+ #include
+#else
+ typedef char int8_t;
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef long long int64_t;
+#endif
typedef unsigned long long u_int64_t;
-typedef u_int64_t uint64_t;
-typedef long long int64_t;
typedef unsigned int u_int32_t;
typedef u_int32_t uint32_t;
-typedef int int32_t;
typedef unsigned char u_int8_t;
-typedef u_int8_t uint8_t;
-typedef char int8_t;
typedef unsigned short u_int16_t;
-typedef u_int16_t uint16_t;
-typedef short int16_t;
typedef int64_t ssize_t;
struct iovec {
void *iov_base; /* Starting address */
@@ -1175,8 +1178,6 @@ extern int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssiz
*************************************************************/
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifdef _WIN32
-// for time.
-#define _CRT_SECURE_NO_WARNINGS
#include
int gettimeofday(struct timeval* tv, struct timezone* tz);
#define PRId64 "lld"
@@ -1205,8 +1206,6 @@ typedef int mode_t;
#define open _open
#define close _close
#define lseek _lseek
-#define write _write
-#define read _read
// for socket.
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
diff --git a/trunk/src/protocol/srs_protocol_amf0.cpp b/trunk/src/protocol/srs_protocol_amf0.cpp
index 9fc5a3bcc..ae98a41c2 100644
--- a/trunk/src/protocol/srs_protocol_amf0.cpp
+++ b/trunk/src/protocol/srs_protocol_amf0.cpp
@@ -1169,7 +1169,7 @@ void SrsAmf0StrictArray::append(SrsAmf0Any* any)
int SrsAmf0Size::utf8(string value)
{
- return 2 + (int)value.length();
+ return (int)(2 + value.length());
}
int SrsAmf0Size::str(string value)
@@ -1752,7 +1752,7 @@ namespace _srs_internal
if (!stream->require(2)) {
return srs_error_new(ERROR_RTMP_AMF0_ENCODE, "requires 2 only %d bytes", stream->left());
}
- stream->write_2bytes(value.length());
+ stream->write_2bytes((int16_t)value.length());
// empty string
if (value.length() <= 0) {
diff --git a/trunk/src/protocol/srs_protocol_stream.cpp b/trunk/src/protocol/srs_protocol_stream.cpp
index dfc24d7e2..96a55c265 100755
--- a/trunk/src/protocol/srs_protocol_stream.cpp
+++ b/trunk/src/protocol/srs_protocol_stream.cpp
@@ -194,7 +194,7 @@ srs_error_t SrsFastStream::grow(ISrsReader* reader, int required_size)
// we just move the ptr to next.
srs_assert((int)nread > 0);
end += nread;
- nb_free_space -= nread;
+ nb_free_space -= (int)nread;
}
return err;
diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp
index 5095290bc..1044236a3 100644
--- a/trunk/src/protocol/srs_protocol_utility.cpp
+++ b/trunk/src/protocol/srs_protocol_utility.cpp
@@ -61,6 +61,7 @@ void srs_vhost_resolve(string& vhost, string& app, string& param)
app = srs_string_replace(app, ",", "?");
app = srs_string_replace(app, "...", "?");
app = srs_string_replace(app, "&&", "?");
+ app = srs_string_replace(app, "&", "?");
app = srs_string_replace(app, "=", "?");
if (srs_string_ends_with(app, "/_definst_")) {
@@ -78,6 +79,11 @@ void srs_vhost_resolve(string& vhost, string& app, string& param)
}
}
}
+
+ // vhost with params.
+ if ((pos = vhost.find("?")) != std::string::npos) {
+ vhost = vhost.substr(0, pos);
+ }
/* others */
}
diff --git a/trunk/src/protocol/srs_raw_avc.cpp b/trunk/src/protocol/srs_raw_avc.cpp
index b09479a3a..6b8f24b9a 100644
--- a/trunk/src/protocol/srs_raw_avc.cpp
+++ b/trunk/src/protocol/srs_raw_avc.cpp
@@ -183,7 +183,7 @@ srs_error_t SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32
// numOfSequenceParameterSets, always 1
stream.write_1bytes(0x01);
// sequenceParameterSetLength
- stream.write_2bytes(sps.length());
+ stream.write_2bytes((int16_t)sps.length());
// sequenceParameterSetNALUnit
stream.write_string(sps);
}
@@ -194,7 +194,7 @@ srs_error_t SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32
// numOfPictureParameterSets, always 1
stream.write_1bytes(0x01);
// pictureParameterSetLength
- stream.write_2bytes(pps.length());
+ stream.write_2bytes((int16_t)pps.length());
// pictureParameterSetNALUnit
stream.write_string(pps);
}
diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp
index 89105bf6f..b59a41a83 100644
--- a/trunk/src/protocol/srs_rtmp_stack.cpp
+++ b/trunk/src/protocol/srs_rtmp_stack.cpp
@@ -220,7 +220,8 @@ srs_error_t SrsPacket::encode_packet(SrsBuffer* stream)
SrsProtocol::AckWindowSize::AckWindowSize()
{
window = 0;
- sequence_number = nb_recv_bytes = 0;
+ sequence_number = 0;
+ nb_recv_bytes = 0;
}
SrsProtocol::SrsProtocol(ISrsProtocolReadWriter* io)
@@ -253,6 +254,8 @@ SrsProtocol::SrsProtocol(ISrsProtocolReadWriter* io)
cs_cache[cid] = cs;
}
+
+ out_c0c3_caches = new char[SRS_CONSTS_C0C3_HEADERS_MAX];
}
SrsProtocol::~SrsProtocol()
@@ -291,6 +294,8 @@ SrsProtocol::~SrsProtocol()
srs_freep(cs);
}
srs_freepa(cs_cache);
+
+ srs_freepa(out_c0c3_caches);
}
void SrsProtocol::set_auto_response(bool v)
@@ -2375,7 +2380,8 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser
srs_error_t err = srs_success;
SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket();
-
+
+ // @remark For windows, there must be a space between const string and macro.
pkt->props->set("fmsVer", SrsAmf0Any::str("FMS/" RTMP_SIG_FMS_VER));
pkt->props->set("capabilities", SrsAmf0Any::number(127));
pkt->props->set("mode", SrsAmf0Any::number(1));
diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp
index 79122f3d9..3a64d47bc 100644
--- a/trunk/src/protocol/srs_rtmp_stack.hpp
+++ b/trunk/src/protocol/srs_rtmp_stack.hpp
@@ -213,7 +213,8 @@ private:
// The c0c3 caches must use unit SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE bytes.
//
// @remark, the c0c3 cache cannot be realloc.
- char out_c0c3_caches[SRS_CONSTS_C0C3_HEADERS_MAX];
+ // To allocate it in heap to make VS2015 happy.
+ char* out_c0c3_caches;
// Whether warned user to increase the c0c3 header cache.
bool warned_c0c3_cache_dry;
// The output chunk size, default to 128, set by config.
diff --git a/trunk/src/utest/srs_utest_rtmp.cpp b/trunk/src/utest/srs_utest_rtmp.cpp
index 639f2ab70..09ea6cd5c 100644
--- a/trunk/src/utest/srs_utest_rtmp.cpp
+++ b/trunk/src/utest/srs_utest_rtmp.cpp
@@ -3271,6 +3271,34 @@ VOID TEST(ProtocolRTMPTest, GenerateURL)
*/
VOID TEST(ProtocolRTMPTest, DiscoveryTcUrl)
{
+ // vhost and params
+ if (true) {
+ int port; std::string tcUrl, schema, ip, vhost, app, stream, param;
+
+ tcUrl = "rtmp://127.0.0.1:19351/live?vhost=demo&token=abc"; stream= "show";
+ srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
+ EXPECT_STREQ("rtmp", schema.c_str());
+ EXPECT_STREQ("127.0.0.1", ip.c_str());
+ EXPECT_STREQ("demo", vhost.c_str());
+ EXPECT_STREQ("live", app.c_str());
+ EXPECT_STREQ("show", stream.c_str());
+ EXPECT_EQ(19351, port);
+ }
+
+ // vhost and params
+ if (true) {
+ int port; std::string tcUrl, schema, ip, vhost, app, stream, param;
+
+ tcUrl = "rtmp://127.0.0.1:19351/live"; stream= "show?vhost=demo&token=abc";
+ srs_discovery_tc_url(tcUrl, schema, ip, vhost, app, stream, port, param);
+ EXPECT_STREQ("rtmp", schema.c_str());
+ EXPECT_STREQ("127.0.0.1", ip.c_str());
+ EXPECT_STREQ("demo", vhost.c_str());
+ EXPECT_STREQ("live", app.c_str());
+ EXPECT_STREQ("show", stream.c_str());
+ EXPECT_EQ(19351, port);
+ }
+
// default vhost in param
if (true) {
int port; std::string tcUrl, schema, ip, vhost, app, stream, param;