From aea2bfbaf9eca9fefb735a7f768b3ee4114f3a99 Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 9 Sep 2022 16:34:45 +0800 Subject: [PATCH] For #3174: WebRTC: Support Unity to publish or play stream. v4.0.264 --- trunk/doc/CHANGELOG.md | 1 + trunk/src/app/srs_app_rtc_api.cpp | 18 ++++++++++++++---- trunk/src/app/srs_app_rtc_api.hpp | 4 +++- trunk/src/app/srs_app_rtc_conn.cpp | 5 +++++ trunk/src/app/srs_app_rtc_server.cpp | 6 ++++++ trunk/src/app/srs_app_rtc_source.hpp | 8 +------- trunk/src/core/srs_core_version4.hpp | 2 +- 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 4706ad1ca..0c31b1ecc 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -8,6 +8,7 @@ The changelog for SRS. ## SRS 4.0 Changelog +* v4.0, 2022-09-09, For [#3174](https://github.com/ossrs/srs/issues/3174): WebRTC: Support Unity to publish or play stream. v4.0.264 * v4.0, 2022-09-09, Fix [#3093](https://github.com/ossrs/srs/issues/3093): WebRTC: Ignore unknown fmtp for h.264. v4.0.263 * v4.0, 2022-09-06, Fix [#3170](https://github.com/ossrs/srs/issues/3170): WebRTC: Support WHIP(WebRTC-HTTP ingestion protocol). v4.0.262 * v4.0, 2022-09-03, Fix HTTP url parsing bug. v4.0.261 diff --git a/trunk/src/app/srs_app_rtc_api.cpp b/trunk/src/app/srs_app_rtc_api.cpp index 09d99bd3c..f739efb47 100644 --- a/trunk/src/app/srs_app_rtc_api.cpp +++ b/trunk/src/app/srs_app_rtc_api.cpp @@ -577,11 +577,13 @@ srs_error_t SrsGoApiRtcPublish::http_hooks_on_publish(SrsRequest* req) SrsGoApiRtcWhip::SrsGoApiRtcWhip(SrsRtcServer* server) { publish_ = new SrsGoApiRtcPublish(server); + play_ = new SrsGoApiRtcPlay(server); } SrsGoApiRtcWhip::~SrsGoApiRtcWhip() { srs_freep(publish_); + srs_freep(play_); } srs_error_t SrsGoApiRtcWhip::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) @@ -614,6 +616,13 @@ srs_error_t SrsGoApiRtcWhip::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa string codec = r->query_get("codec"); string app = r->query_get("app"); string stream = r->query_get("stream"); + string action = r->query_get("action"); + if (action.empty()) { + action = "publish"; + } + if (srs_string_ends_with(r->path(), "/whip-play/")) { + action = "play"; + } // The RTC user config object. SrsRtcUserConfig ruc; @@ -629,14 +638,14 @@ srs_error_t SrsGoApiRtcWhip::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa ruc.req_->vhost = parsed_vhost->arg0(); } - srs_trace("RTC whip %s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, codec=%s", - ruc.req_->get_stream_url().c_str(), clientip.c_str(), ruc.req_->app.c_str(), ruc.req_->stream.c_str(), + srs_trace("RTC whip %s %s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, codec=%s", + action.c_str(), ruc.req_->get_stream_url().c_str(), clientip.c_str(), ruc.req_->app.c_str(), ruc.req_->stream.c_str(), remote_sdp_str.length(), eip.c_str(), codec.c_str() ); ruc.eip_ = eip; ruc.codec_ = codec; - ruc.publish_ = true; + ruc.publish_ = (action == "publish"); ruc.dtls_ = ruc.srtp_ = true; // TODO: FIXME: It seems remote_sdp doesn't represents the full SDP information. @@ -645,7 +654,8 @@ srs_error_t SrsGoApiRtcWhip::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa return srs_error_wrap(err, "parse sdp failed: %s", remote_sdp_str.c_str()); } - if ((err = publish_->serve_http(w, r, &ruc)) != srs_success) { + err = action == "publish" ? publish_->serve_http(w, r, &ruc) : play_->serve_http(w, r, &ruc); + if (err != srs_success) { return srs_error_wrap(err, "serve"); } diff --git a/trunk/src/app/srs_app_rtc_api.hpp b/trunk/src/app/srs_app_rtc_api.hpp index c448e518c..74d1dd99c 100644 --- a/trunk/src/app/srs_app_rtc_api.hpp +++ b/trunk/src/app/srs_app_rtc_api.hpp @@ -27,7 +27,9 @@ public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); private: virtual srs_error_t do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsJsonObject* res); +public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsRtcUserConfig* ruc); +private: srs_error_t check_remote_sdp(const SrsSdp& remote_sdp); private: virtual srs_error_t http_hooks_on_play(SrsRequest* req); @@ -56,8 +58,8 @@ private: class SrsGoApiRtcWhip : public ISrsHttpHandler { private: - SrsRtcServer* server_; SrsGoApiRtcPublish* publish_; + SrsGoApiRtcPlay* play_; public: SrsGoApiRtcWhip(SrsRtcServer* server); virtual ~SrsGoApiRtcWhip(); diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 99a423a2d..b50398dc7 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -2977,6 +2977,9 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc SrsVideoPayload* video_payload = new SrsVideoPayload(payload.payload_type_, payload.encoding_name_, payload.clock_rate_); video_payload->set_h264_param_desc(payload.format_specific_param_); + // Set the codec parameter for H.264, to make Unity happy. + video_payload->h264_param_ = h264_param; + // TODO: FIXME: Only support some transport algorithms. for (int k = 0; k < (int)payload.rtcp_fb_.size(); ++k) { const string& rtcp_fb = payload.rtcp_fb_.at(k); @@ -3061,6 +3064,8 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc stream_desc->audio_track_desc_ = track_desc_copy; } else if (remote_media_desc.is_video()) { stream_desc->video_track_descs_.push_back(track_desc_copy); + } else { + srs_freep(track_desc_copy); } } track_id = ssrc_info.msid_tracker_; diff --git a/trunk/src/app/srs_app_rtc_server.cpp b/trunk/src/app/srs_app_rtc_server.cpp index 7480ccf33..2449096a5 100644 --- a/trunk/src/app/srs_app_rtc_server.cpp +++ b/trunk/src/app/srs_app_rtc_server.cpp @@ -505,10 +505,16 @@ srs_error_t SrsRtcServer::listen_api() return srs_error_wrap(err, "handle publish"); } + // Generally, WHIP is a publishing protocol, but it can be also used as playing. if ((err = http_api_mux->handle("/rtc/v1/whip/", new SrsGoApiRtcWhip(this))) != srs_success) { return srs_error_wrap(err, "handle whip"); } + // We create another mount, to support play with the same query string as publish. + if ((err = http_api_mux->handle("/rtc/v1/whip-play/", new SrsGoApiRtcWhip(this))) != srs_success) { + return srs_error_wrap(err, "handle whip play"); + } + #ifdef SRS_SIMULATOR if ((err = http_api_mux->handle("/rtc/v1/nack/", new SrsGoApiRtcNACK(this))) != srs_success) { return srs_error_wrap(err, "handle nack"); diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index e7c03f8ab..2f5c4ccc5 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -357,13 +357,7 @@ public: class SrsVideoPayload : public SrsCodecPayload { public: - struct H264SpecificParameter - { - std::string profile_level_id; - std::string packetization_mode; - std::string level_asymmerty_allow; - }; - H264SpecificParameter h264_param_; + H264SpecificParam h264_param_; public: SrsVideoPayload(); diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 01b4f5d5e..83f0c2de0 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 4 #define VERSION_MINOR 0 -#define VERSION_REVISION 263 +#define VERSION_REVISION 264 #endif