diff --git a/conf/config.ini b/conf/config.ini index 2e407739..8043f750 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -55,6 +55,21 @@ modifyStamp=0 #服务器唯一id,用于触发hook时区别是哪台服务器 mediaServerId=your_server_id +###### 以下是按需转协议的开关,在测试ZLMediaKit的接收推流性能时,请关闭以下全部开关 +###### 如果某种协议你用不到,你可以把以下开关置1以便节省资源(但是还是可以播放,只是第一个播放者体验稍微差点), +###### 如果某种协议你想获取最好的用户体验,请置1(第一个播放者可以秒开,且不花屏) + +#hls协议是否按需生成,如果hls.segNum配置为0(意味着hls录制),那么hls将一直生成(不管此开关) +hls_demand=0 +#rtsp[s]协议是否按需生成 +rtsp_demand=0 +#rtmp[s]、http[s]-flv、ws[s]-flv协议是否按需生成 +rtmp_demand=0 +#http[s]-ts协议是否按需生成 +ts_demand=0 +#http[s]-fmp4、ws[s]-fmp4协议是否按需生成 +fmp4_demand=0 + [hls] #hls写文件的buf大小,调整参数可以提高文件io性能 fileBufSize=65536 diff --git a/src/Common/config.cpp b/src/Common/config.cpp index 38091f0b..8dbadda6 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -69,6 +69,11 @@ const string kPublishToHls = GENERAL_FIELD"publishToHls"; const string kPublishToMP4 = GENERAL_FIELD"publishToMP4"; const string kMergeWriteMS = GENERAL_FIELD"mergeWriteMS"; const string kModifyStamp = GENERAL_FIELD"modifyStamp"; +const string kHlsDemand = GENERAL_FIELD"hls_demand"; +const string kRtspDemand = GENERAL_FIELD"rtsp_demand"; +const string kRtmpDemand = GENERAL_FIELD"rtmp_demand"; +const string kTSDemand = GENERAL_FIELD"ts_demand"; +const string kFMP4Demand = GENERAL_FIELD"fmp4_demand"; onceToken token([](){ mINI::Instance()[kFlowThreshold] = 1024; diff --git a/src/Common/config.h b/src/Common/config.h index bc11d9b6..4c41e1f9 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -181,6 +181,12 @@ extern const string kPublishToMP4 ; extern const string kMergeWriteMS ; //全局的时间戳覆盖开关,在转协议时,对frame进行时间戳覆盖 extern const string kModifyStamp; +//按需转协议的开关 +extern const string kHlsDemand; +extern const string kRtspDemand; +extern const string kRtmpDemand; +extern const string kTSDemand; +extern const string kFMP4Demand; }//namespace General diff --git a/src/FMP4/FMP4MediaSourceMuxer.h b/src/FMP4/FMP4MediaSourceMuxer.h index 3d8482a0..6d133db5 100644 --- a/src/FMP4/FMP4MediaSourceMuxer.h +++ b/src/FMP4/FMP4MediaSourceMuxer.h @@ -41,26 +41,29 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { - _enabled = size; - if (!size) { + GET_CONFIG(bool, fmp4_demand, General::kFMP4Demand); + _enabled = fmp4_demand ? size : true; + if (!size && fmp4_demand) { _clear_cache = true; } MediaSourceEventInterceptor::onReaderChanged(sender, size); } void inputFrame(const Frame::Ptr &frame) override { - if (_clear_cache) { + GET_CONFIG(bool, fmp4_demand, General::kFMP4Demand); + if (_clear_cache && fmp4_demand) { _clear_cache = false; _media_src->clearCache(); } - if (_enabled) { + if (_enabled || !fmp4_demand) { MP4MuxerMemory::inputFrame(frame); } } bool isEnabled() { + GET_CONFIG(bool, fmp4_demand, General::kFMP4Demand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return _clear_cache ? true : _enabled; + return fmp4_demand ? (_clear_cache ? true : _enabled) : true; } void onAllTrackReady() { diff --git a/src/Record/HlsRecorder.h b/src/Record/HlsRecorder.h index 465a4199..5b076d36 100644 --- a/src/Record/HlsRecorder.h +++ b/src/Record/HlsRecorder.h @@ -45,9 +45,10 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { + GET_CONFIG(bool, hls_demand, General::kHlsDemand); //hls保留切片个数为0时代表为hls录制(不删除切片),那么不管有无观看者都一直生成hls - _enabled = _hls->isLive() ? size : true; - if (!size && _hls->isLive()) { + _enabled = hls_demand ? (_hls->isLive() ? size : true) : true; + if (!size && _hls->isLive() && hls_demand) { //hls直播时,如果无人观看就删除视频缓存,目的是为了防止视频跳跃 _clear_cache = true; } @@ -55,16 +56,18 @@ public: } bool isEnabled() { + GET_CONFIG(bool, hls_demand, General::kHlsDemand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return _clear_cache ? true : _enabled; + return hls_demand ? (_clear_cache ? true : _enabled) : true; } - void inputFrame(const Frame::Ptr &frame) override{ - if (_clear_cache) { + void inputFrame(const Frame::Ptr &frame) override { + GET_CONFIG(bool, hls_demand, General::kHlsDemand); + if (_clear_cache && hls_demand) { _clear_cache = false; _hls->clearCache(); } - if (_enabled) { + if (_enabled || !hls_demand) { TsMuxer::inputFrame(frame); } } diff --git a/src/Rtmp/RtmpMediaSourceMuxer.h b/src/Rtmp/RtmpMediaSourceMuxer.h index c8ef9652..f998a3a2 100644 --- a/src/Rtmp/RtmpMediaSourceMuxer.h +++ b/src/Rtmp/RtmpMediaSourceMuxer.h @@ -50,26 +50,29 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { - _enabled = size; - if (!size) { + GET_CONFIG(bool, rtmp_demand, General::kRtmpDemand); + _enabled = rtmp_demand ? size : true; + if (!size && rtmp_demand) { _clear_cache = true; } MediaSourceEventInterceptor::onReaderChanged(sender, size); } void inputFrame(const Frame::Ptr &frame) override { - if (_clear_cache) { + GET_CONFIG(bool, rtmp_demand, General::kRtmpDemand); + if (_clear_cache && rtmp_demand) { _clear_cache = false; _media_src->clearCache(); } - if (_enabled) { + if (_enabled || !rtmp_demand) { RtmpMuxer::inputFrame(frame); } } bool isEnabled() { + GET_CONFIG(bool, rtmp_demand, General::kRtmpDemand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return _clear_cache ? true : _enabled; + return rtmp_demand ? (_clear_cache ? true : _enabled) : true; } private: diff --git a/src/Rtsp/RtspMediaSourceMuxer.h b/src/Rtsp/RtspMediaSourceMuxer.h index eb2a4bd4..18059910 100644 --- a/src/Rtsp/RtspMediaSourceMuxer.h +++ b/src/Rtsp/RtspMediaSourceMuxer.h @@ -49,26 +49,29 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { - _enabled = size; - if (!size) { + GET_CONFIG(bool, rtsp_demand, General::kRtspDemand); + _enabled = rtsp_demand ? size : true; + if (!size && rtsp_demand) { _clear_cache = true; } MediaSourceEventInterceptor::onReaderChanged(sender, size); } void inputFrame(const Frame::Ptr &frame) override { - if (_clear_cache) { + GET_CONFIG(bool, rtsp_demand, General::kRtspDemand); + if (_clear_cache && rtsp_demand) { _clear_cache = false; _media_src->clearCache(); } - if (_enabled) { + if (_enabled || !rtsp_demand) { RtspMuxer::inputFrame(frame); } } bool isEnabled() { + GET_CONFIG(bool, rtsp_demand, General::kRtspDemand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return _clear_cache ? true : _enabled; + return rtsp_demand ? (_clear_cache ? true : _enabled) : true; } private: diff --git a/src/TS/TSMediaSourceMuxer.h b/src/TS/TSMediaSourceMuxer.h index 34051808..a8cf9efc 100644 --- a/src/TS/TSMediaSourceMuxer.h +++ b/src/TS/TSMediaSourceMuxer.h @@ -40,26 +40,29 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { - _enabled = size; - if (!size) { + GET_CONFIG(bool, ts_demand, General::kTSDemand); + _enabled = ts_demand ? size : true; + if (!size && ts_demand) { _clear_cache = true; } MediaSourceEventInterceptor::onReaderChanged(sender, size); } void inputFrame(const Frame::Ptr &frame) override { - if (_clear_cache) { + GET_CONFIG(bool, ts_demand, General::kTSDemand); + if (_clear_cache && ts_demand) { _clear_cache = false; _media_src->clearCache(); } - if (_enabled) { + if (_enabled || !ts_demand) { TsMuxer::inputFrame(frame); } } bool isEnabled() { + GET_CONFIG(bool, ts_demand, General::kTSDemand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return _clear_cache ? true : _enabled; + return ts_demand ? (_clear_cache ? true : _enabled) : true; } protected: