From 7ef39d1b6f496479a3654a52e4cc9fb91779a6f5 Mon Sep 17 00:00:00 2001 From: ljx0305 Date: Mon, 8 May 2023 15:27:43 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8DopenRtpServer=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=A3=B0=E6=98=8E=E4=B8=8D=E4=B8=80=E8=87=B4=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20(#2445)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/WebApi.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/WebApi.h b/server/WebApi.h index aaf0b19e..15210d53 100755 --- a/server/WebApi.h +++ b/server/WebApi.h @@ -231,9 +231,12 @@ bool checkArgs(Args &args, const First &first, const KeyTypes &...keys) { void installWebApi(); void unInstallWebApi(); -uint16_t openRtpServer(uint16_t local_port, const std::string &stream_id, int tcp_mode, const std::string &local_ip, bool re_use_port, uint32_t ssrc); +#if defined(ENABLE_RTPPROXY) +uint16_t openRtpServer(uint16_t local_port, const std::string &stream_id, int tcp_mode, const std::string &local_ip, bool re_use_port, uint32_t ssrc, bool only_audio); void connectRtpServer(const std::string &stream_id, const std::string &dst_url, uint16_t dst_port, const std::function &cb); bool closeRtpServer(const std::string &stream_id); +#endif + Json::Value makeMediaSourceJson(mediakit::MediaSource &media); void getStatisticJson(const std::function &cb); void addStreamProxy(const std::string &vhost, const std::string &app, const std::string &stream, const std::string &url, int retry_count, From 350e262433ca88f4c0873fcf0b2376444176b498 Mon Sep 17 00:00:00 2001 From: Per-Arne Andersen Date: Thu, 11 May 2023 03:58:48 +0200 Subject: [PATCH 02/12] Added support for GCC 13 (#2452) GCC Does not explicitly include stdint. This update includes them where needed. A very minor change that would allow GCC13 and above to compile correctly. In newer versions, cstdint is not implicitly included, hence it errors out during compilation for some files. --- src/Http/strCoding.h | 2 +- src/Record/HlsMaker.h | 1 + src/Rtmp/amf.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Http/strCoding.h b/src/Http/strCoding.h index 4be8328e..00177f74 100644 --- a/src/Http/strCoding.h +++ b/src/Http/strCoding.h @@ -13,7 +13,7 @@ #include #include - +#include namespace mediakit { class strCoding { diff --git a/src/Record/HlsMaker.h b/src/Record/HlsMaker.h index 57a5308a..be20ba1b 100644 --- a/src/Record/HlsMaker.h +++ b/src/Record/HlsMaker.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace mediakit { diff --git a/src/Rtmp/amf.h b/src/Rtmp/amf.h index 283fbcc7..276315cf 100644 --- a/src/Rtmp/amf.h +++ b/src/Rtmp/amf.h @@ -16,6 +16,7 @@ #include #include #include +#include namespace toolkit { class BufferLikeString; } From 1136b0a3c0ccc93689c02c95cef2592cd343bf53 Mon Sep 17 00:00:00 2001 From: codeRATny <60806889+codeRATny@users.noreply.github.com> Date: Fri, 12 May 2023 10:20:31 +0700 Subject: [PATCH 03/12] Adding new features for proxy player (#2448) Add some functions for the proxy player, such as: getting stream information (basic video/audio information) callbacks for any connection and disconnection from the server And now you can set delay between reconnections. See proxy player constructor --- src/Player/PlayerProxy.cpp | 59 +++++++++++++++++++++++++++++++++-- src/Player/PlayerProxy.h | 63 +++++++++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 3 deletions(-) diff --git a/src/Player/PlayerProxy.cpp b/src/Player/PlayerProxy.cpp index b2b567ff..289c7249 100644 --- a/src/Player/PlayerProxy.cpp +++ b/src/Player/PlayerProxy.cpp @@ -25,7 +25,8 @@ using namespace std; namespace mediakit { PlayerProxy::PlayerProxy( - const string &vhost, const string &app, const string &stream_id, const ProtocolOption &option, int retry_count, const EventPoller::Ptr &poller) + const string &vhost, const string &app, const string &stream_id, const ProtocolOption &option, int retry_count, + const EventPoller::Ptr &poller, int reconnect_delay_min, int reconnect_delay_max, int reconnect_delay_step) : MediaPlayer(poller) , _option(option) { _vhost = vhost; @@ -33,6 +34,12 @@ PlayerProxy::PlayerProxy( _stream_id = stream_id; _retry_count = retry_count; + setOnConnect(nullptr); + setOnDisconnect(nullptr); + + _reconnect_delay_min = reconnect_delay_min > 0 ? reconnect_delay_min : 2; + _reconnect_delay_max = reconnect_delay_max > 0 ? reconnect_delay_max : 60; + _reconnect_delay_step = reconnect_delay_step > 0 ? reconnect_delay_step : 3; _live_secs = 0; _live_status = 1; _repull_count = 0; @@ -48,6 +55,47 @@ void PlayerProxy::setOnClose(const function &cb) _on_close = cb ? cb : [](const SockException &) {}; } +void PlayerProxy::setOnDisconnect(std::function cb) { + _on_disconnect = cb ? std::move(cb) : [] () {}; +} + +void PlayerProxy::setOnConnect(std::function cb) { + _on_connect = cb ? std::move(cb) : [](const TranslationInfo&) {}; +} + +void PlayerProxy::setTranslationInfo() +{ + _transtalion_info.byte_speed = _media_src->getBytesSpeed(); + _transtalion_info.start_time_stamp = _media_src->getCreateStamp(); + _transtalion_info.stream_info.clear(); + auto tracks = _muxer->getTracks(); + for (auto &track : tracks) { + _transtalion_info.stream_info.emplace_back(); + auto &back = _transtalion_info.stream_info.back(); + back.bitrate = track->getBitRate(); + back.codec_type = track->getTrackType(); + back.codec_name = track->getCodecName(); + switch (back.codec_type) { + case TrackAudio : { + auto audio_track = dynamic_pointer_cast(track); + back.audio_sample_rate = audio_track->getAudioSampleRate(); + back.audio_channel = audio_track->getAudioChannel(); + back.audio_sample_bit = audio_track->getAudioSampleBit(); + break; + } + case TrackVideo : { + auto video_track = dynamic_pointer_cast(track); + back.video_width = video_track->getVideoWidth(); + back.video_height = video_track->getVideoHeight(); + back.video_fps = video_track->getVideoFps(); + break; + } + default: + break; + } + } +} + void PlayerProxy::play(const string &strUrlTmp) { weak_ptr weakSelf = shared_from_this(); std::shared_ptr piFailedCnt(new int(0)); // 连续播放失败次数 @@ -70,10 +118,13 @@ void PlayerProxy::play(const string &strUrlTmp) { // 播放成功 *piFailedCnt = 0; // 连续播放失败次数清0 strongSelf->onPlaySuccess(); + strongSelf->setTranslationInfo(); + strongSelf->_on_connect(strongSelf->_transtalion_info); InfoL << "play " << strUrlTmp << " success"; } else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { // 播放失败,延时重试播放 + strongSelf->_on_disconnect(); strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++); } else { // 达到了最大重试次数,回调关闭 @@ -157,7 +208,7 @@ PlayerProxy::~PlayerProxy() { } void PlayerProxy::rePlay(const string &strUrl, int iFailedCnt) { - auto iDelay = MAX(2 * 1000, MIN(iFailedCnt * 3000, 60 * 1000)); + auto iDelay = MAX(_reconnect_delay_min * 1000, MIN(iFailedCnt * _reconnect_delay_step * 1000, _reconnect_delay_max * 1000)); weak_ptr weakSelf = shared_from_this(); _timer = std::make_shared( iDelay / 1000.0f, @@ -216,6 +267,10 @@ float PlayerProxy::getLossRate(MediaSource &sender, TrackType type) { return getPacketLossRate(type); } +TranslationInfo PlayerProxy::getTranslationInfo() { + return _transtalion_info; +} + void PlayerProxy::onPlaySuccess() { GET_CONFIG(bool, reset_when_replay, General::kResetWhenRePlay); if (dynamic_pointer_cast(_media_src)) { diff --git a/src/Player/PlayerProxy.h b/src/Player/PlayerProxy.h index d828f696..1ed625c6 100644 --- a/src/Player/PlayerProxy.h +++ b/src/Player/PlayerProxy.h @@ -18,6 +18,45 @@ namespace mediakit { +struct StreamInfo +{ + TrackType codec_type; + std::string codec_name; + int bitrate; + int audio_sample_rate; + int audio_sample_bit; + int audio_channel; + int video_width; + int video_height; + float video_fps; + + StreamInfo() + { + codec_type = TrackInvalid; + codec_name = "none"; + bitrate = -1; + audio_sample_rate = -1; + audio_channel = -1; + audio_sample_bit = -1; + video_height = -1; + video_width = -1; + video_fps = -1.0; + } +}; + +struct TranslationInfo +{ + std::vector stream_info; + int byte_speed; + uint64_t start_time_stamp; + + TranslationInfo() + { + byte_speed = -1; + start_time_stamp = 0; + } +}; + class PlayerProxy : public MediaPlayer , public MediaSourceEvent @@ -29,7 +68,7 @@ public: // 默认一直重试 PlayerProxy( const std::string &vhost, const std::string &app, const std::string &stream_id, const ProtocolOption &option, int retry_count = -1, - const toolkit::EventPoller::Ptr &poller = nullptr); + const toolkit::EventPoller::Ptr &poller = nullptr, int reconnect_delay_min = 2, int reconnect_delay_max = 60, int reconnect_delay_step = 3); ~PlayerProxy() override; @@ -45,6 +84,18 @@ public: */ void setOnClose(const std::function &cb); + /** + * Set a callback for failed server connection + * @param cb 回调对象 + */ + void setOnDisconnect(std::function cb); + + /** + * Set a callback for a successful connection to the server + * @param cb 回调对象 + */ + void setOnConnect(std::function cb); + /** * 开始拉流播放 * @param strUrl @@ -60,6 +111,9 @@ public: uint64_t getLiveSecs(); uint64_t getRePullCount(); + // Using this only makes sense after a successful connection to the server + TranslationInfo getTranslationInfo(); + private: // MediaSourceEvent override bool close(MediaSource &sender) override; @@ -72,17 +126,24 @@ private: void rePlay(const std::string &strUrl, int iFailedCnt); void onPlaySuccess(); void setDirectProxy(); + void setTranslationInfo(); private: ProtocolOption _option; int _retry_count; + int _reconnect_delay_min; + int _reconnect_delay_max; + int _reconnect_delay_step; std::string _vhost; std::string _app; std::string _stream_id; std::string _pull_url; toolkit::Timer::Ptr _timer; + std::function _on_disconnect; + std::function _on_connect; std::function _on_close; std::function _on_play; + TranslationInfo _transtalion_info; MultiMediaSourceMuxer::Ptr _muxer; toolkit::Ticker _live_ticker; From f6ac39ade5c08e65c07d622bad6becac00eef834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E8=A1=B2=E4=B8=8D=E5=87=BA=E5=AE=B6?= Date: Fri, 12 May 2023 11:47:22 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=85=81=E8=AE=B8?= =?UTF-8?q?=E6=89=80=E6=9C=89=E8=B7=A8=E5=9F=9F=E8=AF=B7=E6=B1=82=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=A1=B9=20(#2449)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 配置项为http.allow_cross_domains --- conf/config.ini | 2 ++ src/Common/config.cpp | 2 ++ src/Common/config.h | 2 ++ src/Http/HttpSession.cpp | 9 +++++++-- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/conf/config.ini b/conf/config.ini index 8950b299..d2b2c0dd 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -230,6 +230,8 @@ forbidCacheSuffix= #可以把http代理前真实客户端ip放在http头中:https://github.com/ZLMediaKit/ZLMediaKit/issues/1388 #切勿暴露此key,否则可能导致伪造客户端ip forwarded_ip_header= +#默认允许所有跨域请求 +allow_cross_domains=1 [multicast] #rtp组播截止组播ip地址 diff --git a/src/Common/config.cpp b/src/Common/config.cpp index cae98d55..1654c61c 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -159,6 +159,7 @@ const string kNotFound = HTTP_FIELD "notFound"; const string kDirMenu = HTTP_FIELD "dirMenu"; const string kForbidCacheSuffix = HTTP_FIELD "forbidCacheSuffix"; const string kForwardedIpHeader = HTTP_FIELD "forwarded_ip_header"; +const string kAllowCrossDomains = HTTP_FIELD "allow_cross_domains"; static onceToken token([]() { mINI::Instance()[kSendBufSize] = 64 * 1024; @@ -186,6 +187,7 @@ static onceToken token([]() { << endl; mINI::Instance()[kForbidCacheSuffix] = ""; mINI::Instance()[kForwardedIpHeader] = ""; + mINI::Instance()[kAllowCrossDomains] = 1; }); } // namespace Http diff --git a/src/Common/config.h b/src/Common/config.h index 146c6067..ea874d64 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -246,6 +246,8 @@ extern const std::string kDirMenu; extern const std::string kForbidCacheSuffix; // 可以把http代理前真实客户端ip放在http头中:https://github.com/ZLMediaKit/ZLMediaKit/issues/1388 extern const std::string kForwardedIpHeader; +// 是否允许所有跨域请求 +extern const std::string kAllowCrossDomains; } // namespace Http ////////////SHELL配置/////////// diff --git a/src/Http/HttpSession.cpp b/src/Http/HttpSession.cpp index a990f98b..c1a045f6 100644 --- a/src/Http/HttpSession.cpp +++ b/src/Http/HttpSession.cpp @@ -39,8 +39,13 @@ void HttpSession::Handle_Req_HEAD(ssize_t &content_len){ void HttpSession::Handle_Req_OPTIONS(ssize_t &content_len) { KeyValue header; - header.emplace("Allow", "GET, POST, OPTIONS"); - header.emplace("Access-Control-Allow-Origin", "*"); + header.emplace("Allow", "GET, POST, HEAD, OPTIONS"); + GET_CONFIG(bool, allow_cross_domains, Http::kAllowCrossDomains); + if (allow_cross_domains) { + header.emplace("Access-Control-Allow-Origin", "*"); + header.emplace("Access-Control-Allow-Headers", "*"); + header.emplace("Access-Control-Allow-Methods", "GET, POST, HEAD, OPTIONS"); + } header.emplace("Access-Control-Allow-Credentials", "true"); header.emplace("Access-Control-Request-Methods", "GET, POST, OPTIONS"); header.emplace("Access-Control-Request-Headers", "Accept,Accept-Language,Content-Language,Content-Type"); From 0afe75229e30b5d4729a2f49c29aa8b75d78fe70 Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Sat, 13 May 2023 00:02:06 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8B=89=E6=B5=81?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E8=8E=B7=E5=8F=96=E6=B5=81=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E8=AE=BF=E9=97=AE=E7=A9=BA=E6=8C=87=E9=92=88?= =?UTF-8?q?=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 此bug由 #2448 引入,触发条件: - 1.配置文件rtsp.directProxy设置为0 - 2.调用addStreamProxy代理rtsp流 在非直接代理情况下,PlayerProxy::_media_src为空,导致访问空指针。 --- src/Player/PlayerProxy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Player/PlayerProxy.cpp b/src/Player/PlayerProxy.cpp index 289c7249..5bdb3083 100644 --- a/src/Player/PlayerProxy.cpp +++ b/src/Player/PlayerProxy.cpp @@ -65,8 +65,8 @@ void PlayerProxy::setOnConnect(std::function cb) { void PlayerProxy::setTranslationInfo() { - _transtalion_info.byte_speed = _media_src->getBytesSpeed(); - _transtalion_info.start_time_stamp = _media_src->getCreateStamp(); + _transtalion_info.byte_speed = _media_src ? _media_src->getBytesSpeed() : -1; + _transtalion_info.start_time_stamp = _media_src ? _media_src->getCreateStamp() : 0; _transtalion_info.stream_info.clear(); auto tracks = _muxer->getTracks(); for (auto &track : tracks) { From 4fa04d6a370eb4787de21ef55ad108fed63b34b5 Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Sat, 13 May 2023 00:14:35 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E4=BC=98=E5=8C=96PlayerProxy=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Player/PlayerProxy.cpp | 15 +++++++-------- src/Player/PlayerProxy.h | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Player/PlayerProxy.cpp b/src/Player/PlayerProxy.cpp index 5bdb3083..d1f414d3 100644 --- a/src/Player/PlayerProxy.cpp +++ b/src/Player/PlayerProxy.cpp @@ -34,6 +34,7 @@ PlayerProxy::PlayerProxy( _stream_id = stream_id; _retry_count = retry_count; + setOnClose(nullptr); setOnConnect(nullptr); setOnDisconnect(nullptr); @@ -43,16 +44,15 @@ PlayerProxy::PlayerProxy( _live_secs = 0; _live_status = 1; _repull_count = 0; - _on_close = [](const SockException &) {}; (*this)[Client::kWaitTrackReady] = false; } -void PlayerProxy::setPlayCallbackOnce(const function &cb) { - _on_play = cb; +void PlayerProxy::setPlayCallbackOnce(function cb) { + _on_play = std::move(cb); } -void PlayerProxy::setOnClose(const function &cb) { - _on_close = cb ? cb : [](const SockException &) {}; +void PlayerProxy::setOnClose(function cb) { + _on_close = cb ? std::move(cb) : [](const SockException &) {}; } void PlayerProxy::setOnDisconnect(std::function cb) { @@ -174,7 +174,7 @@ void PlayerProxy::play(const string &strUrlTmp) { MediaPlayer::play(strUrlTmp); } catch (std::exception &ex) { ErrorL << ex.what(); - _on_play_result(SockException(Err_other, ex.what())); + onPlayResult(SockException(Err_other, ex.what())); return; } _pull_url = strUrlTmp; @@ -324,9 +324,8 @@ int PlayerProxy::getStatus() { uint64_t PlayerProxy::getLiveSecs() { if (_live_status == 0) { return _live_secs + _live_ticker.elapsedTime() / 1000; - } else { - return _live_secs; } + return _live_secs; } uint64_t PlayerProxy::getRePullCount() { diff --git a/src/Player/PlayerProxy.h b/src/Player/PlayerProxy.h index 1ed625c6..9cf621da 100644 --- a/src/Player/PlayerProxy.h +++ b/src/Player/PlayerProxy.h @@ -76,13 +76,13 @@ public: * 设置play结果回调,只触发一次;在play执行之前有效 * @param cb 回调对象 */ - void setPlayCallbackOnce(const std::function &cb); + void setPlayCallbackOnce(std::function cb); /** * 设置主动关闭回调 * @param cb 回调对象 */ - void setOnClose(const std::function &cb); + void setOnClose(std::function cb); /** * Set a callback for failed server connection From 4f6e32b51088c64cdffd4ac08efbd86844496c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=8F=E6=A5=9A?= <771730766@qq.com> Date: Sun, 14 May 2023 09:57:59 +0800 Subject: [PATCH 07/12] =?UTF-8?q?mk=5Fmedia=5Finput=5Faac=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=8F=AF=E4=BB=A5=E4=B8=8D=E6=8C=87=E5=AE=9Aadts?= =?UTF-8?q?=E5=A4=B4(#2463)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复issue: #2432 --- api/source/mk_media.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/source/mk_media.cpp b/api/source/mk_media.cpp index 070c12ed..9bd2afa4 100755 --- a/api/source/mk_media.cpp +++ b/api/source/mk_media.cpp @@ -263,7 +263,7 @@ API_EXPORT void API_CALL mk_media_input_yuv(mk_media ctx, const char *yuv[3], in } API_EXPORT int API_CALL mk_media_input_aac(mk_media ctx, const void *data, int len, uint64_t dts, void *adts) { - assert(ctx && data && len > 0 && adts); + assert(ctx && data && len > 0); MediaHelper::Ptr *obj = (MediaHelper::Ptr *) ctx; return (*obj)->getChannel()->inputAAC((const char *) data, len, dts, (char *) adts); } From cb362371b917ff36ab0a8e20deb6525827e1f12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=8F=E6=A5=9A?= <771730766@qq.com> Date: Sun, 14 May 2023 10:10:08 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E6=9B=B4=E6=96=B0zltoolkit,=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DiOS=E4=B8=8B=E7=BC=96=E8=AF=91=E9=97=AE=E9=A2=98=20=20?= =?UTF-8?q?(#2464)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 参考:#2459 --- 3rdpart/ZLToolKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdpart/ZLToolKit b/3rdpart/ZLToolKit index d134fbb9..b30eeca0 160000 --- a/3rdpart/ZLToolKit +++ b/3rdpart/ZLToolKit @@ -1 +1 @@ -Subproject commit d134fbb9fe0b108dddb66a7bfa35b7b438426411 +Subproject commit b30eeca034456417dfca72aa0d2258031013a5e6 From 15e76293d0921c9b9a73bddac9516f9940423a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=8F=E6=A5=9A?= <771730766@qq.com> Date: Sun, 14 May 2023 10:19:07 +0800 Subject: [PATCH 09/12] =?UTF-8?q?readme=E6=96=B0=E5=A2=9E=E5=A4=9A?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E8=B7=B3=E8=BD=AC=E9=93=BE=E6=8E=A5=20(#2465?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ README_en.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 9843b217..fa9f50d5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ![logo](https://raw.githubusercontent.com/ZLMediaKit/ZLMediaKit/master/www/logo.png) +简体中文 | [English](./README_en.md) + # 一个基于C++11的高性能运营级流媒体服务框架 [![](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/ZLMediaKit/ZLMediaKit/blob/master/LICENSE) diff --git a/README_en.md b/README_en.md index 25980d01..b7410f8b 100644 --- a/README_en.md +++ b/README_en.md @@ -1,5 +1,7 @@ ![logo](https://raw.githubusercontent.com/zlmediakit/ZLMediaKit/master/www/logo.png) +[简体中文](./README.md) | English + # An high-performance, enterprise-level streaming media service framework based on C++11. From 7e4010df83ffd9b513daaea02f93b53f77a26716 Mon Sep 17 00:00:00 2001 From: Kiki Date: Thu, 18 May 2023 16:35:54 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8DstartSendRtp=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3gop=E7=BC=93=E5=AD=98=E5=8A=9F=E8=83=BD=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E5=A4=B1=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98=20(#2455?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 如果帧序列为SPS PPS SEI IDR,那么GOP缓存会从IDR开始,导致解码器未获取到SPS PPS从而不能秒开 --- src/Common/MultiMediaSourceMuxer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Common/MultiMediaSourceMuxer.cpp b/src/Common/MultiMediaSourceMuxer.cpp index daa68769..440adcc1 100644 --- a/src/Common/MultiMediaSourceMuxer.cpp +++ b/src/Common/MultiMediaSourceMuxer.cpp @@ -327,7 +327,6 @@ EventPoller::Ptr MultiMediaSourceMuxer::getOwnerPoller(MediaSource &sender) { } bool MultiMediaSourceMuxer::onTrackReady(const Track::Ptr &track) { - bool ret = false; if (_rtmp) { ret = _rtmp->addTrack(track) ? true : ret; @@ -471,7 +470,9 @@ bool MultiMediaSourceMuxer::onTrackFrame(const Frame::Ptr &frame_in) { // 视频时,遇到第一帧配置帧或关键帧则标记为gop开始处 auto video_key_pos = frame->keyFrame() || frame->configFrame(); _ring->write(frame, video_key_pos && !_video_key_pos); - _video_key_pos = video_key_pos; + if (!frame->dropAble()) { + _video_key_pos = video_key_pos; + } } else { // 没有视频时,设置is_key为true,目的是关闭gop缓存 _ring->write(frame, !haveVideo()); From d4f80171171cdfc00c6be27fab33124eae6a1bdd Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Wed, 24 May 2023 10:50:49 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dmk=5Ftcp=5Fsession=5Fre?= =?UTF-8?q?f=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E8=AF=AF=E5=AF=BC?= =?UTF-8?q?=E6=80=A7=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/include/mk_tcp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/include/mk_tcp.h b/api/include/mk_tcp.h index 84deed8e..4ab19da1 100644 --- a/api/include/mk_tcp.h +++ b/api/include/mk_tcp.h @@ -82,11 +82,11 @@ API_EXPORT void API_CALL mk_tcp_session_send_buffer(const mk_tcp_session ctx, mk API_EXPORT void API_CALL mk_tcp_session_send_safe(const mk_tcp_session ctx, const char *data, size_t len); API_EXPORT void API_CALL mk_tcp_session_send_buffer_safe(const mk_tcp_session ctx, mk_buffer buffer); -//创建mk_tcp_session的弱引用 +//创建mk_tcp_session的强引用 API_EXPORT mk_tcp_session_ref API_CALL mk_tcp_session_ref_from(const mk_tcp_session ctx); -//删除mk_tcp_session的弱引用 +//删除mk_tcp_session的强引用 API_EXPORT void mk_tcp_session_ref_release(const mk_tcp_session_ref ref); -//根据弱引用获取mk_tcp_session,如果mk_tcp_session已经销毁,那么返回NULL +//根据强引用获取mk_tcp_session API_EXPORT mk_tcp_session mk_tcp_session_from_ref(const mk_tcp_session_ref ref); ///////////////////////////////////////////自定义tcp服务///////////////////////////////////////////// From 936babf4599e619b4dc721a0dc75562ddd67481c Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Thu, 25 May 2023 16:57:03 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E6=96=B0=E5=A2=9Emk=5Fmedia=5Fsource=5Ff?= =?UTF-8?q?ind2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/include/mk_events_objects.h | 6 ++++++ api/source/mk_events_objects.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/api/include/mk_events_objects.h b/api/include/mk_events_objects.h index f8d3c571..8f362980 100644 --- a/api/include/mk_events_objects.h +++ b/api/include/mk_events_objects.h @@ -132,6 +132,12 @@ API_EXPORT void API_CALL mk_media_source_find(const char *schema, int from_mp4, void *user_data, on_mk_media_source_find_cb cb); + +API_EXPORT const mk_media_source API_CALL mk_media_source_find2(const char *schema, + const char *vhost, + const char *app, + const char *stream, + int from_mp4); //MediaSource::for_each_media() API_EXPORT void API_CALL mk_media_source_for_each(void *user_data, on_mk_media_source_find_cb cb, const char *schema, const char *vhost, const char *app, const char *stream); diff --git a/api/source/mk_events_objects.cpp b/api/source/mk_events_objects.cpp index 4b641a2b..fa820062 100644 --- a/api/source/mk_events_objects.cpp +++ b/api/source/mk_events_objects.cpp @@ -248,6 +248,16 @@ API_EXPORT void API_CALL mk_media_source_find(const char *schema, cb(user_data, (mk_media_source)src.get()); } +API_EXPORT const mk_media_source API_CALL mk_media_source_find2(const char *schema, + const char *vhost, + const char *app, + const char *stream, + int from_mp4) { + assert(schema && vhost && app && stream); + auto src = MediaSource::find(schema, vhost, app, stream, from_mp4); + return (mk_media_source)src.get(); +} + API_EXPORT void API_CALL mk_media_source_for_each(void *user_data, on_mk_media_source_find_cb cb, const char *schema, const char *vhost, const char *app, const char *stream) { assert(cb);