diff --git a/trunk/3rdparty/srs-docs/doc/getting-started-cdk.md b/trunk/3rdparty/srs-docs/doc/getting-started-cdk.md
new file mode 100644
index 000000000..0c4e63041
--- /dev/null
+++ b/trunk/3rdparty/srs-docs/doc/getting-started-cdk.md
@@ -0,0 +1,13 @@
+---
+title: CDK
+sidebar_label: CDK
+hide_title: false
+hide_table_of_contents: false
+---
+
+# CDK
+
+Please use [srs-cdk](https://github.com/ossrs/srs-cdk) to deploy SRS on AWS.
+
+
+
diff --git a/trunk/3rdparty/srs-docs/doc/getting-started-k8s.md b/trunk/3rdparty/srs-docs/doc/getting-started-k8s.md
index a78a12a78..1312ba07d 100644
--- a/trunk/3rdparty/srs-docs/doc/getting-started-k8s.md
+++ b/trunk/3rdparty/srs-docs/doc/getting-started-k8s.md
@@ -7,14 +7,16 @@ hide_table_of_contents: false
# K8s
-We recommend using the HELM method to deploy SRS, see [srs-helm](https://github.com/ossrs/srs-helm). Of course,
+> **Note:** SRS K8s is deprecated. Please use [CDK](./getting-started-cdk.md) instead.
+
+We recommend using the HELM method to deploy SRS, see [srs-helm](https://github.com/ossrs/srs-helm). Of course,
SRS also supports direct deployment with K8s, refer to [SRS K8s](./k8s.md).
-Actually, HELM is based on K8s and deploys K8s pods, which can be managed with kubectl. However, HELM offers a
+Actually, HELM is based on K8s and deploys K8s pods, which can be managed with kubectl. However, HELM offers a
more convenient way to manage and install applications, so SRS will mainly support HELM in the future.
-Compared to Docker, HELM and K8s are mainly for medium to large scale deployments. If your business is not that
-big, we recommend using Docker or Oryx directly. Generally, if you have less than a thousand streams, please
+Compared to Docker, HELM and K8s are mainly for medium to large scale deployments. If your business is not that
+big, we recommend using Docker or Oryx directly. Generally, if you have less than a thousand streams, please
do not use HELM or K8s.

diff --git a/trunk/3rdparty/srs-docs/doc/k8s.md b/trunk/3rdparty/srs-docs/doc/k8s.md
index b92983373..0b031feaa 100644
--- a/trunk/3rdparty/srs-docs/doc/k8s.md
+++ b/trunk/3rdparty/srs-docs/doc/k8s.md
@@ -7,6 +7,8 @@ hide_table_of_contents: false
# K8S
+> **Note:** SRS K8s is deprecated. Please use [CDK](./getting-started-cdk.md) instead.
+
> Cloud+Docker+K8S enable everyone to build live video streaming cluster and service.
Why should you use [k8s](https://docs.kubernetes.io/docs/concepts/overview/what-is-kubernetes) to build your SRS cluster?
diff --git a/trunk/3rdparty/srs-docs/doc/srt.md b/trunk/3rdparty/srs-docs/doc/srt.md
index 055ba3d80..a9e2dab7b 100644
--- a/trunk/3rdparty/srs-docs/doc/srt.md
+++ b/trunk/3rdparty/srs-docs/doc/srt.md
@@ -58,12 +58,13 @@ srt_server {
# Overwrite by env SRS_SRT_SERVER_ENABLED
# default: off
enabled on;
- # The UDP listen port for SRT.
+ # The UDP listen endpoints for SRT, each with format as <[ip:]port>. The ip can be either ipv4 or ipv6,
+ # or both. For example:
+ # listen 10080 [::]:10080 192.168.1.100:10080 10.10.10.100:10080;
# Overwrite by env SRS_SRT_SERVER_LISTEN
listen 10080;
# For detail parameters, please read wiki:
- # @see https://ossrs.net/lts/zh-cn/docs/v5/doc/srt-params
- # @see https://ossrs.io/lts/en-us/docs/v5/doc/srt-params
+ # @see https://ossrs.io/lts/en-us/docs/v7/doc/srt#config
# The maxbw is the max bandwidth of the sender side.
# -1: Means the biggest bandwidth is infinity.
# 0: Means the bandwidth is determined by SRTO_INPUTBW.
@@ -77,12 +78,12 @@ srt_server {
# Overwrite by env SRS_SRT_SERVER_MSS
# default: 1500
mss 1500;
- # The timeout time of the SRT connection on the sender side in ms. When SRT connects to a peer costs time
+ # The timeout time of the SRT connection on the sender side in ms. When SRT connects to a peer costs time
# more than this config, it will be close.
# Overwrite by env SRS_SRT_SERVER_CONNECT_TIMEOUT
# default: 3000
connect_timeout 4000;
- # The timeout time of SRT connection on the receiver side in ms. When the SRT connection is idle
+ # The timeout time of SRT connection on the receiver side in ms. When the SRT connection is idle
# more than this config, it will be close.
# Overwrite by env SRS_SRT_SERVER_PEER_IDLE_TIMEOUT
# default: 10000
@@ -91,36 +92,52 @@ srt_server {
# Overwrite by env SRS_SRT_SERVER_DEFAULT_APP
# default: live
default_app live;
- # The peerlatency is set by the sender side and will notify the receiver side.
+ # Default mode for short streamid format (without #!:: prefix).
+ # When client uses short streamid like "live/stream" or "stream", this config
+ # determines whether it's a publisher or player by default.
+ # Options: publish, request
+ # - publish: short streamid is treated as publisher
+ # - request: short streamid is treated as player (default)
+ # Example: with default_mode=publish, "srt://host:port?streamid=live/stream" publishes.
+ # Overwrite by env SRS_SRT_SERVER_DEFAULT_MODE
+ # 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
+ # Overwrite by env SRS_SRT_SERVER_DEFAULT_STREAMID
+ # default: #!::r=live/livestream,m=request
+ default_streamid "#!::r=live/livestream,m=request";
+ # The peerlatency is set by the sender side and will notify the receiver side.
# Overwrite by env SRS_SRT_SERVER_PEERLATENCY
# default: 0
peerlatency 0;
- # The recvlatency means latency from sender to receiver.
+ # The recvlatency means latency from sender to receiver.
# Overwrite by env SRS_SRT_SERVER_RECVLATENCY
# default: 120
recvlatency 0;
- # This latency configuration configures both recvlatency and peerlatency to the same value.
+ # This latency configuration configures both recvlatency and peerlatency to the same value.
# Overwrite by env SRS_SRT_SERVER_LATENCY
# default: 120
latency 0;
- # The tsbpd mode means timestamp based packet delivery.
- # SRT sender side will pack timestamp in each packet. If this config is true,
- # the receiver will read the packet according to the timestamp in the head of the packet.
+ # The tsbpd mode means timestamp based packet delivery.
+ # SRT sender side will pack timestamp in each packet. If this config is true,
+ # the receiver will read the packet according to the timestamp in the head of the packet.
# Overwrite by env SRS_SRT_SERVER_TSBPDMODE
# default: on
tsbpdmode off;
- # The tlpkdrop means too-late Packet Drop
- # SRT sender side will pack timestamp in each packet, When the network is congested,
- # the packet will drop if latency is bigger than the configuration in both sender side and receiver side.
- # And on the sender side, it also will be dropped because latency is bigger than configuration.
+ # The tlpkdrop means too-late Packet Drop
+ # SRT sender side will pack timestamp in each packet, When the network is congested,
+ # the packet will drop if latency is bigger than the configuration in both sender side and receiver side.
+ # And on the sender side, it also will be dropped because latency is bigger than configuration.
# Overwrite by env SRS_SRT_SERVER_TLPKTDROP
# default: on
tlpktdrop off;
- # The send buffer size of SRT.
+ # The send buffer size of SRT.
# Overwrite by env SRS_SRT_SERVER_SENDBUF
# default: 8192 * (1500-28)
sendbuf 2000000;
- # The recv buffer size of SRT.
+ # The recv buffer size of SRT.
# Overwrite by env SRS_SRT_SERVER_RECVBUF
# default: 8192 * (1500-28)
recvbuf 2000000;
@@ -336,6 +353,64 @@ In other words, the following two addresses are equivalent:
* `srt://127.0.0.1:10080`
* `srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish`
+## SRT URL with short streamid
+
+SRS supports a short streamid format without the `#!::` prefix for simpler URLs. When using short streamid format like `live/livestream` or just `livestream`, SRS uses the `default_mode` configuration to determine whether it's a publish or play request.
+
+The `default_mode` configuration accepts two values:
+* `publish`: Short streamid will be treated as publish/push mode.
+* `request`: Short streamid will be treated as request/play/pull mode (this is the default).
+
+For publisher-friendly setup where clients can push with simple URLs, configure `default_mode` to `publish`:
+
+```bash
+srt_server {
+ enabled on;
+ listen 10080;
+ # Short streamid format will be treated as publisher
+ default_mode publish;
+}
+```
+
+With this configuration, you can publish with a simple URL:
+
+```bash
+# Publish with short streamid (uses default_mode=publish)
+ffmpeg -re -i source.flv -c copy -pes_payload_size 0 -f mpegts \
+ 'srt://127.0.0.1:10080?streamid=live/livestream'
+
+# Play with explicit mode (must specify m=request)
+ffplay 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request'
+```
+
+For player-friendly setup where clients can play with simple URLs, use the default `default_mode=request`:
+
+```bash
+srt_server {
+ enabled on;
+ listen 10080;
+ # Short streamid format will be treated as player (default)
+ default_mode request;
+}
+```
+
+With this configuration, you can play with a simple URL:
+
+```bash
+# Publish with explicit mode (must specify m=publish)
+ffmpeg -re -i source.flv -c copy -pes_payload_size 0 -f mpegts \
+ 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'
+
+# Play with short streamid (uses default_mode=request)
+ffplay 'srt://127.0.0.1:10080?streamid=live/livestream'
+```
+
+SRS provides two ready-to-use configuration files:
+* `conf/srt.shortstreamid.publish.conf`: For publisher-friendly setup with `default_mode publish`.
+* `conf/srt.shortstreamid.play.conf`: For player-friendly setup with `default_mode request`.
+
+Note that explicit mode specification with the full `#!::` prefix always takes precedence over `default_mode`. This allows clients that support full streamid format to override the default behavior.
+
## Authentication
For the definition of SRT URLs, please refer to [SRT URL Schema](#srt-url).
diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf
index 2fcfca22e..f9bfdbe41 100644
--- a/trunk/conf/full.conf
+++ b/trunk/conf/full.conf
@@ -689,6 +689,16 @@ srt_server {
# Overwrite by env SRS_SRT_SERVER_DEFAULT_APP
# default: live
default_app live;
+ # Default mode for short streamid format (without #!:: prefix).
+ # When client uses short streamid like "live/stream" or "stream", this config
+ # determines whether it's a publisher or player by default.
+ # Options: publish, request
+ # - publish: short streamid is treated as publisher
+ # - request: short streamid is treated as player (default)
+ # Example: with default_mode=publish, "srt://host:port?streamid=live/stream" publishes.
+ # Overwrite by env SRS_SRT_SERVER_DEFAULT_MODE
+ # 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/conf/srt.shortstreamid.play.conf b/trunk/conf/srt.shortstreamid.play.conf
new file mode 100644
index 000000000..3d72a49a1
--- /dev/null
+++ b/trunk/conf/srt.shortstreamid.play.conf
@@ -0,0 +1,51 @@
+# SRT with short streamid format and default_mode=request (play/pull)
+# For publishing: ffmpeg -re -i source.flv -c copy -pes_payload_size 0 -f mpegts 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'
+# For playing: ffprobe 'srt://127.0.0.1:10080?streamid=live/livestream'
+# For playing HTTP-FLV: ffprobe 'http://127.0.0.1:8080/live/livestream.flv'
+
+listen 1935;
+max_connections 1000;
+daemon off;
+srs_log_tank console;
+
+http_api {
+ enabled on;
+ listen 1985;
+}
+
+http_server {
+ enabled on;
+ listen 8080;
+ dir ./objs/nginx/html;
+}
+
+srt_server {
+ enabled on;
+ listen 10080;
+ maxbw 1000000000;
+ connect_timeout 4000;
+ peerlatency 0;
+ recvlatency 0;
+ latency 0;
+ tsbpdmode off;
+ tlpktdrop off;
+ sendbuf 2000000;
+ recvbuf 2000000;
+ payloadsize 1316;
+ # Short streamid format (without #!::) will be treated as player/puller by default.
+ # This allows: srt://host:port?streamid=live/stream to play directly.
+ default_mode request;
+}
+
+vhost __defaultVhost__ {
+ srt {
+ enabled on;
+ srt_to_rtmp on;
+ }
+
+ http_remux {
+ enabled on;
+ mount [vhost]/[app]/[stream].flv;
+ }
+}
+
diff --git a/trunk/conf/srt.shortstreamid.publish.conf b/trunk/conf/srt.shortstreamid.publish.conf
new file mode 100644
index 000000000..de7421cb6
--- /dev/null
+++ b/trunk/conf/srt.shortstreamid.publish.conf
@@ -0,0 +1,51 @@
+# SRT with short streamid format and default_mode=publish
+# For publishing: ffmpeg -re -i source.flv -c copy -pes_payload_size 0 -f mpegts 'srt://127.0.0.1:10080?streamid=live/livestream'
+# For playing: ffprobe 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request'
+# For playing HTTP-FLV: ffprobe 'http://127.0.0.1:8080/live/livestream.flv'
+
+listen 1935;
+max_connections 1000;
+daemon off;
+srs_log_tank console;
+
+http_api {
+ enabled on;
+ listen 1985;
+}
+
+http_server {
+ enabled on;
+ listen 8080;
+ dir ./objs/nginx/html;
+}
+
+srt_server {
+ enabled on;
+ listen 10080;
+ maxbw 1000000000;
+ connect_timeout 4000;
+ peerlatency 0;
+ recvlatency 0;
+ latency 0;
+ tsbpdmode off;
+ tlpktdrop off;
+ sendbuf 2000000;
+ recvbuf 2000000;
+ payloadsize 1316;
+ # Short streamid format (without #!::) will be treated as publisher by default.
+ # This allows: srt://host:port?streamid=live/stream to publish directly.
+ default_mode publish;
+}
+
+vhost __defaultVhost__ {
+ srt {
+ enabled on;
+ srt_to_rtmp on;
+ }
+
+ http_remux {
+ enabled on;
+ mount [vhost]/[app]/[stream].flv;
+ }
+}
+
diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index fcadc6e4d..7c0ad9f30 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 7.0 Changelog
+* v7.0, 2025-11-30, SRT: Support default_mode config for short streamid format. v7.0.131
* v7.0, 2025-11-28, SRT: Fix player not exiting when publisher disconnects. v7.0.130 (#4591)
* v7.0, 2025-11-27, Merge [#4588](https://github.com/ossrs/srs/pull/4588): RTMP: Ignore FMLE start packet after flash publish. v7.0.129 (#4588)
* v7.0, 2025-11-18, AI: API: Change pagination default count to 10, minimum 1. v7.0.128
diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp
index b830b02ef..0937184a3 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());
}
}
@@ -7687,6 +7687,23 @@ string SrsConfig::get_srt_default_streamid()
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();
+}
+
SrsConfDirective *SrsConfig::get_srt(std::string vhost)
{
SrsConfDirective *conf = get_vhost(vhost);
diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp
index 2c8ae2e82..caac94ad9 100644
--- a/trunk/src/app/srs_app_config.hpp
+++ b/trunk/src/app/srs_app_config.hpp
@@ -488,6 +488,7 @@ public:
virtual bool get_srt_enabled() = 0;
virtual bool get_srt_enabled(std::string vhost) = 0;
virtual std::string get_srt_default_streamid() = 0;
+ virtual std::string get_srt_default_mode() = 0;
virtual bool get_srt_to_rtmp(std::string vhost) = 0;
virtual bool get_rtc_to_rtmp(std::string vhost) = 0;
virtual srs_utime_t get_rtc_stun_timeout(std::string vhost) = 0;
@@ -1078,6 +1079,9 @@ public:
virtual std::string get_default_app_name();
// Get the default streamid when client doesn't provide one.
virtual std::string get_srt_default_streamid();
+ // Get the default mode for short streamid format.
+ // @return "publish" or "request", default is "request".
+ virtual std::string get_srt_default_mode();
// clang-format off
SRS_DECLARE_PRIVATE: // clang-format on
diff --git a/trunk/src/app/srs_app_factory.cpp b/trunk/src/app/srs_app_factory.cpp
index 2a18d0213..6819006e0 100644
--- a/trunk/src/app/srs_app_factory.cpp
+++ b/trunk/src/app/srs_app_factory.cpp
@@ -299,6 +299,11 @@ std::string SrsConfigProxy::get_default_app_name()
{
return _srs_config->get_default_app_name();
}
+
+std::string SrsConfigProxy::get_srt_default_mode()
+{
+ return _srs_config->get_srt_default_mode();
+}
// LCOV_EXCL_STOP
SrsTrueTime::SrsTrueTime()
diff --git a/trunk/src/app/srs_app_factory.hpp b/trunk/src/app/srs_app_factory.hpp
index 208bc6fdd..4bd7c44c7 100644
--- a/trunk/src/app/srs_app_factory.hpp
+++ b/trunk/src/app/srs_app_factory.hpp
@@ -189,6 +189,7 @@ public:
public:
virtual srs_utime_t get_pithy_print();
virtual std::string get_default_app_name();
+ virtual std::string get_srt_default_mode();
};
// The time to use system time.
diff --git a/trunk/src/app/srs_app_srt_conn.cpp b/trunk/src/app/srs_app_srt_conn.cpp
index c9ae19a3a..39ac758df 100644
--- a/trunk/src/app/srs_app_srt_conn.cpp
+++ b/trunk/src/app/srs_app_srt_conn.cpp
@@ -344,7 +344,7 @@ srs_error_t SrsMpegtsSrtConn::do_cycle()
// Detect streamid of srt to request.
SrtMode mode = SrtModePull;
- if (!srs_srt_streamid_to_request(streamid, mode, req_)) {
+ if (!srs_srt_streamid_to_request(config_, streamid, mode, req_)) {
return srs_error_new(ERROR_SRT_CONN, "invalid srt streamid=%s", streamid.c_str());
}
diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp
index e43b7fc68..33b21501d 100644
--- a/trunk/src/core/srs_core_version7.hpp
+++ b/trunk/src/core/srs_core_version7.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
-#define VERSION_REVISION 130
+#define VERSION_REVISION 131
#endif
\ No newline at end of file
diff --git a/trunk/src/kernel/srs_kernel_factory.hpp b/trunk/src/kernel/srs_kernel_factory.hpp
index 78ecaa1c7..5fbb67eec 100644
--- a/trunk/src/kernel/srs_kernel_factory.hpp
+++ b/trunk/src/kernel/srs_kernel_factory.hpp
@@ -24,6 +24,9 @@ public:
public:
virtual srs_utime_t get_pithy_print() = 0;
virtual std::string get_default_app_name() = 0;
+ // Get the default mode for short streamid format.
+ // @return "publish" or "request", default is "request".
+ virtual std::string get_srt_default_mode() = 0;
};
// The factory to create kernel objects.
diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp
index 0944d01c0..c2aa45a1e 100644
--- a/trunk/src/protocol/srs_protocol_utility.cpp
+++ b/trunk/src/protocol/srs_protocol_utility.cpp
@@ -753,15 +753,20 @@ utsname *SrsProtocolUtility::system_uname()
// See streamid of https://github.com/ossrs/srs/issues/2893
// 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)
+bool srs_srt_streamid_info(ISrsConfig *config, const std::string &streamid, SrtMode &mode, std::string &vhost, std::string &url_subpath)
{
mode = SrtModePull;
size_t pos = streamid.find("#!::");
if (pos != 0) {
+ // Short format without #!:: prefix, use default_mode config.
+ std::string default_mode = config->get_srt_default_mode();
+ if (default_mode == "publish") {
+ mode = SrtModePush;
+ }
+
pos = streamid.find("/");
if (pos == streamid.npos) {
- SrsUniquePtr config(_srs_kernel_factory->create_config());
url_subpath = config->get_default_app_name() + "/" + streamid;
return true;
}
@@ -849,10 +854,10 @@ bool srs_srt_streamid_info(const std::string &streamid, SrtMode &mode, std::stri
return true;
}
-bool srs_srt_streamid_to_request(const std::string &streamid, SrtMode &mode, ISrsRequest *request)
+bool srs_srt_streamid_to_request(ISrsConfig *config, const std::string &streamid, SrtMode &mode, ISrsRequest *request)
{
string url_subpath = "";
- bool ret = srs_srt_streamid_info(streamid, mode, request->vhost_, url_subpath);
+ bool ret = srs_srt_streamid_info(config, streamid, mode, request->vhost_, url_subpath);
if (!ret) {
return ret;
}
@@ -860,7 +865,6 @@ bool srs_srt_streamid_to_request(const std::string &streamid, SrtMode &mode, ISr
size_t pos = url_subpath.find("/");
string stream_with_params = "";
if (pos == string::npos) {
- SrsUniquePtr config(_srs_kernel_factory->create_config());
request->app_ = config->get_default_app_name();
stream_with_params = url_subpath;
} else {
diff --git a/trunk/src/protocol/srs_protocol_utility.hpp b/trunk/src/protocol/srs_protocol_utility.hpp
index 125bd7800..56a84c251 100644
--- a/trunk/src/protocol/srs_protocol_utility.hpp
+++ b/trunk/src/protocol/srs_protocol_utility.hpp
@@ -32,6 +32,7 @@
#include
class ISrsHttpMessage;
+class ISrsConfig;
class SrsMessageHeader;
class SrsMediaPacket;
@@ -169,9 +170,11 @@ enum SrtMode {
};
// Get SRT streamid info.
-extern bool srs_srt_streamid_info(const std::string &streamid, SrtMode &mode, std::string &vhost, std::string &url_subpath);
+// @param config The config to get default_app and default_mode.
+extern bool srs_srt_streamid_info(ISrsConfig *config, const std::string &streamid, SrtMode &mode, std::string &vhost, std::string &url_subpath);
// SRT streamid to request.
-extern bool srs_srt_streamid_to_request(const std::string &streamid, SrtMode &mode, ISrsRequest *request);
+// @param config The config to get default_app and default_mode.
+extern bool srs_srt_streamid_to_request(ISrsConfig *config, const std::string &streamid, SrtMode &mode, ISrsRequest *request);
#endif
diff --git a/trunk/src/utest/srs_utest_manual_mock.hpp b/trunk/src/utest/srs_utest_manual_mock.hpp
index ba4ed6be6..0835e66b9 100644
--- a/trunk/src/utest/srs_utest_manual_mock.hpp
+++ b/trunk/src/utest/srs_utest_manual_mock.hpp
@@ -326,6 +326,7 @@ public:
bool rtc_enabled_;
bool rtc_init_rate_from_sdp_;
bool asprocess_;
+ std::string srt_default_mode_;
public:
MockAppConfig()
@@ -357,6 +358,7 @@ public:
rtc_enabled_ = false;
rtc_init_rate_from_sdp_ = false;
asprocess_ = false;
+ srt_default_mode_ = "request";
}
virtual ~MockAppConfig()
{
@@ -533,6 +535,7 @@ public:
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 srt_default_mode_; }
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 d2d7faadf..a5bd92e4b 100644
--- a/trunk/src/utest/srs_utest_manual_srt.cpp
+++ b/trunk/src/utest/srs_utest_manual_srt.cpp
@@ -360,11 +360,13 @@ VOID TEST(SrtServerTest, SrtListener)
// Test srt app
VOID TEST(ProtocolSrtTest, SrtGetStreamInfoNormal)
{
+ MockAppConfig config;
+
if (true) {
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::r=live/livestream,key1=value1,key2=value2", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::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());
@@ -374,7 +376,7 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoNormal)
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::h=host.com,r=live/livestream,key1=value1,key2=value2", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::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());
@@ -383,11 +385,13 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoNormal)
VOID TEST(ProtocolSrtTest, SrtGetStreamInfoMethod)
{
+ MockAppConfig config;
+
if (true) {
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::r=live/livestream,m=request", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::r=live/livestream,m=request", mode, vhost, subpath));
EXPECT_EQ(SrtModePull, mode);
EXPECT_STREQ("live/livestream", subpath.c_str());
}
@@ -396,7 +400,7 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoMethod)
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::r=live/livestream,m=publish", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::r=live/livestream,m=publish", mode, vhost, subpath));
EXPECT_EQ(SrtModePush, mode);
EXPECT_STREQ("live/livestream", subpath.c_str());
}
@@ -404,11 +408,13 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoMethod)
VOID TEST(ProtocolSrtTest, SrtGetStreamInfoCompatible)
{
+ MockAppConfig config;
+
if (true) {
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::h=live/livestream,m=request", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::h=live/livestream,m=request", mode, vhost, subpath));
EXPECT_EQ(SrtModePull, mode);
EXPECT_STREQ("", vhost.c_str());
EXPECT_STREQ("live/livestream", subpath.c_str());
@@ -418,7 +424,7 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoCompatible)
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::h=live/livestream,m=publish", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::h=live/livestream,m=publish", mode, vhost, subpath));
EXPECT_EQ(SrtModePush, mode);
EXPECT_STREQ("", vhost.c_str());
EXPECT_STREQ("live/livestream", subpath.c_str());
@@ -428,7 +434,7 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoCompatible)
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::h=srs.srt.com.cn/live/livestream,m=request", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::h=srs.srt.com.cn/live/livestream,m=request", mode, vhost, subpath));
EXPECT_EQ(SrtModePull, mode);
EXPECT_STREQ("srs.srt.com.cn", vhost.c_str());
EXPECT_STREQ("live/livestream?vhost=srs.srt.com.cn", subpath.c_str());
@@ -438,7 +444,7 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoCompatible)
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::h=srs.srt.com.cn/live/livestream,m=publish", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::h=srs.srt.com.cn/live/livestream,m=publish", mode, vhost, subpath));
EXPECT_EQ(SrtModePush, mode);
EXPECT_STREQ("srs.srt.com.cn", vhost.c_str());
EXPECT_STREQ("live/livestream?vhost=srs.srt.com.cn", subpath.c_str());
@@ -448,21 +454,132 @@ VOID TEST(ProtocolSrtTest, SrtGetStreamInfoCompatible)
SrtMode mode;
string vhost;
string subpath;
- EXPECT_TRUE(srs_srt_streamid_info("#!::h=live/livestream?secret=d6d2be37,m=publish", mode, vhost, subpath));
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::h=live/livestream?secret=d6d2be37,m=publish", mode, vhost, subpath));
EXPECT_EQ(SrtModePush, mode);
EXPECT_STREQ("", vhost.c_str());
EXPECT_STREQ("live/livestream?secret=d6d2be37", subpath.c_str());
}
}
+// Test short streamid format with default_mode config
+VOID TEST(ProtocolSrtTest, SrtGetStreamInfoShortFormat)
+{
+ MockAppConfig config;
+ config.srt_default_mode_ = "request";
+
+ // Test short format "live/livestream" - default mode is request (pull)
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "live/livestream", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePull, mode);
+ EXPECT_STREQ("", vhost.c_str());
+ EXPECT_STREQ("live/livestream", subpath.c_str());
+ }
+
+ // Test minimal format "livestream" - uses default app "live"
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "livestream", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePull, mode);
+ EXPECT_STREQ("", vhost.c_str());
+ EXPECT_STREQ("live/livestream", subpath.c_str());
+ }
+
+ // Test short format with stream name only, different stream
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "testkey", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePull, mode);
+ EXPECT_STREQ("", vhost.c_str());
+ EXPECT_STREQ("live/testkey", subpath.c_str());
+ }
+
+ // Test short format with custom app
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "myapp/mystream", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePull, mode);
+ EXPECT_STREQ("", vhost.c_str());
+ EXPECT_STREQ("myapp/mystream", subpath.c_str());
+ }
+}
+
+// Test short streamid format with default_mode=publish via mock config
+VOID TEST(ProtocolSrtTest, SrtGetStreamInfoShortFormatPublishMode)
+{
+ MockAppConfig config;
+ config.srt_default_mode_ = "publish";
+
+ // Test short format "live/livestream" - should be push mode now
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "live/livestream", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePush, mode);
+ EXPECT_STREQ("", vhost.c_str());
+ EXPECT_STREQ("live/livestream", subpath.c_str());
+ }
+
+ // Test minimal format "livestream" - uses default app "live", push mode
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "livestream", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePush, mode);
+ EXPECT_STREQ("", vhost.c_str());
+ EXPECT_STREQ("live/livestream", subpath.c_str());
+ }
+
+ // Test short format "testkey" - push mode
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "testkey", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePush, mode);
+ EXPECT_STREQ("", vhost.c_str());
+ EXPECT_STREQ("live/testkey", subpath.c_str());
+ }
+
+ // Full YAML format should still respect explicit mode (not affected by default_mode)
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::r=live/livestream,m=request", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePull, mode);
+ EXPECT_STREQ("live/livestream", subpath.c_str());
+ }
+
+ if (true) {
+ SrtMode mode;
+ string vhost;
+ string subpath;
+ EXPECT_TRUE(srs_srt_streamid_info(&config, "#!::r=live/livestream,m=publish", mode, vhost, subpath));
+ EXPECT_EQ(SrtModePush, mode);
+ EXPECT_STREQ("live/livestream", subpath.c_str());
+ }
+}
+
VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest)
{
+ MockAppConfig config;
SrsProtocolUtility utility;
if (true) {
SrtMode mode;
SrsRequest req;
- EXPECT_TRUE(srs_srt_streamid_to_request("#!::r=live/livestream?key1=val1,key2=val2", mode, &req));
+ EXPECT_TRUE(srs_srt_streamid_to_request(&config, "#!::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");
@@ -473,7 +590,7 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest)
if (true) {
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_TRUE(srs_srt_streamid_to_request(&config, "#!::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");
@@ -484,7 +601,7 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest)
if (true) {
SrtMode mode;
SrsRequest req;
- EXPECT_TRUE(srs_srt_streamid_to_request("#!::h=live/livestream?key1=val1,key2=val2", mode, &req));
+ EXPECT_TRUE(srs_srt_streamid_to_request(&config, "#!::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");
@@ -495,7 +612,7 @@ VOID TEST(ProtocolSrtTest, SrtStreamIdToRequest)
if (true) {
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_TRUE(srs_srt_streamid_to_request(&config, "#!::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");