From f47e3ab45870037fa4eda8e6cdafb5205b5329ce Mon Sep 17 00:00:00 2001 From: OSSRS-AI Date: Sun, 30 Nov 2025 16:26:04 -0500 Subject: [PATCH] SRT: Support default_mode config for short streamid format. v7.0.131 (#4598) --- .../srs-docs/doc/getting-started-cdk.md | 13 ++ .../srs-docs/doc/getting-started-k8s.md | 10 +- trunk/3rdparty/srs-docs/doc/k8s.md | 2 + trunk/3rdparty/srs-docs/doc/srt.md | 109 ++++++++++--- trunk/conf/full.conf | 10 ++ trunk/conf/srt.shortstreamid.play.conf | 51 +++++++ trunk/conf/srt.shortstreamid.publish.conf | 51 +++++++ trunk/doc/CHANGELOG.md | 1 + trunk/src/app/srs_app_config.cpp | 19 ++- trunk/src/app/srs_app_config.hpp | 4 + trunk/src/app/srs_app_factory.cpp | 5 + trunk/src/app/srs_app_factory.hpp | 1 + trunk/src/app/srs_app_srt_conn.cpp | 2 +- trunk/src/core/srs_core_version7.hpp | 2 +- trunk/src/kernel/srs_kernel_factory.hpp | 3 + trunk/src/protocol/srs_protocol_utility.cpp | 14 +- trunk/src/protocol/srs_protocol_utility.hpp | 7 +- trunk/src/utest/srs_utest_manual_mock.hpp | 3 + trunk/src/utest/srs_utest_manual_srt.cpp | 143 ++++++++++++++++-- 19 files changed, 406 insertions(+), 44 deletions(-) create mode 100644 trunk/3rdparty/srs-docs/doc/getting-started-cdk.md create mode 100644 trunk/conf/srt.shortstreamid.play.conf create mode 100644 trunk/conf/srt.shortstreamid.publish.conf 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. + +![](https://ossrs.io/gif/v1/sls.gif?site=ossrs.io&path=/lts/doc/en/v7/getting-started-cdk) + 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. ![](https://ossrs.io/gif/v1/sls.gif?site=ossrs.io&path=/lts/doc/en/v7/getting-started-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");