/* * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved. * * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit). * * Use of this source code is governed by MIT license that can be found in the * LICENSE file in the root of the source tree. All contributing project authors * may be found in the AUTHORS file in the root of the source tree. */ #ifndef COMMON_CONFIG_H #define COMMON_CONFIG_H #include "Util/NoticeCenter.h" #include "Util/mini.h" #include "Util/onceToken.h" #include "macros.h" #include namespace mediakit { class ProtocolOption; // 加载配置文件,如果配置文件不存在,那么会导出默认配置并生成配置文件 // 加载配置文件成功后会触发kBroadcastUpdateConfig广播 // 如果指定的文件名(ini_path)为空,那么会加载默认配置文件 // 默认配置文件名为 /path/to/your/exe.ini // 加载配置文件成功后返回true,否则返回false bool loadIniConfig(const char *ini_path = nullptr); ////////////广播名称/////////// namespace Broadcast { // 注册或反注册MediaSource事件广播 extern const std::string kBroadcastMediaChanged; #define BroadcastMediaChangedArgs const bool &bRegist, MediaSource &sender // 录制mp4文件成功后广播 extern const std::string kBroadcastRecordMP4; #define BroadcastRecordMP4Args const RecordInfo &info // 录制 ts 文件后广播 extern const std::string kBroadcastRecordTs; #define BroadcastRecordTsArgs const RecordInfo &info // 收到http api请求广播 extern const std::string kBroadcastHttpRequest; #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 // 在http文件服务器中,收到http访问文件或目录前的广播,通过该事件可以控制http url到文件路径的映射 // 在该事件中通过自行覆盖path参数,可以做到譬如根据虚拟主机或者app选择不同http根目录的目的 extern const std::string kBroadcastHttpBeforeAccess; #define BroadcastHttpBeforeAccessArgs const Parser &parser, std::string &path, SockInfo &sender // 该流是否需要认证?是的话调用invoker并传入realm,否则传入空的realm.如果该事件不监听则不认证 extern const std::string kBroadcastOnGetRtspRealm; #define BroadcastOnGetRtspRealmArgs const MediaInfo &args, const RtspSession::onGetRealm &invoker, SockInfo &sender // 请求认证用户密码事件,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 // 推流鉴权结果回调对象 // 如果err为空则代表鉴权成功 using PublishAuthInvoker = std::function; // 收到rtsp/rtmp推流事件广播,通过该事件控制推流鉴权 extern const std::string kBroadcastMediaPublish; #define BroadcastMediaPublishArgs const MediaOriginType &type, const MediaInfo &args, const Broadcast::PublishAuthInvoker &invoker, SockInfo &sender // 播放鉴权结果回调对象 // 如果err为空则代表鉴权成功 using AuthInvoker = std::function; // 播放rtsp/rtmp/http-flv事件广播,通过该事件控制播放鉴权 extern const std::string kBroadcastMediaPlayed; #define BroadcastMediaPlayedArgs const MediaInfo &args, const Broadcast::AuthInvoker &invoker, SockInfo &sender // shell登录鉴权 extern const std::string kBroadcastShellLogin; #define BroadcastShellLoginArgs const std::string &user_name, const std::string &passwd, const Broadcast::AuthInvoker &invoker, SockInfo &sender // 停止rtsp/rtmp/http-flv会话后流量汇报事件广播 extern const std::string kBroadcastFlowReport; #define BroadcastFlowReportArgs const MediaInfo &args, const uint64_t &totalBytes, const uint64_t &totalDuration, const bool &isPlayer, SockInfo &sender // 未找到流后会广播该事件,请在监听该事件后去拉流或其他方式产生流,这样就能按需拉流了 extern const std::string kBroadcastNotFoundStream; #define BroadcastNotFoundStreamArgs const MediaInfo &args, SockInfo &sender, const std::function &closePlayer // 某个流无人消费时触发,目的为了实现无人观看时主动断开拉流等业务逻辑 extern const std::string kBroadcastStreamNoneReader; #define BroadcastStreamNoneReaderArgs MediaSource &sender // rtp推流被动停止时触发 extern const std::string kBroadcastSendRtpStopped; #define BroadcastSendRtpStoppedArgs MultiMediaSourceMuxer &sender, const std::string &ssrc, const SockException &ex // 更新配置文件事件广播,执行loadIniConfig函数加载配置文件成功后会触发该广播 extern const std::string kBroadcastReloadConfig; #define BroadcastReloadConfigArgs void // rtp server 超时 extern const std::string KBroadcastRtpServerTimeout; #define BroadcastRtpServerTimeoutArgs uint16_t &local_port, const string &stream_id,int &tcp_mode, bool &re_use_port, uint32_t &ssrc #define ReloadConfigTag ((void *)(0xFF)) #define RELOAD_KEY(arg, key) \ do { \ decltype(arg) arg##_tmp = ::toolkit::mINI::Instance()[key]; \ if (arg == arg##_tmp) { \ return; \ } \ arg = arg##_tmp; \ InfoL << "reload config:" << key << "=" << arg; \ } while (0) // 监听某个配置发送变更 #define LISTEN_RELOAD_KEY(arg, key, ...) \ do { \ static ::toolkit::onceToken s_token_listen([]() { \ ::toolkit::NoticeCenter::Instance().addListener( \ ReloadConfigTag, Broadcast::kBroadcastReloadConfig, [](BroadcastReloadConfigArgs) { __VA_ARGS__; }); \ }); \ } while (0) #define GET_CONFIG(type, arg, key) \ static type arg = ::toolkit::mINI::Instance()[key]; \ LISTEN_RELOAD_KEY(arg, key, { RELOAD_KEY(arg, key); }); #define GET_CONFIG_FUNC(type, arg, key, ...) \ static type arg; \ do { \ static ::toolkit::onceToken s_token_set([]() { \ static auto lam = __VA_ARGS__; \ static auto arg##_str = ::toolkit::mINI::Instance()[key]; \ arg = lam(arg##_str); \ LISTEN_RELOAD_KEY(arg, key, { \ RELOAD_KEY(arg##_str, key); \ arg = lam(arg##_str); \ }); \ }); \ } while (0) } // namespace Broadcast ////////////通用配置/////////// namespace General { // 每个流媒体服务器的ID(GUID) extern const std::string kMediaServerId; // 流量汇报事件流量阈值,单位KB,默认1MB extern const std::string kFlowThreshold; // 流无人观看并且超过若干时间后才触发kBroadcastStreamNoneReader事件 // 默认连续5秒无人观看然后触发kBroadcastStreamNoneReader事件 extern const std::string kStreamNoneReaderDelayMS; // 等待流注册超时时间,收到播放器后请求后,如果未找到相关流,服务器会等待一定时间, // 如果在这个时间内,相关流注册上了,那么服务器会立即响应播放器播放成功, // 否则会最多等待kMaxStreamWaitTimeMS毫秒,然后响应播放器播放失败 extern const std::string kMaxStreamWaitTimeMS; // 是否启动虚拟主机 extern const std::string kEnableVhost; // 拉流代理时如果断流再重连成功是否删除前一次的媒体流数据,如果删除将重新开始, // 如果不删除将会接着上一次的数据继续写(录制hls/mp4时会继续在前一个文件后面写) extern const std::string kResetWhenRePlay; // 合并写缓存大小(单位毫秒),合并写指服务器缓存一定的数据后才会一次性写入socket,这样能提高性能,但是会提高延时 // 开启后会同时关闭TCP_NODELAY并开启MSG_MORE extern const std::string kMergeWriteMS; // 在docker环境下,不能通过英伟达驱动是否存在来判断是否支持硬件转码 extern const std::string kCheckNvidiaDev; // 是否开启ffmpeg日志 extern const std::string kEnableFFmpegLog; // 最多等待未初始化的Track 10秒,超时之后会忽略未初始化的Track extern const std::string kWaitTrackReadyMS; // 如果直播流只有单Track,最多等待3秒,超时后未收到其他Track的数据,则认为是单Track // 如果协议元数据有声明特定track数,那么无此等待时间 extern const std::string kWaitAddTrackMS; // 如果track未就绪,我们先缓存帧数据,但是有最大个数限制(100帧时大约4秒),防止内存溢出 extern const std::string kUnreadyFrameCache; } // namespace General namespace Protocol { //时间戳修复这一路流标志位 extern const std::string kModifyStamp; //转协议是否开启音频 extern const std::string kEnableAudio; //添加静音音频,在关闭音频时,此开关无效 extern const std::string kAddMuteAudio; // 无人观看时,是否直接关闭(而不是通过on_none_reader hook返回close) // 此配置置1时,此流如果无人观看,将不触发on_none_reader hook回调, // 而是将直接关闭流 extern const std::string kAutoClose; //断连续推延时,单位毫秒,默认采用配置文件 extern const std::string kContinuePushMS; //是否开启转换为hls(mpegts) extern const std::string kEnableHls; //是否开启转换为hls(fmp4) extern const std::string kEnableHlsFmp4; //是否开启MP4录制 extern const std::string kEnableMP4; //是否开启转换为rtsp/webrtc extern const std::string kEnableRtsp; //是否开启转换为rtmp/flv extern const std::string kEnableRtmp; //是否开启转换为http-ts/ws-ts extern const std::string kEnableTS; //是否开启转换为http-fmp4/ws-fmp4 extern const std::string kEnableFMP4; //是否将mp4录制当做观看者 extern const std::string kMP4AsPlayer; //mp4切片大小,单位秒 extern const std::string kMP4MaxSecond; //mp4录制保存路径 extern const std::string kMP4SavePath; //hls录制保存路径 extern const std::string kHlsSavePath; // 按需转协议的开关 extern const std::string kHlsDemand; extern const std::string kRtspDemand; extern const std::string kRtmpDemand; extern const std::string kTSDemand; extern const std::string kFMP4Demand; } // !Protocol ////////////HTTP配置/////////// namespace Http { // http 文件发送缓存大小 extern const std::string kSendBufSize; // http 最大请求字节数 extern const std::string kMaxReqSize; // http keep-alive秒数 extern const std::string kKeepAliveSecond; // http 字符编码 extern const std::string kCharSet; // http 服务器根目录 extern const std::string kRootPath; // http 服务器虚拟目录 虚拟目录名和文件路径使用","隔开,多个配置路径间用";"隔开,例如 path_d,d:/record;path_e,e:/record extern const std::string kVirtualPath; // http 404错误提示内容 extern const std::string kNotFound; // 是否显示文件夹菜单 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; // 允许访问http api和http文件索引的ip地址范围白名单,置空情况下不做限制 extern const std::string kAllowIPRange; } // namespace Http ////////////SHELL配置/////////// namespace Shell { extern const std::string kMaxReqSize; } // namespace Shell ////////////RTSP服务器配置/////////// namespace Rtsp { // 是否优先base64方式认证?默认Md5方式认证 extern const std::string kAuthBasic; // 握手超时时间,默认15秒 extern const std::string kHandshakeSecond; // 维持链接超时时间,默认15秒 extern const std::string kKeepAliveSecond; // rtsp拉流代理是否直接代理 // 直接代理后支持任意编码格式,但是会导致GOP缓存无法定位到I帧,可能会导致开播花屏 // 并且如果是tcp方式拉流,如果rtp大于mtu会导致无法使用udp方式代理 // 假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理 // 默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的 extern const std::string kDirectProxy; // rtsp 转发是否使用低延迟模式,当开启时,不会缓存rtp包,来提高并发,可以降低一帧的延迟 extern const std::string kLowLatency; //强制协商rtp传输方式 (0:TCP,1:UDP,2:MULTICAST,-1:不限制) //当客户端发起RTSP SETUP的时候如果传输类型和此配置不一致则返回461 Unsupport Transport //迫使客户端重新SETUP并切换到对应协议。目前支持FFMPEG和VLC extern const std::string kRtpTransportType; } // namespace Rtsp ////////////RTMP服务器配置/////////// namespace Rtmp { // 握手超时时间,默认15秒 extern const std::string kHandshakeSecond; // 维持链接超时时间,默认15秒 extern const std::string kKeepAliveSecond; } // namespace Rtmp ////////////RTP配置/////////// namespace Rtp { // RTP打包最大MTU,公网情况下更小 extern const std::string kVideoMtuSize; // RTP打包最大MTU,公网情况下更小 extern const std::string kAudioMtuSize; // rtp包最大长度限制, 单位KB extern const std::string kRtpMaxSize; // rtp 打包时,低延迟开关,默认关闭(为0),h264存在一帧多个slice(NAL)的情况,在这种情况下,如果开启可能会导致画面花屏 extern const std::string kLowLatency; //H264 rtp打包模式是否采用stap-a模式(为了在老版本浏览器上兼容webrtc)还是采用Single NAL unit packet per H.264 模式 extern const std::string kH264StapA; } // namespace Rtp ////////////组播配置/////////// namespace MultiCast { // 组播分配起始地址 extern const std::string kAddrMin; // 组播分配截止地址 extern const std::string kAddrMax; // 组播TTL extern const std::string kUdpTTL; } // namespace MultiCast ////////////录像配置/////////// namespace Record { // 查看录像的应用名称 extern const std::string kAppName; // 每次流化MP4文件的时长,单位毫秒 extern const std::string kSampleMS; // mp4文件写缓存大小 extern const std::string kFileBufSize; // mp4录制完成后是否进行二次关键帧索引写入头部 extern const std::string kFastStart; // mp4文件是否重头循环读取 extern const std::string kFileRepeat; } // namespace Record ////////////HLS相关配置/////////// namespace Hls { // HLS切片时长,单位秒 extern const std::string kSegmentDuration; // m3u8文件中HLS切片个数,如果设置为0,则不删除切片,而是保存为点播 extern const std::string kSegmentNum; // 如果设置为0,则不保留切片,设置为1则一直保留切片 extern const std::string kSegmentKeep; // HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数 extern const std::string kSegmentRetain; // HLS文件写缓存大小 extern const std::string kFileBufSize; // 是否广播 ts 切片完成通知 extern const std::string kBroadcastRecordTs; // hls直播文件删除延时,单位秒 extern const std::string kDeleteDelaySec; } // namespace Hls ////////////Rtp代理相关配置/////////// namespace RtpProxy { // rtp调试数据保存目录,置空则不生成 extern const std::string kDumpDir; // rtp接收超时时间 extern const std::string kTimeoutSec; // 随机端口范围,最少确保36个端口 // 该范围同时限制rtsp服务器udp端口范围 extern const std::string kPortRange; // rtp server h264的pt extern const std::string kH264PT; // rtp server h265的pt extern const std::string kH265PT; // rtp server ps 的pt extern const std::string kPSPT; // rtp server opus 的pt extern const std::string kOpusPT; // RtpSender相关功能是否提前开启gop缓存优化级联秒开体验,默认开启 extern const std::string kGopCache; } // namespace RtpProxy /** * rtsp/rtmp播放器、推流器相关设置名, * 这些设置项都不是配置文件用 * 只用于设置某个播放器或推流器实例用 */ namespace Client { // 指定网卡ip extern const std::string kNetAdapter; // 设置rtp传输类型,可选项有0(tcp,默认)、1(udp)、2(组播) // 设置方法:player[PlayerBase::kRtpType] = 0/1/2; extern const std::string kRtpType; // rtsp认证用户名 extern const std::string kRtspUser; // rtsp认证用用户密码,可以是明文也可以是md5,md5密码生成方式 md5(username:realm:password) extern const std::string kRtspPwd; // rtsp认证用用户密码是否为md5类型 extern const std::string kRtspPwdIsMD5; // 握手超时时间,默认10,000 毫秒 extern const std::string kTimeoutMS; // rtp/rtmp包接收超时时间,默认5000秒 extern const std::string kMediaTimeoutMS; // rtsp/rtmp心跳时间,默认5000毫秒 extern const std::string kBeatIntervalMS; // 是否为性能测试模式,性能测试模式开启后不会解析rtp或rtmp包 extern const std::string kBenchmarkMode; // 播放器在触发播放成功事件时,是否等待所有track ready时再回调 extern const std::string kWaitTrackReady; // rtsp播放指定track,可选项有0(不指定,默认)、1(视频)、2(音频) // 设置方法:player[Client::kPlayTrack] = 0/1/2; extern const std::string kPlayTrack; } // namespace Client } // namespace mediakit #endif /* COMMON_CONFIG_H */