mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-05 02:38:10 +08:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "Common/config.h"
|
||||
#include "MultiMediaSourceMuxer.h"
|
||||
namespace mediakit {
|
||||
|
||||
@@ -480,11 +481,21 @@ void MultiMediaSourceMuxer::inputFrame(const Frame::Ptr &frame_in) {
|
||||
}
|
||||
|
||||
bool MultiMediaSourceMuxer::isEnabled(){
|
||||
GET_CONFIG(uint32_t, stream_none_reader_delay_ms, General::kStreamNoneReaderDelayMS);
|
||||
if (!_is_enable || _last_check.elapsedTime() > stream_none_reader_delay_ms) {
|
||||
//无人观看时,每次检查是否真的无人观看
|
||||
//有人观看时,则延迟一定时间检查一遍是否无人观看了(节省性能)
|
||||
#if defined(ENABLE_RTPPROXY)
|
||||
return (_muxer->isEnabled() || _rtp_sender);
|
||||
_is_enable = (_muxer->isEnabled() || _rtp_sender);
|
||||
#else
|
||||
return _muxer->isEnabled();
|
||||
_is_enable = _muxer->isEnabled();
|
||||
#endif //ENABLE_RTPPROXY
|
||||
if (_is_enable) {
|
||||
//无人观看时,不刷新计时器,因为无人观看时每次都会检查一遍,所以刷新计数器无意义且浪费cpu
|
||||
_last_check.resetTime();
|
||||
}
|
||||
}
|
||||
return _is_enable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -184,6 +184,8 @@ public:
|
||||
void onAllTrackReady() override;
|
||||
|
||||
private:
|
||||
bool _is_enable = false;
|
||||
Ticker _last_check;
|
||||
Stamp _stamp[2];
|
||||
MultiMuxerPrivate::Ptr _muxer;
|
||||
std::weak_ptr<MultiMuxerPrivate::Listener> _track_listener;
|
||||
|
||||
@@ -71,6 +71,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;
|
||||
@@ -84,6 +89,12 @@ onceToken token([](){
|
||||
mINI::Instance()[kMergeWriteMS] = 0;
|
||||
mINI::Instance()[kModifyStamp] = 0;
|
||||
mINI::Instance()[kMediaServerId] = makeRandStr(16);
|
||||
mINI::Instance()[kHlsDemand] = 0;
|
||||
mINI::Instance()[kRtspDemand] = 0;
|
||||
mINI::Instance()[kRtmpDemand] = 0;
|
||||
mINI::Instance()[kTSDemand] = 0;
|
||||
mINI::Instance()[kFMP4Demand] = 0;
|
||||
|
||||
},nullptr);
|
||||
|
||||
}//namespace General
|
||||
|
||||
@@ -189,6 +189,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
|
||||
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -169,10 +169,10 @@ bool PlayerProxy::close(MediaSource &sender,bool force) {
|
||||
strongSelf->_muxer.reset();
|
||||
strongSelf->setMediaSource(nullptr);
|
||||
strongSelf->teardown();
|
||||
if (strongSelf->_on_close) {
|
||||
strongSelf->_on_close();
|
||||
}
|
||||
});
|
||||
if (_on_close) {
|
||||
_on_close();
|
||||
}
|
||||
WarnL << sender.getSchema() << "/" << sender.getVhost() << "/" << sender.getApp() << "/" << sender.getId() << " " << force;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -101,6 +101,14 @@ bool RtpProcess::inputRtp(bool is_udp, const Socket::Ptr &sock, const char *data
|
||||
if (!_process) {
|
||||
_process = std::make_shared<GB28181Process>(_media_info, this);
|
||||
}
|
||||
|
||||
GET_CONFIG(string, dump_dir, RtpProxy::kDumpDir);
|
||||
if (!_muxer->isEnabled() && !dts_out && dump_dir.empty()) {
|
||||
//无人访问、且不取时间戳、不导出调试文件时,我们可以直接丢弃数据
|
||||
_last_frame_time.resetTime();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = _process ? _process->inputRtp(is_udp, data, len) : false;
|
||||
if (dts_out) {
|
||||
*dts_out = _dts;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user