SRS forward feature only supports plain RTMP protocol, not RTMPS (RTMP over SSL/TLS). This is by design - SRS SSL is server-side only (accepting connections), not client-side (initiating connections). The forward feature uses SrsSimpleRtmpClient which has no SSL handshake or encryption capabilities for outgoing connections.
Changes:
1. Add RTMPS URL detection in SrsForwarder::initialize()
2. Return ERROR_NOT_SUPPORTED error when RTMPS destination is detected
3. Add unit test to verify RTMPS URLs are properly rejected
4. Add FAQ section to .augment-guidelines explaining the limitation
For users who need to forward to RTMPS destinations (e.g., AWS IVS), the recommended solution is to use FFmpeg with SRS HTTP Hooks:
- on_publish event: Automatically start FFmpeg to relay stream to RTMPS destination
- on_unpublish event: Automatically stop FFmpeg process when stream ends
This provides a fully automated, production-ready RTMPS relay solution without adding complexity to SRS core.
Related: #4536
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
Regression since 20f6cd595c
The early code might meet bridge is empty when
there is no bridge(e.x. rtc to rtc). Then srs_freep will free the brige.
Remove this code that seems redundant.
---------
Co-authored-by: Jacob Su <suzp1984@gmail.com>
Signed-off-by: Jack Lau <jacklau1222@qq.com>
This PR refactors the stream bridge architecture in SRS to improve code
organization, type safety, and maintainability by replacing the generic
ISrsStreamBridge interface with protocol-specific bridge classes and
target interfaces.
1. New Target Interface Architecture:
- Introduces ISrsFrameTarget for AV frame consumers (RTMP sources)
- Introduces ISrsRtpTarget for RTP packet consumers (RTC sources)
- Introduces ISrsSrtTarget for SRT packet consumers (SRT sources)
2. Protocol-Specific Bridge Classes:
- SrsRtmpBridge: Converts RTMP frames to RTC/RTSP protocols
- SrsSrtBridge: Converts SRT packets to RTMP/RTC protocols
- SrsRtcBridge: Converts RTC packets to RTMP protocol
3. Simplified Bridge Management:
- Removes the generic SrsCompositeBridge chain pattern
- Each source type now uses its appropriate bridge type directly
With this improvement, you are able to implement very complex bridge and
protocol converting, for example, you can bridge RTMP to RTC with opus
audio when you support enhanced RTMP with opus.
Another plan is to support bridging RTC to RTSP, directly without
converting RTP to media frame packet, but directly deliver RTP packet
from RTC source to RTSP source.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
The issue occurred when srs_rtp_seq_distance(start, end) + 1 resulted in
values <= 0
due to sequence number wraparound (e.g., when end < start). This caused
assertion
failures and server crashes.
SrsRtcFrameBuilder::check_frame_complete(): Added validation to return
false
for invalid sequence ranges instead of asserting.
However, it maybe cause converting RTC to RTMP stream failure, because
this issue
should be caused by the problem of sequence number of RTP, which means
there potentially
be stream problem in RTC stream. Even so, changing assert to warning
logs is better,
because SRS should not crash when stream is corrupt.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
try to fix#4428.
## Cause
rtmp do not support hevc, rtmp enhanced do.
## How to reproduce
1. start srs.
`./objs/srs -c conf/srt.conf`
2. publish hevc (h.265) stream to srs by srt.
`ffmpeg -re -i ./doc/source.flv -c:v libx265 -crf 28 -preset medium -c:a
copy -pes_payload_size 0 -f mpegts
'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'`
3. probe the rtmp stream
`ffprobe rtmp://localhost/live/livestream`
## About the Failed BlackBox test
The failed blackbox test: `TestSlow_SrtPublish_RtmpPlay_HEVC_Basic`
`TestSlow_SrtPublish_HttpFlvPlay_HEVC_Basic`
### Cause:
The ffmpeg 5 is used to record a piece of video (DRV), the ffmpeg will
transcode the enhanced flv format to TS format, but ffmpeg 5 don't
support enhanced rtmp (or flv) in this case.
The solution is to replace the ffmpeg to version 7 in those 2 test
cases.
### why not upgrade ffmpeg to version 7?
The black tests dependency on ffmpeg 5 will fail, and there are a few of
them are not easy to resolve in ffmpeg 7.
---------
Co-authored-by: winlin <winlinvip@gmail.com>
This PR significantly enhances the kernel module by adding comprehensive
unit test coverage and improving interface design for core buffer and
load balancer components.
- **ISrsDecoder**: New interface for decoding/deserialization operations
- **ISrsLbRoundRobin**: Extracted interface from concrete
SrsLbRoundRobin class for better abstraction
- **Enhanced Documentation**: Added comprehensive inline documentation
for ISrsEncoder, ISrsCodec, SrsBuffer, and SrsBitBuffer classes
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR introduces anonymous coroutine macros for easier coroutine
creation and improves the State Threads (ST) mutex and condition
variable handling in SRS.
- **Added coroutine macros**: `SRS_COROUTINE_GO`, `SRS_COROUTINE_GO2`,
`SRS_COROUTINE_GO_CTX`, `SRS_COROUTINE_GO_CTX2`
- **Added `SrsCoroutineChan`**: Channel for sharing data between
coroutines with coroutine-safe operations
- **Simplified coroutine creation**: Go-like syntax for creating
anonymous coroutines with code blocks
---------
Co-authored-by: Jacob Su <suzp1984@gmail.com>
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
Fixes a bug in WebRTC NACK packet recovery mechanism where recovered
packets were being discarded instead of processed.
In `SrsRtcRecvTrack::on_nack()`, when a retransmitted packet arrived
(found in NACK receiver), the method would:
1. ✅ Remove the packet from NACK receiver (correct)
2. ❌ Return early without adding the packet to RTP queue (BUG)
This caused recovered packets to be lost, defeating the purpose of the
NACK mechanism and potentially causing media quality issues.
Restructured the control flow in `on_nack()` to ensure both new and
recovered packets reach the packet insertion logic:
- **Before**: Early return for recovered packets → packets discarded
- **After**: Conditional NACK management + unified packet processing →
all packets queued
Closes#3820
---------
Co-authored-by: Haibo Chen <495810242@qq.com>
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR modernizes SRS's HTTP handling by upgrading from the legacy
http-parser library to the more performant and actively maintained
llhttp library.
* Replace http-parser with llhttp: Migrated from the deprecated
http-parser to llhttp for better performance and maintenance
* API compatibility: Updated all HTTP parsing logic to use llhttp APIs
while maintaining backward compatibility
* Simplified URL parsing: Replaced complex http-parser URL parsing with
custom simple parser implementation
Enhanced error handling: Improved error reporting with llhttp's better
error context and positioning
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
WebRTC RTC publish streams use timer callbacks (`SrsRtcPublishRtcpTimer`
and `SrsRtcPublishTwccTimer`) that can cause race conditions in SRS's
coroutine-based architecture. The timer callbacks are heavy functions
that may trigger coroutine switches, during which the timer object can
be freed by another coroutine, leading to use-after-free crashes.
The race condition occurs because:
1. Timer callbacks (`on_timer`) perform heavy operations that can yield
control
2. During coroutine switches, other coroutines may destroy the timer
object
3. When control returns, the callback continues executing on a freed
object
Fixes potential crashes in WebRTC RTC publish streams under high
concurrency.
This PR removes the embedded GB28181 SIP server implementation from SRS
and enforces the use of external SIP servers for production deployments.
The embedded SIP server depended on the deprecated `http-parser`
library. With the planned migration to `llhttp` (which doesn't support
SIP parsing), maintaining the embedded SIP server would require
significant additional work. Since external SIP servers are already the
recommended approach for production, removing the embedded
implementation simplifies the codebase and eliminates this dependency.
Eliminated `srs_gb28181_test` from CI workflow.
Removed SIP configuration validation tests.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
Co-authored-by: haibo.chen <495810242@qq.com>
This PR introduces a major refactoring to replace `SrsSharedPtrMessage`
with `SrsMediaPacket` throughout the SRS codebase, providing a more
unified and cleaner approach to media packet handling.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR modernizes the memory management architecture in SRS by
refactoring RTMP message handling to use shared pointers
(SrsSharedPtr<SrsMemoryBlock>) instead of manual memory management. This
change improves memory safety, reduces the risk of memory leaks, and
provides a cleaner abstraction for message payload handling.
* Introduced `SrsMemoryBlock`: A dedicated class for managing memory
buffers with size information
* Replaced manual memory management: `SrsCommonMessage` and
`SrsSharedPtrMessage` now use `SrsSharedPtr<SrsMemoryBlock>` instead of
raw pointers
* Updated `SrsRtpPacket`: Now uses `SrsSharedPtr<SrsMemoryBlock>` for
shared buffer management
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
Refactors the `srs_net_url_parse_tcurl` function to use the robust
`SrsHttpUri` class for URL parsing and implements a dedicated legacy
RTMP URL conversion function to handle various URL formats consistently.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR refactors the HTTP routing system by renaming "hijack"
terminology to "dynamic match" for improved code clarity and better
semantic meaning.
Interface and Class Renaming
* ISrsHttpMatchHijacker → ISrsHttpDynamicMatcher
* hijack() method → dynamic_match() method
* hijackers member variables → dynamic_matchers_
Method Renaming
* SrsHttpServeMux::hijack() → SrsHttpServeMux::add_dynamic_matcher()
* SrsHttpServeMux::unhijack() →
SrsHttpServeMux::remove_dynamic_matcher()
The new "dynamic match" terminology better reflects that this is a
legitimate routing mechanism, not a security bypass or interception.
Move global xpps statistics variables from `srs_app_server.cpp` to
`srs_kernel_kbps.cpp`.
Extract global shared timers from `SrsServer` into new `SrsSharedTimer`
class.
Extract WebRTC session management logic from `SrsServer` into dedicated
`SrsRtcSessionManager` class.
Extract PID file handling into dedicated `SrsPidFileLocker` class.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR consolidates the SRT and RTC server functionality into the main
SrsServer class, eliminating the separate `SrsSrtServer` and
`SrsRtcServer` classes and their corresponding adapter classes. This
architectural change simplifies the codebase by removing the hybrid
server pattern and integrating all protocol handling directly into
`SrsServer`.
As unified connection manager (`_srs_conn_manager`) for all protocol
connections, all incoming connections are checked against the same
connection limit in `on_before_connection()`. This enables consistent
connection limits: `max_connections` now protects against resource
exhaustion from any protocol, not just RTMP.
Remove modules because it's not used now, so only keep the server
application module and main entry point. Remove the wait group to run
server, instead, directly run server and invoke the cycle method.
After this PR, the startup workflow and servers architecture should be
much easier to maintain.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
Try to fix#4450
The SRS transcode rtp packets, whose sequence number in range [start,
end], to one rtmp packet, but when the first rtp packet is empty, then
this crash happens.
check #4450 for details.
5.0release and 6.0release branch.
develop branch already has its own solution.
So this PR is targeting to **6.0release**.
find the first not empty rtp packet in seq range [start, end].
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
Co-authored-by: winlin <winlinvip@gmail.com>
This PR introduces a comprehensive stream publish token system that
prevents race conditions when multiple publishers attempt to publish to
the same stream URL simultaneously across different protocols (RTMP,
WebRTC, SRT).
* Race Condition Issue: Multiple publishers could create duplicate
sources for the same stream when context switches occurred during source
initialization in SRS's coroutine-based architecture
* Cross-Protocol Conflicts: Different protocols (RTMP, RTC, SRT) could
simultaneously publish to the same stream URL without coordination
* Resource Management: No centralized mechanism to ensure exclusive
stream publishing access
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR fixes a critical race condition in SRS source managers where
multiple coroutines could create duplicate sources for the same stream.
- **Atomic source creation**: Source lookup, creation, and pool
insertion now happen atomically within lock scope
- **Consistent interface**: Standardize on `ISrsRequest*` interface
throughout codebase
- **Handler simplification**: Remove `ISrsLiveSourceHandler*` parameter,
obtain from global server instance
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR makes WebRTC a core feature of SRS and enforces C++98
compatibility by:
1. Always Enable WebRTC Support
- Remove `--rtc=on|off` configuration option - WebRTC is now always
enabled
- Eliminate all `#ifdef SRS_RTC` conditional compilation blocks
- Include WebRTC-related modules (RTC, SRTP, DTLS) in all builds
- Update build scripts to always link WebRTC dependencies
2. Enforce C++98 Compatibility
- Remove `--cxx11=on|off` and `--cxx14=on|off` configuration options
- Force `SRS_CXX11=NO` and `SRS_CXX14=NO` in build system
- Move these options to deprecated section with warnings
- Ensure codebase maintains C++98 standard compatibility
3. Remove Windows/Cygwin Support
- Remove all Windows and Cygwin64 conditional compilation blocks (#ifdef
_WIN32, #ifdef CYGWIN64)
- Delete Cygwin64 build configurations from build scripts (
auto/options.sh, auto/depends.sh, configure)
- Remove Cygwin64 assembly files and State Threads platform support (
md_cygwin64.S)
- Eliminate Windows-specific GitHub Actions workflows and CI/CD jobs
- Remove NSIS packaging files and Windows installer generation
- Delete Windows documentation and update feature lists to mark support
as removed in v7.0
- Simplify OS detection to only support Unix-like systems (Linux, macOS)
4. Code Cleanup
- Remove conditional WebRTC code blocks throughout the codebase
- Simplify build configuration by removing WebRTC-related conditionals
- Update constructor delegation patterns to be C++98 compatible
- Fix vector initialization to use C++98 syntax
- Eliminate Windows-specific implementations for file operations, time
handling, and networking
- Unified platform handling with consistent POSIX API usage
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR removes the multi-threading infrastructure from SRS and
consolidates the codebase to use single-thread architecture exclusively.
This is a architectural simplification that aligns with SRS's
coroutine-based design philosophy.
* Simplified Architecture: Eliminates complexity of multi-threading
coordination
* Better Alignment: Matches SRS's coroutine-based single-thread design
philosophy
* Reduced Complexity: Removes potential race conditions and threading
bugs
* Cleaner Code: More focused modules with clear responsibilities
* Easier Maintenance: Fewer moving parts and clearer execution flow
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR refactors the HTTP hooks system from static methods to a proper
interface-based architecture, improving code maintainability,
testability, and extensibility.
1. **Testability**: Interface allows easy mocking for unit tests
1. **Extensibility**: Custom hook implementations can be injected
1. **Maintainability**: Clear separation of concerns and better code
organization
1. **Documentation**: Comprehensive inline documentation for all hook
methods
1. **Future-proofing**: Enables plugin architecture and custom hook
handlers
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
### Feature
HLS continuous mode: In this mode HLS sequence number is started from
where it stopped last time. Old fragments are kept. Default is on.
### Configuration
```
vhost __defaultVhost__ {
hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 10;
hls_window 60;
hls_continuous on;
}
}
```
Contributed by AI:
* [AI: Refine and extract HLS
recover.](656e4e296d)
---------
Co-authored-by: Haibo Chen <495810242@qq.com>
Co-authored-by: winlin <winlinvip@gmail.com>
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR is extracted by AI from #3949 to support RTMPS server in SRS.
Run SRS with RTMPS support:
```bash
./objs/srs -c conf/rtmps.conf
```
Publish RTMPS stream by FFmpeg:
```bash
ffmpeg -re -i doc/source.flv -c copy -f flv rtmps://localhost:1443/live/livetream
```
Play RTMPS stream by ffplay:
```bash
ffplay rtmps://localhost:1443/live/livetream
```
Below work is done by AI:
* [AI: Extract RTMP transport for
RTMPS.](7948111464)
* [AI: Extract RTMPS
transport.](a669cbba89)
---------
Co-authored-by: john <hondaxiao@tencent.com>
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
1. print the error messages before dismiss it;
2. free the err to avoid memory leak;
## Cause
found this issue when research #4434 .
## Impact
1. develop
2. 5.0release
3. 6.0release
---------
Co-authored-by: winlin <winlinvip@gmail.com>
## Problem
HLS and DASH components had redundant `enabled` flag checks in their
`cycle()` and `cleanup_delay()` methods that prevented proper cleanup of
files when components were disabled. This created a race condition
where:
1. Stream stops publishing and HLS/DASH components get disabled
2. `cycle()` returns early without performing disposal operations
3. `cleanup_delay()` returns 0 instead of configured disposal timeout
4. Source cleanup doesn't wait long enough for file disposal
5. HLS/DASH files remain on disk without proper cleanup
## Root Cause
The `enabled` flag should control processing of **new incoming
streams**, but should NOT prevent **cleanup of existing files** from
previously enabled streams.
## Solution
Remove redundant `enabled` checks from:
- `SrsHls::cycle()` and `SrsDash::cycle()` - Allow disposal logic to run
even when disabled
- `SrsHls::cleanup_delay()` and `SrsDash::cleanup_delay()` - Always
return proper disposal timeout
---------
Co-authored-by: winlin <winlinvip@gmail.com>
## Summary
Removes the deprecated `hls_acodec` and `hls_vcodec` configuration
options and implements automatic codec detection for HLS streams, fixing
issues with video-only streams incorrectly showing audio information.
## Problem
- When streaming video-only content via RTMP, HLS output incorrectly
contained audio track information due to hardcoded default codec
settings
- The static `hls_acodec` and `hls_vcodec` configurations were
inflexible and caused compatibility issues with some players
- Users had to manually configure `hls_acodec an` to fix video-only
streams
## Solution
- **Remove deprecated configs**: Eliminates `hls_acodec` and
`hls_vcodec` configuration options entirely
- **Dynamic codec detection**: HLS muxer now automatically detects and
uses actual stream codecs in real-time
- **Improved defaults**: Changes from hardcoded AAC/H.264 defaults to
disabled state, letting actual stream content determine codec
information
- **Real-time codec switching**: Supports codec changes during streaming
with proper logging
## Changes
- Remove `get_hls_acodec()` and `get_hls_vcodec()` from SrsConfig
- Update HLS muxer to use `latest_acodec_`/`latest_vcodec_` for codec
detection
- Add codec detection logic in `write_audio()` and `write_video()`
methods
- Remove deprecated config options from all configuration files
- Add comprehensive unit tests for codec detection functionality
Fixes#4223
---------
Co-authored-by: Haibo Chen <495810242@qq.com>
Co-authored-by: OSSRS-AI <winlinam@gmail.com>