diff --git a/trunk/3rdparty/srs-docs/doc/srt.md b/trunk/3rdparty/srs-docs/doc/srt.md index 055ba3d807..b9c90620b7 100644 --- a/trunk/3rdparty/srs-docs/doc/srt.md +++ b/trunk/3rdparty/srs-docs/doc/srt.md @@ -91,6 +91,11 @@ srt_server { # Overwrite by env SRS_SRT_SERVER_DEFAULT_APP # default: live default_app live; + # Default mode + # Overwrite by env SRS_SRT_SERVER_DEFAULT_MODE + # It can be: [publish, request] + # default: request + default_mode request; # The peerlatency is set by the sender side and will notify the receiver side. # Overwrite by env SRS_SRT_SERVER_PEERLATENCY # default: 0 @@ -328,6 +333,19 @@ Here is an SRT URL with vhost support: Where: * `h`, maps to the vhost in the RTMP address +## SRT URL short format + +You may want to use a simpler and shorter streamid format. + +If the client sends a streamid that does not begin with `#!::`, streamid value will be processed as `r=` value for the full format. + +So: +* Short address: `srt://127.0.0.1:10080?streamid=livestream` +* Identical to: `srt://127.0.0.1:10080?streamid=#!::r={default_app}/livestream,m={default_mode}` + +Important: You will probably want to use a short format for publishing, so you must also set `default_mode publish;`. +Otherwise, it will be processed as a playback request by default. + ## SRT URL without streamid Some devices do not support streamid input or do not support some special characters in streamid, such as `!`, `#`, `,`, etc. In this case, you can use only `ip:port` for streaming, such as `srt://127.0.0.1:10080`. For this URL, SRS will set the streamid to `#!::r=live/livestream,m=publish` by default. diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 2fcfca22ef..2fd58117d2 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -689,6 +689,11 @@ srt_server { # Overwrite by env SRS_SRT_SERVER_DEFAULT_APP # default: live default_app live; + # Default mode + # Overwrite by env SRS_SRT_SERVER_DEFAULT_MODE + # It can be: [publish, request] + # default: request + default_mode request; # Default streamid when client doesn't provide one. # This is used when SRT client connects without setting SRTO_STREAMID socket option. # The streamid format follows SRT standard: #!::r=app/stream,m=publish|request diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index b830b02efe..0e33cdba0f 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -1935,7 +1935,7 @@ srs_error_t SrsConfig::check_normal_config() SrsConfDirective *conf = root_->get("srt_server"); for (int i = 0; conf && i < (int)conf->directives_.size(); i++) { string n = conf->at(i)->name_; - if (n != "enabled" && n != "listen" && n != "maxbw" && n != "mss" && n != "latency" && n != "recvlatency" && n != "peerlatency" && n != "connect_timeout" && n != "peer_idle_timeout" && n != "sendbuf" && n != "recvbuf" && n != "payloadsize" && n != "default_app" && n != "sei_filter" && n != "mix_correct" && n != "tlpktdrop" && n != "tsbpdmode" && n != "passphrase" && n != "pbkeylen" && n != "default_streamid") { + if (n != "enabled" && n != "listen" && n != "maxbw" && n != "mss" && n != "latency" && n != "recvlatency" && n != "peerlatency" && n != "connect_timeout" && n != "peer_idle_timeout" && n != "sendbuf" && n != "recvbuf" && n != "payloadsize" && n != "default_app" && n != "sei_filter" && n != "mix_correct" && n != "tlpktdrop" && n != "tsbpdmode" && n != "passphrase" && n != "pbkeylen" && n != "default_streamid" && n != "default_mode") { return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal srt_server.%s", n.c_str()); } } @@ -7670,6 +7670,23 @@ string SrsConfig::get_default_app_name() return conf->arg0(); } +string SrsConfig::get_srt_default_mode() +{ + SRS_OVERWRITE_BY_ENV_STRING("srs.srt_server.default_mode"); // SRS_SRT_SERVER_DEFAULT_MODE + + static string DEFAULT = "request"; + SrsConfDirective *conf = root_->get("srt_server"); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("default_mode"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + return conf->arg0(); +} + string SrsConfig::get_srt_default_streamid() { SRS_OVERWRITE_BY_ENV_STRING("srs.srt_server.default_streamid"); // SRS_SRT_SERVER_DEFAULT_STREAMID diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 2c8ae2e827..9334b54650 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -487,6 +487,7 @@ class ISrsAppConfig : public ISrsConfig virtual bool get_rtc_keep_original_ssrc(std::string vhost) = 0; virtual bool get_srt_enabled() = 0; virtual bool get_srt_enabled(std::string vhost) = 0; + virtual std::string get_srt_default_mode() = 0; virtual std::string get_srt_default_streamid() = 0; virtual bool get_srt_to_rtmp(std::string vhost) = 0; virtual bool get_rtc_to_rtmp(std::string vhost) = 0; @@ -1076,6 +1077,8 @@ class SrsConfig : public ISrsAppConfig virtual int get_srto_pbkeylen(); // Get the default app. virtual std::string get_default_app_name(); + // Get the default mode. + virtual std::string get_srt_default_mode(); // Get the default streamid when client doesn't provide one. virtual std::string get_srt_default_streamid(); diff --git a/trunk/src/app/srs_app_srt_conn.cpp b/trunk/src/app/srs_app_srt_conn.cpp index c9ae19a3a2..76120ebe14 100644 --- a/trunk/src/app/srs_app_srt_conn.cpp +++ b/trunk/src/app/srs_app_srt_conn.cpp @@ -343,7 +343,7 @@ srs_error_t SrsMpegtsSrtConn::do_cycle() } // Detect streamid of srt to request. - SrtMode mode = SrtModePull; + SrtMode mode = config_->get_srt_default_mode() == "publish" ? SrtModePush : SrtModePull; if (!srs_srt_streamid_to_request(streamid, mode, req_)) { return srs_error_new(ERROR_SRT_CONN, "invalid srt streamid=%s", streamid.c_str()); } diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp index 0944d01c03..2c9c738546 100644 --- a/trunk/src/protocol/srs_protocol_utility.cpp +++ b/trunk/src/protocol/srs_protocol_utility.cpp @@ -755,10 +755,8 @@ utsname *SrsProtocolUtility::system_uname() // TODO: FIMXE: We should parse SRT streamid to URL object, rather than a HTTP url subpath. bool srs_srt_streamid_info(const std::string &streamid, SrtMode &mode, std::string &vhost, std::string &url_subpath) { - mode = SrtModePull; - size_t pos = streamid.find("#!::"); - if (pos != 0) { + if (pos != 0 || pos == string::npos) { pos = streamid.find("/"); if (pos == streamid.npos) { SrsUniquePtr config(_srs_kernel_factory->create_config()); diff --git a/trunk/src/utest/srs_utest_manual_mock.hpp b/trunk/src/utest/srs_utest_manual_mock.hpp index ba4ed6be66..59c8eaba1c 100644 --- a/trunk/src/utest/srs_utest_manual_mock.hpp +++ b/trunk/src/utest/srs_utest_manual_mock.hpp @@ -533,6 +533,7 @@ class MockAppConfig : public ISrsAppConfig virtual bool get_srt_enabled() { return srt_enabled_; } virtual bool get_srt_enabled(std::string vhost) { return srt_enabled_; } virtual std::string get_srt_default_streamid() { return "#!::r=live/livestream,m=request"; } + virtual std::string get_srt_default_mode() { return "request"; } virtual bool get_srt_to_rtmp(std::string vhost) { return srt_to_rtmp_; } virtual srs_utime_t get_srto_peeridletimeout() { return 10 * SRS_UTIME_SECONDS; } virtual bool get_rtc_to_rtmp(std::string vhost) { return rtc_to_rtmp_; } diff --git a/trunk/src/utest/srs_utest_manual_srt.cpp b/trunk/src/utest/srs_utest_manual_srt.cpp index d2d7faadf0..1c1fe6afbf 100644 --- a/trunk/src/utest/srs_utest_manual_srt.cpp +++ b/trunk/src/utest/srs_utest_manual_srt.cpp @@ -365,7 +365,6 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoNormal) string vhost; string subpath; EXPECT_TRUE(srs_srt_streamid_info("#!::r=live/livestream,key1=value1,key2=value2", mode, vhost, subpath)); - EXPECT_EQ(SrtModePull, mode); EXPECT_STREQ("", vhost.c_str()); EXPECT_STREQ("live/livestream?key1=value1&key2=value2", subpath.c_str()); } @@ -375,7 +374,6 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoNormal) string vhost; string subpath; EXPECT_TRUE(srs_srt_streamid_info("#!::h=host.com,r=live/livestream,key1=value1,key2=value2", mode, vhost, subpath)); - EXPECT_EQ(SrtModePull, mode); EXPECT_STREQ("host.com", vhost.c_str()); EXPECT_STREQ("live/livestream?vhost=host.com&key1=value1&key2=value2", subpath.c_str()); } @@ -463,7 +461,6 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest) SrtMode mode; SrsRequest req; EXPECT_TRUE(srs_srt_streamid_to_request("#!::r=live/livestream?key1=val1,key2=val2", mode, &req)); - EXPECT_EQ(mode, SrtModePull); EXPECT_STREQ(req.vhost_.c_str(), utility.public_internet_address().c_str()); EXPECT_STREQ(req.app_.c_str(), "live"); EXPECT_STREQ(req.stream_.c_str(), "livestream"); @@ -474,7 +471,6 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest) SrtMode mode; SrsRequest req; EXPECT_TRUE(srs_srt_streamid_to_request("#!::h=srs.srt.com.cn,r=live/livestream?key1=val1,key2=val2", mode, &req)); - EXPECT_EQ(mode, SrtModePull); EXPECT_STREQ(req.vhost_.c_str(), "srs.srt.com.cn"); EXPECT_STREQ(req.app_.c_str(), "live"); EXPECT_STREQ(req.stream_.c_str(), "livestream"); @@ -485,7 +481,6 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest) SrtMode mode; SrsRequest req; EXPECT_TRUE(srs_srt_streamid_to_request("#!::h=live/livestream?key1=val1,key2=val2", mode, &req)); - EXPECT_EQ(mode, SrtModePull); EXPECT_STREQ(req.vhost_.c_str(), utility.public_internet_address().c_str()); EXPECT_STREQ(req.app_.c_str(), "live"); EXPECT_STREQ(req.stream_.c_str(), "livestream"); @@ -496,7 +491,6 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest) SrtMode mode; SrsRequest req; EXPECT_TRUE(srs_srt_streamid_to_request("#!::h=srs.srt.com.cn/live/livestream?key1=val1,key2=val2", mode, &req)); - EXPECT_EQ(mode, SrtModePull); EXPECT_STREQ(req.vhost_.c_str(), "srs.srt.com.cn"); EXPECT_STREQ(req.app_.c_str(), "live"); EXPECT_STREQ(req.stream_.c_str(), "livestream"); @@ -504,6 +498,29 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest) } } +VOID TEST(ProtocolSrtTest, SrtShortStreamId) +{ + SrsProtocolUtility utility; + + if (true) { + SrtMode mode; + SrsRequest req; + + EXPECT_TRUE(srs_srt_streamid_to_request("testapp/livestream", mode, &req)); + EXPECT_STREQ(req.app_.c_str(), "testapp"); + EXPECT_STREQ(req.stream_.c_str(), "livestream"); + } + + if (true) { + SrtMode mode; + SrsRequest req; + + EXPECT_TRUE(srs_srt_streamid_to_request("livestream", mode, &req)); + EXPECT_STREQ(req.app_.c_str(), "live"); + EXPECT_STREQ(req.stream_.c_str(), "livestream"); + } +} + VOID TEST(ServiceSRTTest, Encrypt) { srs_error_t err = srs_success;