Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions trunk/3rdparty/srs-docs/doc/srt.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 18 additions & 1 deletion trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions trunk/src/app/srs_app_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down
2 changes: 1 addition & 1 deletion trunk/src/app/srs_app_srt_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
4 changes: 1 addition & 3 deletions trunk/src/protocol/srs_protocol_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ISrsConfig> config(_srs_kernel_factory->create_config());
Expand Down
1 change: 1 addition & 0 deletions trunk/src/utest/srs_utest_manual_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_; }
Expand Down
29 changes: 23 additions & 6 deletions trunk/src/utest/srs_utest_manual_srt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand All @@ -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());
}
Expand Down Expand Up @@ -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");
Expand All @@ -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");
Expand All @@ -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");
Expand All @@ -496,14 +491,36 @@ 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");
EXPECT_STREQ(req.param_.c_str(), "vhost=srs.srt.com.cn&key1=val1&key2=val2");
}
}

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;
Expand Down
Loading