RTMP: Ignore FMLE start packet after flash publish. v7.0.129 (#4588)
We have discovered that some IP cameras send two publish packets in a
row.
The first packet is flash publish `publish('xxx')`
The second packet is FMLE publish `FCPublish('xxx|@setDataFrame()`
It seems that this is not processed correctly on the SRS side. In fact,
the stream is simply deinitialized, and republish is simply not
supported in this case.
As a fix, I suggest simply ignoring the FMLE publish packet after the
flash publish.
<img width="720" alt="screen"
src="https://github.com/user-attachments/assets/2db806ab-71b9-4e7b-bcf9-c16ea12df671"
/>
This commit is contained in:
parent
e59b30301a
commit
4101900daf
|
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
|||
<a name="v7-changes"></a>
|
||||
|
||||
## SRS 7.0 Changelog
|
||||
* 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
|
||||
* v7.0, 2025-11-14, AI: Fix race condition causing immediate deletion of new sources. v7.0.127 (#4449)
|
||||
* v7.0, 2025-11-11, AI: WebRTC: Support optional msid attribute per RFC 8830. v7.0.126 (#4570)
|
||||
|
|
|
|||
|
|
@ -3604,8 +3604,8 @@ srs_error_t SrsRtcPublisherNegotiator::negotiate_publish_capability(SrsRtcUserCo
|
|||
// Generate msid because it's optional in sdp.
|
||||
string msid_tracker = ssrc_info.msid_tracker_;
|
||||
if (msid_tracker.empty()) {
|
||||
msid_tracker = srs_fmt_sprintf("track-%s-%s-%d",
|
||||
track_desc->type_.c_str(), ssrc_info.cname_.c_str(), ssrc_info.ssrc_);
|
||||
msid_tracker = srs_fmt_sprintf("track-%s-%s-%d",
|
||||
track_desc->type_.c_str(), ssrc_info.cname_.c_str(), ssrc_info.ssrc_);
|
||||
}
|
||||
|
||||
// Generate msid because it's optional in sdp.
|
||||
|
|
|
|||
|
|
@ -1176,6 +1176,11 @@ srs_error_t SrsRtmpConn::handle_publish_message(SrsSharedPtr<SrsLiveSource> &sou
|
|||
|
||||
// for flash, any packet is republish.
|
||||
if (info_->type_ == SrsRtmpConnFlashPublish) {
|
||||
if (dynamic_cast<SrsFMLEStartPacket *>(pkt.get())) {
|
||||
srs_warn("flash late FMLE start packet");
|
||||
return err;
|
||||
}
|
||||
|
||||
// flash unpublish.
|
||||
// TODO: maybe need to support republish.
|
||||
srs_trace("flash flash publish finished.");
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 7
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 128
|
||||
#define VERSION_REVISION 129
|
||||
|
||||
#endif
|
||||
|
|
@ -20,9 +20,9 @@
|
|||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_protocol_sdp.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
#include <srs_utest_ai16.hpp>
|
||||
#include <srs_utest_manual_kernel.hpp>
|
||||
#include <srs_utest_manual_mock.hpp>
|
||||
#include <srs_utest_ai16.hpp>
|
||||
|
||||
#ifdef SRS_FFMPEG_FIT
|
||||
#include <srs_app_rtc_codec.hpp>
|
||||
|
|
@ -1241,7 +1241,7 @@ VOID TEST(SdpTest, ParseLibdatachannelSdpFromIssue4570)
|
|||
EXPECT_TRUE(sdp.media_descs_.size() == 2);
|
||||
|
||||
// Verify first media description is video
|
||||
SrsMediaDesc* video_desc = &sdp.media_descs_[0];
|
||||
SrsMediaDesc *video_desc = &sdp.media_descs_[0];
|
||||
EXPECT_TRUE(video_desc->type_ == "video");
|
||||
EXPECT_TRUE(video_desc->mid_ == "video");
|
||||
EXPECT_TRUE(video_desc->sendonly_);
|
||||
|
|
@ -1253,7 +1253,7 @@ VOID TEST(SdpTest, ParseLibdatachannelSdpFromIssue4570)
|
|||
EXPECT_TRUE(video_desc->payload_types_.size() >= 1);
|
||||
|
||||
// Find H264 payload (PT 96)
|
||||
SrsMediaPayloadType* h264_payload = NULL;
|
||||
SrsMediaPayloadType *h264_payload = NULL;
|
||||
for (size_t i = 0; i < video_desc->payload_types_.size(); i++) {
|
||||
if (video_desc->payload_types_[i].payload_type_ == 96) {
|
||||
h264_payload = &video_desc->payload_types_[i];
|
||||
|
|
@ -1277,7 +1277,7 @@ VOID TEST(SdpTest, ParseLibdatachannelSdpFromIssue4570)
|
|||
EXPECT_TRUE(found_video_ssrc);
|
||||
|
||||
// Verify second media description is audio
|
||||
SrsMediaDesc* audio_desc = &sdp.media_descs_[1];
|
||||
SrsMediaDesc *audio_desc = &sdp.media_descs_[1];
|
||||
EXPECT_TRUE(audio_desc->type_ == "audio");
|
||||
EXPECT_TRUE(audio_desc->mid_ == "audio");
|
||||
EXPECT_TRUE(audio_desc->sendonly_);
|
||||
|
|
@ -1289,7 +1289,7 @@ VOID TEST(SdpTest, ParseLibdatachannelSdpFromIssue4570)
|
|||
EXPECT_TRUE(audio_desc->payload_types_.size() >= 1);
|
||||
|
||||
// Find Opus payload (PT 111)
|
||||
SrsMediaPayloadType* opus_payload = NULL;
|
||||
SrsMediaPayloadType *opus_payload = NULL;
|
||||
for (size_t i = 0; i < audio_desc->payload_types_.size(); i++) {
|
||||
if (audio_desc->payload_types_[i].payload_type_ == 111) {
|
||||
opus_payload = &audio_desc->payload_types_[i];
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user