From 3b7f16b75557a552d6907c60f87f4c06028c5f62 Mon Sep 17 00:00:00 2001 From: haorui wang <56127613+HR1025@users.noreply.github.com> Date: Sat, 16 Mar 2024 21:58:33 +0800 Subject: [PATCH] Fix the issue of failing to push streams to FMS 3.0 server. (#3362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [how] 1. AMF 为简单类型时填插 AMF Null (参考 OBS 以及实际测试) 2. createStream 前附加 releaseStream 和 FCPublish, 兼容旧 FMS3.0 3. 正确处理 RTMP Header fmt 为 1 和 2 的业务逻辑 --- src/Rtmp/RtmpProtocol.cpp | 19 ++++++++++++++++++- src/Rtmp/RtmpProtocol.h | 4 ++++ src/Rtmp/RtmpPusher.cpp | 30 ++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/Rtmp/RtmpProtocol.cpp b/src/Rtmp/RtmpProtocol.cpp index 010e30d4..f98468bf 100644 --- a/src/Rtmp/RtmpProtocol.cpp +++ b/src/Rtmp/RtmpProtocol.cpp @@ -165,7 +165,14 @@ void RtmpProtocol::sendResponse(int type, const string &str) { void RtmpProtocol::sendInvoke(const string &cmd, const AMFValue &val) { AMFEncoder enc; - enc << cmd << ++_send_req_id << val; + if (val.type() == AMFType::AMF_OBJECT || val.type() == AMFType::AMF_NULL) + { + enc << cmd << ++_send_req_id << val; + } + else + { + enc << cmd << ++_send_req_id << AMFValue() << val; + } sendRequest(MSG_CMD, enc.data()); } @@ -619,12 +626,22 @@ const char* RtmpProtocol::handle_rtmp(const char *data, size_t len) { case 12: chunk_data.is_abs_stamp = true; chunk_data.stream_index = load_le32(header->stream_index); + _last_stream_index = chunk_data.stream_index; case 8: chunk_data.body_size = load_be24(header->body_size); chunk_data.type_id = header->type_id; + _last_body_size = chunk_data.body_size; + _last_type_id = chunk_data.type_id; case 4: chunk_data.ts_field = load_be24(header->time_stamp); } + switch (header->fmt) { + case 2: + chunk_data.type_id = _last_type_id; + chunk_data.body_size = _last_body_size; + case 1: + chunk_data.stream_index = _last_stream_index; + } auto time_stamp = chunk_data.ts_field; if (chunk_data.ts_field == 0xFFFFFF) { diff --git a/src/Rtmp/RtmpProtocol.h b/src/Rtmp/RtmpProtocol.h index 7ace93eb..2b7adfff 100644 --- a/src/Rtmp/RtmpProtocol.h +++ b/src/Rtmp/RtmpProtocol.h @@ -11,6 +11,7 @@ #ifndef SRC_RTMP_RTMPPROTOCOL_H_ #define SRC_RTMP_RTMPPROTOCOL_H_ +#include #include #include #include @@ -87,6 +88,9 @@ protected: private: bool _data_started = false; int _now_chunk_id = 0; + uint32_t _last_stream_index = 0; + size_t _last_body_size = 0; + uint8_t _last_type_id = 0; ////////////ChunkSize//////////// size_t _chunk_size_in = DEFAULT_CHUNK_LEN; size_t _chunk_size_out = DEFAULT_CHUNK_LEN; diff --git a/src/Rtmp/RtmpPusher.cpp b/src/Rtmp/RtmpPusher.cpp index 92363241..8f3596fc 100644 --- a/src/Rtmp/RtmpPusher.cpp +++ b/src/Rtmp/RtmpPusher.cpp @@ -163,14 +163,28 @@ void RtmpPusher::send_connect() { } void RtmpPusher::send_createStream() { - AMFValue obj(AMF_NULL); - sendInvoke("createStream", obj); - addOnResultCB([this](AMFDecoder &dec) { - //TraceL << "createStream result"; - dec.load(); - _stream_index = dec.load(); - send_publish(); - }); + // Workaround : 兼容较旧的 FMS3.0 + { + { + AMFValue obj(_stream_id); + sendInvoke("releaseStream", obj); + } + { + AMFValue obj(_stream_id); + sendInvoke("FCPublish", obj); + } + } + { + AMFValue obj(AMF_NULL); + sendInvoke("createStream", obj); + addOnResultCB([this](AMFDecoder &dec) { + //TraceL << "createStream result"; + dec.load(); + _stream_index = dec.load(); + send_publish(); + }); + } + } #define RTMP_STREAM_LIVE "live"