diff --git a/conf/config.ini b/conf/config.ini index 8c1a771c..2dd3dcb3 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -29,6 +29,56 @@ log=./ffmpeg/ffmpeg.log # 自动重启的时间(秒), 默认为0, 也就是不自动重启. 主要是为了避免长时间ffmpeg拉流导致的不同步现象 restart_sec=0 +#转协议相关开关;如果addStreamProxy api和on_publish hook回复未指定转协议参数,则采用这些配置项 +[protocol] +#转协议时,是否开启帧级时间戳覆盖 +modify_stamp=0 +#转协议是否开启音频 +enable_audio=1 +#添加acc静音音频,在关闭音频时,此开关无效 +add_mute_audio=1 +#推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 +#置0关闭此特性(推流断开会导致立即断开播放器) +#此参数不应大于播放器超时时间;单位毫秒 +continue_push_ms=15000 + +#是否开启转换为hls +enable_hls=1 +#是否开启MP4录制 +enable_mp4=0 +#是否开启转换为rtsp/webrtc +enable_rtsp=1 +#是否开启转换为rtmp/flv +enable_rtmp=1 +#是否开启转换为http-ts/ws-ts +enable_ts=1 +#是否开启转换为http-fmp4/ws-fmp4 +enable_fmp4=1 + +#是否将mp4录制当做观看者 +mp4_as_player=0 +#mp4切片大小,单位秒 +mp4_max_second=3600 +#mp4录制保存路径 +mp4_save_path=./www + +#hls录制保存路径 +hls_save_path=./www + +###### 以下是按需转协议的开关,在测试ZLMediaKit的接收推流性能时,请把下面开关置1 +###### 如果某种协议你用不到,你可以把以下开关置1以便节省资源(但是还是可以播放,只是第一个播放者体验稍微差点), +###### 如果某种协议你想获取最好的用户体验,请置0(第一个播放者可以秒开,且不花屏) +#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 + [general] #是否启用虚拟主机 enableVhost=0 @@ -44,43 +94,14 @@ maxStreamWaitMS=15000 #某个流无人观看时,触发hook.on_stream_none_reader事件的最大等待时间,单位毫秒 #在配合hook.on_stream_none_reader事件时,可以做到无人观看自动停止拉流或停止接收推流 streamNoneReaderDelayMS=20000 -#是否全局添加静音aac音频,转协议时有效 -#有些播放器在打开单视频流时不能秒开,添加静音音频可以加快秒开速度 -addMuteAudio=1 #拉流代理时如果断流再重连成功是否删除前一次的媒体流数据,如果删除将重新开始, #如果不删除将会接着上一次的数据继续写(录制hls/mp4时会继续在前一个文件后面写) resetWhenRePlay=1 -#是否默认推流时转换成hls,hook接口(on_publish)中可以覆盖该设置 -publishToHls=1 -#是否默认推流时mp4录像,hook接口(on_publish)中可以覆盖该设置 -publishToMP4=0 #合并写缓存大小(单位毫秒),合并写指服务器缓存一定的数据后才会一次性写入socket,这样能提高性能,但是会提高延时 #开启后会同时关闭TCP_NODELAY并开启MSG_MORE mergeWriteMS=0 -#全局的时间戳覆盖开关,在转协议时,对frame进行时间戳覆盖 -#该开关对rtsp/rtmp/rtp推流、rtsp/rtmp/hls拉流代理转协议时生效 -#会直接影响rtsp/rtmp/hls/mp4/flv等协议的时间戳 -#同协议情况下不影响(例如rtsp/rtmp推流,那么播放rtsp/rtmp时不会影响时间戳) -modifyStamp=0 #服务器唯一id,用于触发hook时区别是哪台服务器 mediaServerId=your_server_id -#转协议是否全局开启或关闭音频 -enable_audio=1 - -###### 以下是按需转协议的开关,在测试ZLMediaKit的接收推流性能时,请把下面开关置1 -###### 如果某种协议你用不到,你可以把以下开关置1以便节省资源(但是还是可以播放,只是第一个播放者体验稍微差点), -###### 如果某种协议你想获取最好的用户体验,请置0(第一个播放者可以秒开,且不花屏) - -#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 #最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track wait_track_ready_ms=10000 @@ -89,17 +110,10 @@ wait_track_ready_ms=10000 wait_add_track_ms=3000 #如果track未就绪,我们先缓存帧数据,但是有最大个数限制,防止内存溢出 unready_frame_cache=100 -#推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。 -#置0关闭此特性(推流断开会导致立即断开播放器) -#此参数不应大于播放器超时时间 -continue_push_ms=15000 [hls] #hls写文件的buf大小,调整参数可以提高文件io性能 fileBufSize=65536 -#hls保存文件路径 -#可以为相对(相对于本可执行程序目录)或绝对路径 -filePath=./www #hls最大切片时间 segDur=2 #m3u8索引中,hls保留切片个数(实际保留切片个数大2~3个) @@ -155,7 +169,6 @@ on_server_started=https://127.0.0.1/index/hook/on_server_started on_server_keepalive=https://127.0.0.1/index/hook/on_server_keepalive #发送rtp(startSendRtp)被动关闭时回调 on_send_rtp_stopped=https://127.0.0.1/index/hook/on_send_rtp_stopped - #rtp server 超时未收到数据 on_rtp_server_timeout=https://127.0.0.1/index/hook/on_rtp_server_timeout @@ -232,11 +245,6 @@ udpTTL=64 appName=record #mp4录制写文件缓存,单位BYTE,调整参数可以提高文件io性能 fileBufSize=65536 -#mp4录制保存、mp4点播根路径 -#可以为相对(相对于本可执行程序目录)或绝对路径 -filePath=./www -#mp4录制切片时间,单位秒 -fileSecond=3600 #mp4点播每次流化数据量,单位毫秒, #减少该值可以让点播数据发送量更平滑,增大该值则更节省cpu资源 sampleMS=500 @@ -244,8 +252,6 @@ sampleMS=500 fastStart=0 #MP4点播(rtsp/rtmp/http-flv/ws-flv)是否循环播放文件 fileRepeat=0 -#MP4录制是否当做播放器参与播放人数统计 -mp4_as_player=0 [rtmp] #rtmp必须在此时间内完成握手,否则服务器会断开链接,单位秒 @@ -281,25 +287,18 @@ timeoutSec=15 #随机端口范围,最少确保36个端口 #该范围同时限制rtsp服务器udp端口范围 port_range=30000-35000 - #rtp h264 负载的pt h264_pt=98 - #rtp h265 负载的pt h265_pt=99 - #rtp ps 负载的pt ps_pt=96 - #rtp ts 负载的pt ts_pt=33 - #rtp opus 负载的pt opus_pt=100 - #rtp g711u 负载的pt g711u_pt=0 - #rtp g711a 负载的pt g711a_pt=8 @@ -330,10 +329,8 @@ timeoutSec=5 #srt udp服务器监听端口号,所有srt客户端将通过该端口传输srt数据, #该端口是多线程的,同时支持客户端网络切换导致的连接迁移 port=9000 - #srt 协议中延迟缓存的估算参数,在握手阶段估算rtt ,然后latencyMul*rtt 为最大缓存时长,此参数越大,表示等待重传的时长就越大 latencyMul=4 - #包缓存的大小 pktBufSize=8192 diff --git a/src/Common/MediaSource.cpp b/src/Common/MediaSource.cpp index 6c777a97..5f30e215 100644 --- a/src/Common/MediaSource.cpp +++ b/src/Common/MediaSource.cpp @@ -8,12 +8,13 @@ * may be found in the AUTHORS file in the root of the source tree. */ -#include "MediaSource.h" -#include "Record/MP4Reader.h" #include "Util/util.h" +#include "Util/NoticeCenter.h" #include "Network/sockutil.h" #include "Network/TcpSession.h" -#include "Util/NoticeCenter.h" +#include "MediaSource.h" +#include "Common/config.h" +#include "Record/MP4Reader.h" using namespace std; using namespace toolkit; @@ -49,6 +50,59 @@ string getOriginTypeString(MediaOriginType type){ } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ProtocolOption::ProtocolOption() { + GET_CONFIG(bool, s_modify_stamp, Protocol::kModifyStamp); + GET_CONFIG(bool, s_enabel_audio, Protocol::kEnableAudio); + GET_CONFIG(bool, s_add_mute_audio, Protocol::kAddMuteAudio); + GET_CONFIG(uint32_t, s_continue_push_ms, Protocol::kContinuePushMS); + + GET_CONFIG(bool, s_enable_hls, Protocol::kEnableHls); + GET_CONFIG(bool, s_enable_mp4, Protocol::kEnableMP4); + GET_CONFIG(bool, s_enable_rtsp, Protocol::kEnableRtsp); + GET_CONFIG(bool, s_enable_rtmp, Protocol::kEnableRtmp); + GET_CONFIG(bool, s_enable_ts, Protocol::kEnableTS); + GET_CONFIG(bool, s_enable_fmp4, Protocol::kEnableFMP4); + + GET_CONFIG(bool, s_hls_demand, Protocol::kHlsDemand); + GET_CONFIG(bool, s_rtsp_demand, Protocol::kRtspDemand); + GET_CONFIG(bool, s_rtmp_demand, Protocol::kRtmpDemand); + GET_CONFIG(bool, s_ts_demand, Protocol::kTSDemand); + GET_CONFIG(bool, s_fmp4_demand, Protocol::kFMP4Demand); + + GET_CONFIG(bool, s_mp4_as_player, Protocol::kMP4AsPlayer); + GET_CONFIG(uint32_t, s_mp4_max_second, Protocol::kMP4MaxSecond); + GET_CONFIG(string, s_mp4_save_path, Protocol::kMP4SavePath); + + GET_CONFIG(string, s_hls_save_path, Protocol::kHlsSavePath); + + modify_stamp = s_modify_stamp; + enable_audio = s_enabel_audio; + add_mute_audio = s_add_mute_audio; + continue_push_ms = s_continue_push_ms; + + enable_hls = s_enable_hls; + enable_mp4 = s_enable_mp4; + enable_rtsp = s_enable_rtsp; + enable_rtmp = s_enable_rtmp; + enable_ts = s_enable_ts; + enable_fmp4 = s_enable_fmp4; + + hls_demand = s_hls_demand; + rtsp_demand = s_rtsp_demand; + rtmp_demand = s_rtmp_demand; + ts_demand = s_ts_demand; + fmp4_demand = s_fmp4_demand; + + mp4_as_player = s_mp4_as_player; + mp4_max_second = s_mp4_max_second; + mp4_save_path = s_mp4_save_path; + + hls_save_path = s_hls_save_path; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + struct MediaSourceNull : public MediaSource { MediaSourceNull() : MediaSource("schema", "vhost", "app", "stream") {}; int readerCount() override { return 0; } diff --git a/src/Common/MediaSource.h b/src/Common/MediaSource.h index 5b7f2f46..698cefca 100644 --- a/src/Common/MediaSource.h +++ b/src/Common/MediaSource.h @@ -134,6 +134,91 @@ private: toolkit::Timer::Ptr _async_close_timer; }; +class ProtocolOption { +public: + ProtocolOption(); + + //时间戳修复这一路流标志位 + bool modify_stamp; + //转协议是否开启音频 + bool enable_audio; + //添加静音音频,在关闭音频时,此开关无效 + bool add_mute_audio; + //断连续推延时,单位毫秒,默认采用配置文件 + uint32_t continue_push_ms; + + //是否开启转换为hls + bool enable_hls; + //是否开启MP4录制 + bool enable_mp4; + //是否开启转换为rtsp/webrtc + bool enable_rtsp; + //是否开启转换为rtmp/flv + bool enable_rtmp; + //是否开启转换为http-ts/ws-ts + bool enable_ts; + //是否开启转换为http-fmp4/ws-fmp4 + bool enable_fmp4; + + // hls协议是否按需生成,如果hls.segNum配置为0(意味着hls录制),那么hls将一直生成(不管此开关) + bool hls_demand; + // rtsp[s]协议是否按需生成 + bool rtsp_demand; + // rtmp[s]、http[s]-flv、ws[s]-flv协议是否按需生成 + bool rtmp_demand; + // http[s]-ts协议是否按需生成 + bool ts_demand; + // http[s]-fmp4、ws[s]-fmp4协议是否按需生成 + bool fmp4_demand; + + //是否将mp4录制当做观看者 + bool mp4_as_player; + //mp4切片大小,单位秒 + size_t mp4_max_second; + //mp4录制保存路径 + std::string mp4_save_path; + + //hls录制保存路径 + std::string hls_save_path; + + template + ProtocolOption(const MAP &allArgs) : ProtocolOption() { +#define GET_OPT_VALUE(key) getArgsValue(allArgs, #key, key) + GET_OPT_VALUE(modify_stamp); + GET_OPT_VALUE(enable_audio); + GET_OPT_VALUE(add_mute_audio); + GET_OPT_VALUE(continue_push_ms); + + GET_OPT_VALUE(enable_hls); + GET_OPT_VALUE(enable_mp4); + GET_OPT_VALUE(enable_rtsp); + GET_OPT_VALUE(enable_rtmp); + GET_OPT_VALUE(enable_ts); + GET_OPT_VALUE(enable_fmp4); + + GET_OPT_VALUE(hls_demand); + GET_OPT_VALUE(rtsp_demand); + GET_OPT_VALUE(rtmp_demand); + GET_OPT_VALUE(ts_demand); + GET_OPT_VALUE(fmp4_demand); + + GET_OPT_VALUE(mp4_max_second); + GET_OPT_VALUE(mp4_as_player); + GET_OPT_VALUE(mp4_save_path); + + GET_OPT_VALUE(hls_save_path); + } + +private: + template + static void getArgsValue(const MAP &allArgs, const KEY &key, TYPE &value) { + auto val = ((MAP &)allArgs)[key]; + if (!val.empty()) { + value = (TYPE)val; + } + } +}; + //该对象用于拦截感兴趣的MediaSourceEvent事件 class MediaSourceEventInterceptor : public MediaSourceEvent { public: diff --git a/src/Common/MultiMediaSourceMuxer.cpp b/src/Common/MultiMediaSourceMuxer.cpp index 47012478..7d01f382 100644 --- a/src/Common/MultiMediaSourceMuxer.cpp +++ b/src/Common/MultiMediaSourceMuxer.cpp @@ -21,26 +21,8 @@ namespace toolkit { namespace mediakit { -ProtocolOption::ProtocolOption() { - GET_CONFIG(bool, s_to_hls, General::kPublishToHls); - GET_CONFIG(bool, s_to_mp4, General::kPublishToMP4); - GET_CONFIG(bool, s_enabel_audio, General::kEnableAudio); - GET_CONFIG(bool, s_add_mute_audio, General::kAddMuteAudio); - GET_CONFIG(bool, s_mp4_as_player, Record::kMP4AsPlayer); - GET_CONFIG(uint32_t, s_continue_push_ms, General::kContinuePushMS); - GET_CONFIG(bool, s_modify_stamp, General::kModifyStamp); - - enable_hls = s_to_hls; - enable_mp4 = s_to_mp4; - enable_audio = s_enabel_audio; - add_mute_audio = s_add_mute_audio; - continue_push_ms = s_continue_push_ms; - mp4_as_player = s_mp4_as_player; - modify_stamp = s_modify_stamp; -} - -static std::shared_ptr makeRecorder(MediaSource &sender, const vector &tracks, Recorder::type type, const string &custom_path, size_t max_second){ - auto recorder = Recorder::createRecorder(type, sender.getVhost(), sender.getApp(), sender.getId(), custom_path, max_second); +static std::shared_ptr makeRecorder(MediaSource &sender, const vector &tracks, Recorder::type type, const ProtocolOption &option){ + auto recorder = Recorder::createRecorder(type, sender.getVhost(), sender.getApp(), sender.getId(), option); for (auto &track : tracks) { recorder->addTrack(track); } @@ -106,23 +88,23 @@ MultiMediaSourceMuxer::MultiMediaSourceMuxer(const string &vhost, const string & _option = option; if (option.enable_rtmp) { - _rtmp = std::make_shared(vhost, app, stream, std::make_shared(dur_sec)); + _rtmp = std::make_shared(vhost, app, stream, option, std::make_shared(dur_sec)); } if (option.enable_rtsp) { - _rtsp = std::make_shared(vhost, app, stream, std::make_shared(dur_sec)); + _rtsp = std::make_shared(vhost, app, stream, option, std::make_shared(dur_sec)); } if (option.enable_hls) { - _hls = dynamic_pointer_cast(Recorder::createRecorder(Recorder::type_hls, vhost, app, stream, option.hls_save_path)); + _hls = dynamic_pointer_cast(Recorder::createRecorder(Recorder::type_hls, vhost, app, stream, option)); } if (option.enable_mp4) { - _mp4 = Recorder::createRecorder(Recorder::type_mp4, vhost, app, stream, option.mp4_save_path, option.mp4_max_second); + _mp4 = Recorder::createRecorder(Recorder::type_mp4, vhost, app, stream, option); } if (option.enable_ts) { - _ts = std::make_shared(vhost, app, stream); + _ts = std::make_shared(vhost, app, stream, option); } #if defined(ENABLE_MP4) if (option.enable_fmp4) { - _fmp4 = std::make_shared(vhost, app, stream); + _fmp4 = std::make_shared(vhost, app, stream, option); } #endif @@ -212,7 +194,8 @@ bool MultiMediaSourceMuxer::setupRecord(MediaSource &sender, Recorder::type type case Recorder::type_hls : { if (start && !_hls) { //开始录制 - auto hls = dynamic_pointer_cast(makeRecorder(sender, getTracks(), type, custom_path, max_second)); + _option.hls_save_path = custom_path; + auto hls = dynamic_pointer_cast(makeRecorder(sender, getTracks(), type, _option)); if (hls) { //设置HlsMediaSource的事件监听器 hls->setListener(shared_from_this()); @@ -227,7 +210,9 @@ bool MultiMediaSourceMuxer::setupRecord(MediaSource &sender, Recorder::type type case Recorder::type_mp4 : { if (start && !_mp4) { //开始录制 - _mp4 = makeRecorder(sender, getTracks(), type, custom_path, max_second); + _option.mp4_save_path = custom_path; + _option.mp4_max_second = max_second; + _mp4 = makeRecorder(sender, getTracks(), type, _option); } else if (!start && _mp4) { //停止录制 _mp4 = nullptr; diff --git a/src/Common/MultiMediaSourceMuxer.h b/src/Common/MultiMediaSourceMuxer.h index b8904f09..5414ee9b 100644 --- a/src/Common/MultiMediaSourceMuxer.h +++ b/src/Common/MultiMediaSourceMuxer.h @@ -23,73 +23,6 @@ namespace mediakit { -class ProtocolOption { -public: - ProtocolOption(); - - //是否开启转换为hls - bool enable_hls = false; - //是否开启MP4录制 - bool enable_mp4 = false; - //是否将mp4录制当做观看者 - bool mp4_as_player = false; - //是否开启转换为rtsp/webrtc - bool enable_rtsp = true; - //是否开启转换为rtmp/flv - bool enable_rtmp = true; - //是否开启转换为http-ts/ws-ts - bool enable_ts = true; - //是否开启转换为http-fmp4/ws-fmp4 - bool enable_fmp4 = true; - - //转协议是否开启音频 - bool enable_audio = true; - //添加静音音频,在关闭音频时,此开关无效 - bool add_mute_audio = true; - - //mp4录制保存路径 - std::string mp4_save_path; - //mp4切片大小,单位秒 - size_t mp4_max_second = 0; - - //hls录制保存路径 - std::string hls_save_path; - - //断连续推延时,单位毫秒,默认采用配置文件 - uint32_t continue_push_ms; - - //时间戳修复这一路流标志位 - bool modify_stamp; - - template - ProtocolOption(const MAP &allArgs) : ProtocolOption() { - #define GET_OPT_VALUE(key) getArgsValue(allArgs, #key, key) - GET_OPT_VALUE(enable_hls); - GET_OPT_VALUE(enable_mp4); - GET_OPT_VALUE(mp4_as_player); - GET_OPT_VALUE(enable_rtsp); - GET_OPT_VALUE(enable_rtmp); - GET_OPT_VALUE(enable_ts); - GET_OPT_VALUE(enable_fmp4); - GET_OPT_VALUE(enable_audio); - GET_OPT_VALUE(add_mute_audio); - GET_OPT_VALUE(mp4_save_path); - GET_OPT_VALUE(mp4_max_second); - GET_OPT_VALUE(hls_save_path); - GET_OPT_VALUE(continue_push_ms); - GET_OPT_VALUE(modify_stamp); - } - -private: - template - static void getArgsValue(const MAP &allArgs, const KEY &key, TYPE &value) { - auto val = ((MAP &)allArgs)[key]; - if (!val.empty()) { - value = (TYPE)val; - } - } -}; - class MultiMediaSourceMuxer : public MediaSourceEventInterceptor, public MediaSink, public std::enable_shared_from_this{ public: typedef std::shared_ptr Ptr; diff --git a/src/Common/config.cpp b/src/Common/config.cpp index cf1b6fe8..cb24064b 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -68,53 +68,84 @@ const string kFlowThreshold = GENERAL_FIELD "flowThreshold"; const string kStreamNoneReaderDelayMS = GENERAL_FIELD "streamNoneReaderDelayMS"; const string kMaxStreamWaitTimeMS = GENERAL_FIELD "maxStreamWaitMS"; const string kEnableVhost = GENERAL_FIELD "enableVhost"; -const string kAddMuteAudio = GENERAL_FIELD "addMuteAudio"; const string kResetWhenRePlay = GENERAL_FIELD "resetWhenRePlay"; -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"; -const string kEnableAudio = GENERAL_FIELD "enable_audio"; const string kCheckNvidiaDev = GENERAL_FIELD "check_nvidia_dev"; const string kEnableFFmpegLog = GENERAL_FIELD "enable_ffmpeg_log"; const string kWaitTrackReadyMS = GENERAL_FIELD "wait_track_ready_ms"; const string kWaitAddTrackMS = GENERAL_FIELD "wait_add_track_ms"; const string kUnreadyFrameCache = GENERAL_FIELD "unready_frame_cache"; -const string kContinuePushMS = GENERAL_FIELD "continue_push_ms"; static onceToken token([]() { mINI::Instance()[kFlowThreshold] = 1024; mINI::Instance()[kStreamNoneReaderDelayMS] = 20 * 1000; mINI::Instance()[kMaxStreamWaitTimeMS] = 15 * 1000; mINI::Instance()[kEnableVhost] = 0; - mINI::Instance()[kAddMuteAudio] = 1; mINI::Instance()[kResetWhenRePlay] = 1; - mINI::Instance()[kPublishToHls] = 1; - mINI::Instance()[kPublishToMP4] = 0; 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; - mINI::Instance()[kEnableAudio] = 1; mINI::Instance()[kCheckNvidiaDev] = 1; mINI::Instance()[kEnableFFmpegLog] = 0; mINI::Instance()[kWaitTrackReadyMS] = 10000; mINI::Instance()[kWaitAddTrackMS] = 3000; mINI::Instance()[kUnreadyFrameCache] = 100; - mINI::Instance()[kContinuePushMS] = 15 * 1000; }); } // namespace General +namespace Protocol { +#define PROTOCOL_FIELD "protocol." +const string kModifyStamp = PROTOCOL_FIELD "modify_stamp"; +const string kEnableAudio = PROTOCOL_FIELD "enable_audio"; +const string kAddMuteAudio = PROTOCOL_FIELD "add_mute_audio"; +const string kContinuePushMS = PROTOCOL_FIELD "continue_push_ms"; + +const string kEnableHls = PROTOCOL_FIELD "enable_hls"; +const string kEnableMP4 = PROTOCOL_FIELD "enable_mp4"; +const string kEnableRtsp = PROTOCOL_FIELD "enable_rtsp"; +const string kEnableRtmp = PROTOCOL_FIELD "enable_rtmp"; +const string kEnableTS = PROTOCOL_FIELD "enable_ts"; +const string kEnableFMP4 = PROTOCOL_FIELD "enable_fmp4"; + +const string kMP4AsPlayer = PROTOCOL_FIELD "mp4_as_player"; +const string kMP4MaxSecond = PROTOCOL_FIELD "mp4_max_second"; +const string kMP4SavePath = PROTOCOL_FIELD "mp4_save_path"; + +const string kHlsSavePath = PROTOCOL_FIELD "hls_save_path"; + +const string kHlsDemand = PROTOCOL_FIELD "hls_demand"; +const string kRtspDemand = PROTOCOL_FIELD "rtsp_demand"; +const string kRtmpDemand = PROTOCOL_FIELD "rtmp_demand"; +const string kTSDemand = PROTOCOL_FIELD "ts_demand"; +const string kFMP4Demand = PROTOCOL_FIELD "fmp4_demand"; + +static onceToken token([]() { + mINI::Instance()[kModifyStamp] = 0; + mINI::Instance()[kEnableAudio] = 1; + mINI::Instance()[kAddMuteAudio] = 1; + mINI::Instance()[kContinuePushMS] = 15000; + + mINI::Instance()[kEnableHls] = 1; + mINI::Instance()[kEnableMP4] = 0; + mINI::Instance()[kEnableRtsp] = 1; + mINI::Instance()[kEnableRtmp] = 1; + mINI::Instance()[kEnableTS] = 1; + mINI::Instance()[kEnableFMP4] = 1; + + mINI::Instance()[kMP4AsPlayer] = 0; + mINI::Instance()[kMP4MaxSecond] = 3600; + mINI::Instance()[kMP4SavePath] = "./www"; + + mINI::Instance()[kHlsSavePath] = "./www"; + + mINI::Instance()[kHlsDemand] = 0; + mINI::Instance()[kRtspDemand] = 0; + mINI::Instance()[kRtmpDemand] = 0; + mINI::Instance()[kTSDemand] = 0; + mINI::Instance()[kFMP4Demand] = 0; +}); +} // !Protocol + ////////////HTTP配置/////////// namespace Http { #define HTTP_FIELD "http." @@ -242,22 +273,16 @@ namespace Record { #define RECORD_FIELD "record." const string kAppName = RECORD_FIELD "appName"; const string kSampleMS = RECORD_FIELD "sampleMS"; -const string kFileSecond = RECORD_FIELD "fileSecond"; -const string kFilePath = RECORD_FIELD "filePath"; const string kFileBufSize = RECORD_FIELD "fileBufSize"; const string kFastStart = RECORD_FIELD "fastStart"; const string kFileRepeat = RECORD_FIELD "fileRepeat"; -const string kMP4AsPlayer = RECORD_FIELD "mp4_as_player"; static onceToken token([]() { mINI::Instance()[kAppName] = "record"; mINI::Instance()[kSampleMS] = 500; - mINI::Instance()[kFileSecond] = 60 * 60; - mINI::Instance()[kFilePath] = "./www"; mINI::Instance()[kFileBufSize] = 64 * 1024; mINI::Instance()[kFastStart] = false; mINI::Instance()[kFileRepeat] = false; - mINI::Instance()[kMP4AsPlayer] = false; }); } // namespace Record @@ -269,7 +294,6 @@ const string kSegmentNum = HLS_FIELD "segNum"; const string kSegmentKeep = HLS_FIELD "segKeep"; const string kSegmentRetain = HLS_FIELD "segRetain"; const string kFileBufSize = HLS_FIELD "fileBufSize"; -const string kFilePath = HLS_FIELD "filePath"; const string kBroadcastRecordTs = HLS_FIELD "broadcastRecordTs"; const string kDeleteDelaySec = HLS_FIELD "deleteDelaySec"; @@ -279,7 +303,6 @@ static onceToken token([]() { mINI::Instance()[kSegmentKeep] = false; mINI::Instance()[kSegmentRetain] = 5; mINI::Instance()[kFileBufSize] = 64 * 1024; - mINI::Instance()[kFilePath] = "./www"; mINI::Instance()[kBroadcastRecordTs] = false; mINI::Instance()[kDeleteDelaySec] = 10; }); diff --git a/src/Common/config.h b/src/Common/config.h index c25774b6..36177ec4 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -45,14 +45,11 @@ extern const std::string kBroadcastRecordTs; // 收到http api请求广播 extern const std::string kBroadcastHttpRequest; -#define BroadcastHttpRequestArgs \ - const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, bool &consumed, SockInfo &sender +#define BroadcastHttpRequestArgs const Parser &parser, const HttpSession::HttpResponseInvoker &invoker, bool &consumed, SockInfo &sender // 在http文件服务器中,收到http访问文件或目录的广播,通过该事件控制访问http目录的权限 extern const std::string kBroadcastHttpAccess; -#define BroadcastHttpAccessArgs \ - const Parser &parser, const std::string &path, const bool &is_dir, \ - const HttpSession::HttpAccessPathInvoker &invoker, SockInfo &sender +#define BroadcastHttpAccessArgs const Parser &parser, const std::string &path, const bool &is_dir, const HttpSession::HttpAccessPathInvoker &invoker, SockInfo &sender // 在http文件服务器中,收到http访问文件或目录前的广播,通过该事件可以控制http url到文件路径的映射 // 在该事件中通过自行覆盖path参数,可以做到譬如根据虚拟主机或者app选择不同http根目录的目的 @@ -66,9 +63,7 @@ extern const std::string kBroadcastOnGetRtspRealm; // 请求认证用户密码事件,user_name为用户名,must_no_encrypt如果为true,则必须提供明文密码(因为此时是base64认证方式),否则会导致认证失败 // 获取到密码后请调用invoker并输入对应类型的密码和密码类型,invoker执行时会匹配密码 extern const std::string kBroadcastOnRtspAuth; -#define BroadcastOnRtspAuthArgs \ - const MediaInfo &args, const std::string &realm, const std::string &user_name, const bool &must_no_encrypt, \ - const RtspSession::onAuth &invoker, SockInfo &sender +#define BroadcastOnRtspAuthArgs const MediaInfo &args, const std::string &realm, const std::string &user_name, const bool &must_no_encrypt, const RtspSession::onAuth &invoker, SockInfo &sender // 推流鉴权结果回调对象 // 如果err为空则代表鉴权成功 @@ -76,8 +71,7 @@ using PublishAuthInvoker = std::function(vhost, app, stream_id); } @@ -41,30 +43,27 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { - GET_CONFIG(bool, fmp4_demand, General::kFMP4Demand); - _enabled = fmp4_demand ? size : true; - if (!size && fmp4_demand) { + _enabled = _option.fmp4_demand ? size : true; + if (!size && _option.fmp4_demand) { _clear_cache = true; } MediaSourceEventInterceptor::onReaderChanged(sender, size); } bool inputFrame(const Frame::Ptr &frame) override { - GET_CONFIG(bool, fmp4_demand, General::kFMP4Demand); - if (_clear_cache && fmp4_demand) { + if (_clear_cache && _option.fmp4_demand) { _clear_cache = false; _media_src->clearCache(); } - if (_enabled || !fmp4_demand) { + if (_enabled || !_option.fmp4_demand) { return MP4MuxerMemory::inputFrame(frame); } return false; } bool isEnabled() { - GET_CONFIG(bool, fmp4_demand, General::kFMP4Demand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return fmp4_demand ? (_clear_cache ? true : _enabled) : true; + return _option.fmp4_demand ? (_clear_cache ? true : _enabled) : true; } void onAllTrackReady() { @@ -84,6 +83,7 @@ protected: private: bool _enabled = true; bool _clear_cache = false; + ProtocolOption _option; FMP4MediaSource::Ptr _media_src; }; diff --git a/src/Record/HlsRecorder.h b/src/Record/HlsRecorder.h index 8d40d9dc..14e97e30 100644 --- a/src/Record/HlsRecorder.h +++ b/src/Record/HlsRecorder.h @@ -20,11 +20,13 @@ class HlsRecorder final : public MediaSourceEventInterceptor, public MpegMuxer, public: using Ptr = std::shared_ptr; - HlsRecorder(const std::string &m3u8_file, const std::string ¶ms) : MpegMuxer(false) { + HlsRecorder(const std::string &m3u8_file, const std::string ¶ms, const ProtocolOption &option) : MpegMuxer(false) { GET_CONFIG(uint32_t, hlsNum, Hls::kSegmentNum); GET_CONFIG(bool, hlsKeep, Hls::kSegmentKeep); GET_CONFIG(uint32_t, hlsBufSize, Hls::kFileBufSize); GET_CONFIG(float, hlsDuration, Hls::kSegmentDuration); + + _option = option; _hls = std::make_shared(m3u8_file, params, hlsBufSize, hlsDuration, hlsNum, hlsKeep); //清空上次的残余文件 _hls->clearCache(); @@ -44,10 +46,9 @@ public: int readerCount() { return _hls->getMediaSource()->readerCount(); } void onReaderChanged(MediaSource &sender, int size) override { - GET_CONFIG(bool, hls_demand, General::kHlsDemand); // hls保留切片个数为0时代表为hls录制(不删除切片),那么不管有无观看者都一直生成hls - _enabled = hls_demand ? (_hls->isLive() ? size : true) : true; - if (!size && _hls->isLive() && hls_demand) { + _enabled = _option.hls_demand ? (_hls->isLive() ? size : true) : true; + if (!size && _hls->isLive() && _option.hls_demand) { // hls直播时,如果无人观看就删除视频缓存,目的是为了防止视频跳跃 _clear_cache = true; } @@ -55,23 +56,21 @@ public: } bool inputFrame(const Frame::Ptr &frame) override { - GET_CONFIG(bool, hls_demand, General::kHlsDemand); - if (_clear_cache && hls_demand) { + if (_clear_cache && _option.hls_demand) { _clear_cache = false; //清空旧的m3u8索引文件于ts切片 _hls->clearCache(); _hls->getMediaSource()->setIndexFile(""); } - if (_enabled || !hls_demand) { + if (_enabled || !_option.hls_demand) { return MpegMuxer::inputFrame(frame); } return false; } bool isEnabled() { - GET_CONFIG(bool, hls_demand, General::kHlsDemand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return hls_demand ? (_clear_cache ? true : _enabled) : true; + return _option.hls_demand ? (_clear_cache ? true : _enabled) : true; } private: @@ -86,6 +85,7 @@ private: private: bool _enabled = true; bool _clear_cache = false; + ProtocolOption _option; std::shared_ptr _hls; }; }//namespace mediakit diff --git a/src/Record/MP4Reader.cpp b/src/Record/MP4Reader.cpp index 687072e0..fbc6d8d0 100644 --- a/src/Record/MP4Reader.cpp +++ b/src/Record/MP4Reader.cpp @@ -24,7 +24,7 @@ MP4Reader::MP4Reader(const string &vhost, const string &app, const string &strea _poller = WorkThreadPool::Instance().getPoller(); _file_path = file_path; if (_file_path.empty()) { - GET_CONFIG(string, recordPath, Record::kFilePath); + GET_CONFIG(string, recordPath, Protocol::kMP4SavePath); GET_CONFIG(bool, enableVhost, General::kEnableVhost); if (enableVhost) { _file_path = vhost + "/" + app + "/" + stream_id; diff --git a/src/Record/MP4Recorder.cpp b/src/Record/MP4Recorder.cpp index 201e17ed..88d2d30c 100644 --- a/src/Record/MP4Recorder.cpp +++ b/src/Record/MP4Recorder.cpp @@ -28,8 +28,8 @@ MP4Recorder::MP4Recorder(const string &path, const string &vhost, const string & _info.stream = stream_id; _info.vhost = vhost; _info.folder = path; - GET_CONFIG(size_t ,recordSec,Record::kFileSecond); - _max_second = max_second ? max_second : recordSec; + GET_CONFIG(uint32_t, s_max_second, Protocol::kMP4MaxSecond); + _max_second = max_second ? max_second : s_max_second; } MP4Recorder::~MP4Recorder() { diff --git a/src/Record/Recorder.cpp b/src/Record/Recorder.cpp index 13bd256f..546780d8 100644 --- a/src/Record/Recorder.cpp +++ b/src/Record/Recorder.cpp @@ -23,7 +23,7 @@ string Recorder::getRecordPath(Recorder::type type, const string &vhost, const s GET_CONFIG(bool, enableVhost, General::kEnableVhost); switch (type) { case Recorder::type_hls: { - GET_CONFIG(string, hlsPath, Hls::kFilePath); + GET_CONFIG(string, hlsPath, Protocol::kHlsSavePath); string m3u8FilePath; if (enableVhost) { m3u8FilePath = vhost + "/" + app + "/" + stream_id + "/hls.m3u8"; @@ -37,7 +37,7 @@ string Recorder::getRecordPath(Recorder::type type, const string &vhost, const s return File::absolutePath(m3u8FilePath, hlsPath); } case Recorder::type_mp4: { - GET_CONFIG(string, recordPath, Record::kFilePath); + GET_CONFIG(string, recordPath, Protocol::kMP4SavePath); GET_CONFIG(string, recordAppName, Record::kAppName); string mp4FilePath; if (enableVhost) { @@ -56,13 +56,13 @@ string Recorder::getRecordPath(Recorder::type type, const string &vhost, const s } } -std::shared_ptr Recorder::createRecorder(type type, const string &vhost, const string &app, const string &stream_id, const string &customized_path, size_t max_second){ - auto path = Recorder::getRecordPath(type, vhost, app, stream_id, customized_path); +std::shared_ptr Recorder::createRecorder(type type, const string &vhost, const string &app, const string &stream_id, const ProtocolOption &option){ switch (type) { case Recorder::type_hls: { #if defined(ENABLE_HLS) + auto path = Recorder::getRecordPath(type, vhost, app, stream_id, option.hls_save_path); GET_CONFIG(bool, enable_vhost, General::kEnableVhost); - auto ret = std::make_shared(path, enable_vhost ? string(VHOST_KEY) + "=" + vhost : ""); + auto ret = std::make_shared(path, enable_vhost ? string(VHOST_KEY) + "=" + vhost : "", option); ret->setMediaSource(vhost, app, stream_id); return ret; #else @@ -73,7 +73,8 @@ std::shared_ptr Recorder::createRecorder(type type, const st case Recorder::type_mp4: { #if defined(ENABLE_MP4) - return std::make_shared(path, vhost, app, stream_id, max_second); + auto path = Recorder::getRecordPath(type, vhost, app, stream_id, option.mp4_save_path); + return std::make_shared(path, vhost, app, stream_id, option.mp4_max_second); #else throw std::invalid_argument("mp4相关功能未打开,请开启ENABLE_MP4宏后编译再测试"); #endif diff --git a/src/Record/Recorder.h b/src/Record/Recorder.h index d3529dea..491088ff 100644 --- a/src/Record/Recorder.h +++ b/src/Record/Recorder.h @@ -10,11 +10,13 @@ #ifndef SRC_MEDIAFILE_RECORDER_H_ #define SRC_MEDIAFILE_RECORDER_H_ + #include #include namespace mediakit { class MediaSinkInterface; +class ProtocolOption; class RecordInfo { public: @@ -60,7 +62,7 @@ public: * @param max_second mp4录制最大切片时间,单位秒,置0则采用配置文件配置 * @return 对象指针,可能为nullptr */ - static std::shared_ptr createRecorder(type type, const std::string &vhost, const std::string &app, const std::string &stream_id, const std::string &customized_path = "", size_t max_second = 0); + static std::shared_ptr createRecorder(type type, const std::string &vhost, const std::string &app, const std::string &stream_id, const ProtocolOption &option); private: Recorder() = delete; diff --git a/src/Rtmp/RtmpMediaSourceMuxer.h b/src/Rtmp/RtmpMediaSourceMuxer.h index f89543c6..29a1e8d0 100644 --- a/src/Rtmp/RtmpMediaSourceMuxer.h +++ b/src/Rtmp/RtmpMediaSourceMuxer.h @@ -24,7 +24,9 @@ public: RtmpMediaSourceMuxer(const std::string &vhost, const std::string &strApp, const std::string &strId, - const TitleMeta::Ptr &title = nullptr) : RtmpMuxer(title){ + const ProtocolOption &option, + const TitleMeta::Ptr &title = nullptr) : RtmpMuxer(title) { + _option = option; _media_src = std::make_shared(vhost, strApp, strId); getRtmpRing()->setDelegate(_media_src); } @@ -50,35 +52,33 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { - GET_CONFIG(bool, rtmp_demand, General::kRtmpDemand); - _enabled = rtmp_demand ? size : true; - if (!size && rtmp_demand) { + _enabled = _option.rtmp_demand ? size : true; + if (!size && _option.rtmp_demand) { _clear_cache = true; } MediaSourceEventInterceptor::onReaderChanged(sender, size); } bool inputFrame(const Frame::Ptr &frame) override { - GET_CONFIG(bool, rtmp_demand, General::kRtmpDemand); - if (_clear_cache && rtmp_demand) { + if (_clear_cache && _option.rtmp_demand) { _clear_cache = false; _media_src->clearCache(); } - if (_enabled || !rtmp_demand) { + if (_enabled || !_option.rtmp_demand) { return RtmpMuxer::inputFrame(frame); } return false; } bool isEnabled() { - GET_CONFIG(bool, rtmp_demand, General::kRtmpDemand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return rtmp_demand ? (_clear_cache ? true : _enabled) : true; + return _option.rtmp_demand ? (_clear_cache ? true : _enabled) : true; } private: bool _enabled = true; bool _clear_cache = false; + ProtocolOption _option; RtmpMediaSource::Ptr _media_src; }; diff --git a/src/Rtmp/RtmpSession.cpp b/src/Rtmp/RtmpSession.cpp index fba56f3d..b2d9bbcf 100644 --- a/src/Rtmp/RtmpSession.cpp +++ b/src/Rtmp/RtmpSession.cpp @@ -530,12 +530,6 @@ void RtmpSession::onRtmpChunk(RtmpPacket::Ptr packet) { WarnL << "Not a rtmp push!"; return; } - GET_CONFIG(bool, rtmp_modify_stamp, Rtmp::kModifyStamp); - if (rtmp_modify_stamp) { - int64_t dts_out; - _stamp[chunk_data.type_id % 2].revise(chunk_data.time_stamp, chunk_data.time_stamp, dts_out, dts_out, true); - chunk_data.time_stamp = (uint32_t)dts_out; - } if (!_set_meta_data) { _set_meta_data = true; diff --git a/src/Rtmp/RtmpSession.h b/src/Rtmp/RtmpSession.h index 16ea4d84..cc8344e5 100644 --- a/src/Rtmp/RtmpSession.h +++ b/src/Rtmp/RtmpSession.h @@ -96,8 +96,6 @@ private: //消耗的总流量 uint64_t _total_bytes = 0; std::string _tc_url; - //推流时间戳修整器 - Stamp _stamp[2]; //数据接收超时计时器 toolkit::Ticker _ticker; MediaInfo _media_info; diff --git a/src/Rtsp/RtspMediaSourceMuxer.h b/src/Rtsp/RtspMediaSourceMuxer.h index be2188d4..65e6f91a 100644 --- a/src/Rtsp/RtspMediaSourceMuxer.h +++ b/src/Rtsp/RtspMediaSourceMuxer.h @@ -24,7 +24,9 @@ public: RtspMediaSourceMuxer(const std::string &vhost, const std::string &strApp, const std::string &strId, - const TitleSdp::Ptr &title = nullptr) : RtspMuxer(title){ + const ProtocolOption &option, + const TitleSdp::Ptr &title = nullptr) : RtspMuxer(title) { + _option = option; _media_src = std::make_shared(vhost,strApp,strId); getRtpRing()->setDelegate(_media_src); } @@ -49,35 +51,33 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { - GET_CONFIG(bool, rtsp_demand, General::kRtspDemand); - _enabled = rtsp_demand ? size : true; - if (!size && rtsp_demand) { + _enabled = _option.rtsp_demand ? size : true; + if (!size && _option.rtsp_demand) { _clear_cache = true; } MediaSourceEventInterceptor::onReaderChanged(sender, size); } bool inputFrame(const Frame::Ptr &frame) override { - GET_CONFIG(bool, rtsp_demand, General::kRtspDemand); - if (_clear_cache && rtsp_demand) { + if (_clear_cache && _option.rtsp_demand) { _clear_cache = false; _media_src->clearCache(); } - if (_enabled || !rtsp_demand) { + if (_enabled || !_option.rtsp_demand) { return RtspMuxer::inputFrame(frame); } return false; } bool isEnabled() { - GET_CONFIG(bool, rtsp_demand, General::kRtspDemand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return rtsp_demand ? (_clear_cache ? true : _enabled) : true; + return _option.rtsp_demand ? (_clear_cache ? true : _enabled) : true; } private: bool _enabled = true; bool _clear_cache = false; + ProtocolOption _option; RtspMediaSource::Ptr _media_src; }; diff --git a/src/TS/TSMediaSourceMuxer.h b/src/TS/TSMediaSourceMuxer.h index d1cff544..392b3236 100644 --- a/src/TS/TSMediaSourceMuxer.h +++ b/src/TS/TSMediaSourceMuxer.h @@ -23,7 +23,9 @@ public: TSMediaSourceMuxer(const std::string &vhost, const std::string &app, - const std::string &stream_id) : MpegMuxer(false) { + const std::string &stream_id, + const ProtocolOption &option) : MpegMuxer(false) { + _option = option; _media_src = std::make_shared(vhost, app, stream_id); } @@ -39,30 +41,27 @@ public: } void onReaderChanged(MediaSource &sender, int size) override { - GET_CONFIG(bool, ts_demand, General::kTSDemand); - _enabled = ts_demand ? size : true; - if (!size && ts_demand) { + _enabled = _option.ts_demand ? size : true; + if (!size && _option.ts_demand) { _clear_cache = true; } MediaSourceEventInterceptor::onReaderChanged(sender, size); } bool inputFrame(const Frame::Ptr &frame) override { - GET_CONFIG(bool, ts_demand, General::kTSDemand); - if (_clear_cache && ts_demand) { + if (_clear_cache && _option.ts_demand) { _clear_cache = false; _media_src->clearCache(); } - if (_enabled || !ts_demand) { + if (_enabled || !_option.ts_demand) { return MpegMuxer::inputFrame(frame); } return false; } bool isEnabled() { - GET_CONFIG(bool, ts_demand, General::kTSDemand); //缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存 - return ts_demand ? (_clear_cache ? true : _enabled) : true; + return _option.ts_demand ? (_clear_cache ? true : _enabled) : true; } protected: @@ -78,6 +77,7 @@ protected: private: bool _enabled = true; bool _clear_cache = false; + ProtocolOption _option; TSMediaSource::Ptr _media_src; }; diff --git a/tests/test_bench_proxy.cpp b/tests/test_bench_proxy.cpp index 793b4107..c0f1fceb 100644 --- a/tests/test_bench_proxy.cpp +++ b/tests/test_bench_proxy.cpp @@ -125,11 +125,11 @@ int main(int argc, char *argv[]) { //设置合并写 mINI::Instance()[General::kMergeWriteMS] = merge_ms; - mINI::Instance()[General::kRtspDemand] = demand; - mINI::Instance()[General::kRtmpDemand] = demand; - mINI::Instance()[General::kHlsDemand] = demand; - mINI::Instance()[General::kTSDemand] = demand; - mINI::Instance()[General::kFMP4Demand] = demand; + mINI::Instance()[Protocol::kRtspDemand] = demand; + mINI::Instance()[Protocol::kRtmpDemand] = demand; + mINI::Instance()[Protocol::kHlsDemand] = demand; + mINI::Instance()[Protocol::kTSDemand] = demand; + mINI::Instance()[Protocol::kFMP4Demand] = demand; map proxyMap; ProtocolOption option; diff --git a/tests/test_pusherMp4.cpp b/tests/test_pusherMp4.cpp index c72f52b1..a29d74f3 100644 --- a/tests/test_pusherMp4.cpp +++ b/tests/test_pusherMp4.cpp @@ -105,11 +105,11 @@ int domain(const string &filePath, const string &pushUrl) { Logger::Instance().setWriter(std::make_shared()); //循环点播mp4文件 mINI::Instance()[Record::kFileRepeat] = 1; - mINI::Instance()[General::kHlsDemand] = 1; - mINI::Instance()[General::kTSDemand] = 1; - mINI::Instance()[General::kFMP4Demand] = 1; - //mINI::Instance()[General::kRtspDemand] = 1; - //mINI::Instance()[General::kRtmpDemand] = 1; + mINI::Instance()[Protocol::kHlsDemand] = 1; + mINI::Instance()[Protocol::kTSDemand] = 1; + mINI::Instance()[Protocol::kFMP4Demand] = 1; + //mINI::Instance()[Protocol::kRtspDemand] = 1; + //mINI::Instance()[Protocol::kRtmpDemand] = 1; auto poller = EventPollerPool::Instance().getPoller(); //vhost/app/stream可以随便自己填,现在不限制app应用名了