From 4dc621e1bbcc56ac11968fc68c5451a9e70e939c Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 12 Mar 2022 13:19:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BD=AC=E5=8D=8F=E8=AE=AE=E9=80=89=E9=A1=B9?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E4=B8=BAProtocolOption=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/source/mk_events.cpp | 4 +--- api/source/mk_events_objects.cpp | 5 ++++- api/source/mk_media.cpp | 6 ++++- api/source/mk_proxyplayer.cpp | 5 ++++- server/WebApi.cpp | 21 ++++++++++++------ server/WebApi.h | 3 ++- server/WebHook.cpp | 33 ++++++++++++++-------------- src/Common/Device.cpp | 6 ----- src/Common/Device.h | 12 +++++----- src/Common/MultiMediaSourceMuxer.cpp | 28 ++++++++++++++--------- src/Common/MultiMediaSourceMuxer.h | 23 ++++++++++++++++--- src/Common/config.h | 14 ++++++------ src/Player/PlayerProxy.cpp | 27 +++++++++++------------ src/Player/PlayerProxy.h | 6 ++--- src/Record/MP4Reader.cpp | 6 ++++- src/Rtmp/RtmpMediaSourceImp.h | 16 +++++++++----- src/Rtmp/RtmpSession.cpp | 16 ++++++-------- src/Rtp/RtpProcess.cpp | 12 +++++----- src/Rtsp/RtspMediaSourceImp.h | 23 ++++++++++++------- src/Rtsp/RtspSession.cpp | 14 +++++------- tests/test_bench_proxy.cpp | 5 ++++- tests/test_bench_push.cpp | 6 ++++- tests/test_pusher.cpp | 6 ++++- tests/test_server.cpp | 4 ++-- webrtc/WebRtcPusher.cpp | 7 +++--- webrtc/WebRtcPusher.h | 6 ++--- webrtc/WebRtcTransport.cpp | 8 +++---- 27 files changed, 187 insertions(+), 135 deletions(-) diff --git a/api/source/mk_events.cpp b/api/source/mk_events.cpp index e8bbe894..cd68419d 100644 --- a/api/source/mk_events.cpp +++ b/api/source/mk_events.cpp @@ -104,9 +104,7 @@ API_EXPORT void API_CALL mk_events_listen(const mk_events *events){ (mk_publish_auth_invoker) &invoker, (mk_sock_info) &sender); } else { - GET_CONFIG(bool, toHls, General::kPublishToHls); - GET_CONFIG(bool, toMP4, General::kPublishToMP4); - invoker("", toHls, toMP4); + invoker("", ProtocolOption()); } }); diff --git a/api/source/mk_events_objects.cpp b/api/source/mk_events_objects.cpp index 86fbbfbe..01709f2d 100644 --- a/api/source/mk_events_objects.cpp +++ b/api/source/mk_events_objects.cpp @@ -400,7 +400,10 @@ API_EXPORT void API_CALL mk_publish_auth_invoker_do(const mk_publish_auth_invoke int enable_mp4){ assert(ctx); Broadcast::PublishAuthInvoker *invoker = (Broadcast::PublishAuthInvoker *)ctx; - (*invoker)(err_msg ? err_msg : "", enable_hls, enable_mp4); + ProtocolOption option; + option.enable_hls = enable_hls; + option.enable_mp4 = enable_mp4; + (*invoker)(err_msg ? err_msg : "", option); } API_EXPORT mk_publish_auth_invoker API_CALL mk_publish_auth_invoker_clone(const mk_publish_auth_invoker ctx){ diff --git a/api/source/mk_media.cpp b/api/source/mk_media.cpp index 8ed616ba..3ed7c60c 100755 --- a/api/source/mk_media.cpp +++ b/api/source/mk_media.cpp @@ -163,7 +163,11 @@ API_EXPORT int API_CALL mk_media_total_reader_count(mk_media ctx){ API_EXPORT mk_media API_CALL mk_media_create(const char *vhost, const char *app, const char *stream, float duration, int hls_enabled, int mp4_enabled) { assert(vhost && app && stream); - MediaHelper::Ptr *obj(new MediaHelper::Ptr(new MediaHelper(vhost, app, stream, duration, hls_enabled, mp4_enabled))); + ProtocolOption option; + option.enable_hls = hls_enabled; + option.enable_mp4 = mp4_enabled; + + MediaHelper::Ptr *obj(new MediaHelper::Ptr(new MediaHelper(vhost, app, stream, duration, option))); (*obj)->attachEvent(); return (mk_media) obj; } diff --git a/api/source/mk_proxyplayer.cpp b/api/source/mk_proxyplayer.cpp index 158968a2..18dc2b9d 100644 --- a/api/source/mk_proxyplayer.cpp +++ b/api/source/mk_proxyplayer.cpp @@ -16,7 +16,10 @@ using namespace mediakit; API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create(const char *vhost, const char *app, const char *stream, int hls_enabled, int mp4_enabled) { assert(vhost && app && stream); - PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(vhost, app, stream, hls_enabled, mp4_enabled))); + ProtocolOption option; + option.enable_hls = hls_enabled; + option.enable_mp4 = mp4_enabled; + PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(vhost, app, stream, option))); return (mk_proxy_player) obj; } diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 580acef6..cb58304e 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -448,7 +448,7 @@ void getStatisticJson(const function &cb) { } void addStreamProxy(const string &vhost, const string &app, const string &stream, const string &url, int retry_count, - bool enable_hls, bool enable_mp4, int rtp_type, float timeout_sec, + const ProtocolOption &option, int rtp_type, float timeout_sec, const function &cb) { auto key = getProxyKey(vhost, app, stream); lock_guard lck(s_proxyMapMtx); @@ -458,7 +458,7 @@ void addStreamProxy(const string &vhost, const string &app, const string &stream return; } //添加拉流代理 - auto player = std::make_shared(vhost, app, stream, enable_hls, enable_mp4, retry_count ? retry_count : -1); + auto player = std::make_shared(vhost, app, stream, option, retry_count ? retry_count : -1); s_proxyMap[key] = player; //指定RTP over TCP(播放rtsp时有效) @@ -906,13 +906,16 @@ void installWebApi() { api_regist("/index/api/addStreamProxy",[](API_ARGS_MAP_ASYNC){ CHECK_SECRET(); CHECK_ARGS("vhost","app","stream","url"); + ProtocolOption option; + option.enable_hls = allArgs["enable_hls"]; + option.enable_mp4 = allArgs["enable_mp4"]; + addStreamProxy(allArgs["vhost"], allArgs["app"], allArgs["stream"], allArgs["url"], allArgs["retry_count"], - allArgs["enable_hls"],/* 是否hls转发 */ - allArgs["enable_mp4"],/* 是否MP4录制 */ + option, allArgs["rtp_type"], allArgs["timeout_sec"], [invoker,val,headerOut](const SockException &ex,const string &key) mutable{ @@ -1473,7 +1476,12 @@ void installWebApi() { api_regist("/index/hook/on_stream_not_found",[](API_ARGS_MAP_ASYNC){ //媒体未找到事件,我们都及时拉流hks作为替代品,目的是为了测试按需拉流 CHECK_SECRET(); - CHECK_ARGS("vhost","app","stream"); + CHECK_ARGS("vhost","app","stream", "schema"); + + ProtocolOption option; + option.enable_hls = allArgs["schema"] == HLS_SCHEMA; + option.enable_mp4 = false; + //通过内置支持的rtsp/rtmp按需拉流 addStreamProxy(allArgs["vhost"], allArgs["app"], @@ -1481,8 +1489,7 @@ void installWebApi() { /** 支持rtsp和rtmp方式拉流 ,rtsp支持h265/h264/aac,rtmp仅支持h264/aac **/ "rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov", -1,/*无限重试*/ - true,/* 开启hls转发 */ - false,/* 禁用MP4录制 */ + option, 0,//rtp over tcp方式拉流 10,//10秒超时 [invoker,val,headerOut](const SockException &ex,const string &key) mutable{ diff --git a/server/WebApi.h b/server/WebApi.h index cc7cf62e..eabd8f2a 100755 --- a/server/WebApi.h +++ b/server/WebApi.h @@ -17,6 +17,7 @@ #include "Common/Parser.h" #include "Network/Socket.h" #include "Http/HttpSession.h" +#include "Common/MultiMediaSourceMuxer.h" //配置文件路径 extern std::string g_ini_file; @@ -232,6 +233,6 @@ void unInstallWebApi(); 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, - bool enable_hls, bool enable_mp4, int rtp_type, float timeout_sec, + const mediakit::ProtocolOption &option, int rtp_type, float timeout_sec, const std::function &cb); #endif //ZLMEDIAKIT_WEBAPI_H diff --git a/server/WebHook.cpp b/server/WebHook.cpp index fe88b461..abead83f 100755 --- a/server/WebHook.cpp +++ b/server/WebHook.cpp @@ -244,8 +244,12 @@ static void pullStreamFromOrigin(const vector& urls, size_t index, size_ auto timeout_sec = cluster_timeout_sec / urls.size(); InfoL << "pull stream from origin, failed_cnt: " << failed_cnt << ", timeout_sec: " << timeout_sec << ", url: " << url; - addStreamProxy(args._vhost, args._app, args._streamid, url, -1, args._schema == HLS_SCHEMA, false, - Rtsp::RTP_TCP, timeout_sec, [=](const SockException &ex, const string &key) mutable { + ProtocolOption option; + option.enable_hls = args._schema == HLS_SCHEMA; + option.enable_mp4 = false; + + addStreamProxy(args._vhost, args._app, args._streamid, url, -1, option, Rtsp::RTP_TCP, timeout_sec, + [=](const SockException &ex, const string &key) mutable { if (!ex) { return; } @@ -264,12 +268,10 @@ void installWebHook(){ GET_CONFIG(bool,hook_enable,Hook::kEnable); GET_CONFIG(string,hook_adminparams,Hook::kAdminParams); - NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastMediaPublish,[](BroadcastMediaPublishArgs){ + NoticeCenter::Instance().addListener(nullptr, Broadcast::kBroadcastMediaPublish, [](BroadcastMediaPublishArgs) { GET_CONFIG(string,hook_publish,Hook::kOnPublish); - GET_CONFIG(bool,toHls,General::kPublishToHls); - GET_CONFIG(bool,toMP4,General::kPublishToMP4); - if(!hook_enable || args._param_strs == hook_adminparams || hook_publish.empty() || sender.get_peer_ip() == "127.0.0.1"){ - invoker("", toHls, toMP4); + if (!hook_enable || args._param_strs == hook_adminparams || hook_publish.empty() || sender.get_peer_ip() == "127.0.0.1") { + invoker("", ProtocolOption()); return; } //异步执行该hook api,防止阻塞NoticeCenter @@ -280,25 +282,22 @@ void installWebHook(){ body["originType"] = (int) type; body["originTypeStr"] = getOriginTypeString(type); //执行hook - do_http_hook(hook_publish,body,[invoker](const Value &obj,const string &err){ - if(err.empty()){ + do_http_hook(hook_publish, body, [invoker](const Value &obj, const string &err) mutable { + ProtocolOption option; + if (err.empty()) { //推流鉴权成功 - bool enableHls = toHls; - bool enableMP4 = toMP4; - //兼容用户不传递enableHls、enableMP4参数 if (obj.isMember("enableHls")) { - enableHls = obj["enableHls"].asBool(); + option.enable_hls = obj["enableHls"].asBool(); } if (obj.isMember("enableMP4")) { - enableMP4 = obj["enableMP4"].asBool(); + option.enable_mp4 = obj["enableMP4"].asBool(); } - invoker(err, enableHls, enableMP4); + invoker(err, option); } else { //推流鉴权失败 - invoker(err, false, false); + invoker(err, option); } - }); }); diff --git a/src/Common/Device.cpp b/src/Common/Device.cpp index 6720feb0..c0bd682f 100644 --- a/src/Common/Device.cpp +++ b/src/Common/Device.cpp @@ -28,12 +28,6 @@ using namespace std; namespace mediakit { -DevChannel::DevChannel(const string &vhost, const string &app, const string &stream_id, - float duration, bool enable_hls, bool enable_mp4) : - MultiMediaSourceMuxer(vhost, app, stream_id, duration, true, true, enable_hls, enable_mp4) {} - -DevChannel::~DevChannel() {} - bool DevChannel::inputYUV(char* apcYuv[3], int aiYuvLen[3], uint32_t uiStamp) { #ifdef ENABLE_X264 //TimeTicker1(50); diff --git a/src/Common/Device.h b/src/Common/Device.h index 22b068e9..6eb9c81d 100644 --- a/src/Common/Device.h +++ b/src/Common/Device.h @@ -44,12 +44,14 @@ public: */ class DevChannel : public MultiMediaSourceMuxer{ public: - typedef std::shared_ptr Ptr; - //fDuration<=0为直播,否则为点播 - DevChannel(const std::string &vhost, const std::string &app, const std::string &stream_id, - float duration = 0, bool enable_hls = true, bool enable_mp4 = false); + using Ptr = std::shared_ptr; - ~DevChannel() override ; + //fDuration<=0为直播,否则为点播 + DevChannel( + const std::string &vhost, const std::string &app, const std::string &stream_id, float duration = 0, + const ProtocolOption &option = ProtocolOption()) + : MultiMediaSourceMuxer(vhost, app, stream_id, duration, option) {} + ~DevChannel() override = default; /** * 初始化视频Track diff --git a/src/Common/MultiMediaSourceMuxer.cpp b/src/Common/MultiMediaSourceMuxer.cpp index 03f9df96..fac4684f 100644 --- a/src/Common/MultiMediaSourceMuxer.cpp +++ b/src/Common/MultiMediaSourceMuxer.cpp @@ -21,6 +21,13 @@ namespace toolkit { namespace mediakit { +ProtocolOption::ProtocolOption() { + GET_CONFIG(bool, toHls, General::kPublishToHls); + GET_CONFIG(bool, toMP4, General::kPublishToMP4); + enable_hls = toHls; + enable_mp4 = toMP4; +} + 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); for (auto &track : tracks) { @@ -59,8 +66,7 @@ static string getTrackInfoStr(const TrackSource *track_src){ return std::move(codec_info); } -MultiMediaSourceMuxer::MultiMediaSourceMuxer(const string &vhost, const string &app, const string &stream, float dur_sec, - bool enable_rtsp, bool enable_rtmp, bool enable_hls, bool enable_mp4) { +MultiMediaSourceMuxer::MultiMediaSourceMuxer(const string &vhost, const string &app, const string &stream, float dur_sec, const ProtocolOption &option) { _get_origin_url = [this, vhost, app, stream]() { auto ret = getOriginUrl(*MediaSource::NullMediaSource); if (!ret.empty()) { @@ -69,25 +75,27 @@ MultiMediaSourceMuxer::MultiMediaSourceMuxer(const string &vhost, const string & return vhost + "/" + app + "/" + stream; }; - if (enable_rtmp) { + if (option.enable_rtmp) { _rtmp = std::make_shared(vhost, app, stream, std::make_shared(dur_sec)); } - if (enable_rtsp) { + if (option.enable_rtsp) { _rtsp = std::make_shared(vhost, app, stream, std::make_shared(dur_sec)); } - if (enable_hls) { + if (option.enable_hls) { _hls = dynamic_pointer_cast(Recorder::createRecorder(Recorder::type_hls, vhost, app, stream)); } - if (enable_mp4) { + if (option.enable_mp4) { _mp4 = Recorder::createRecorder(Recorder::type_mp4, vhost, app, stream); } - - _ts = std::make_shared(vhost, app, stream); - + if (option.enable_ts) { + _ts = std::make_shared(vhost, app, stream); + } #if defined(ENABLE_MP4) - _fmp4 = std::make_shared(vhost, app, stream); + if (option.enable_fmp4) { + _fmp4 = std::make_shared(vhost, app, stream); + } #endif } diff --git a/src/Common/MultiMediaSourceMuxer.h b/src/Common/MultiMediaSourceMuxer.h index b811315b..e76fdd75 100644 --- a/src/Common/MultiMediaSourceMuxer.h +++ b/src/Common/MultiMediaSourceMuxer.h @@ -21,7 +21,25 @@ #include "TS/TSMediaSourceMuxer.h" #include "FMP4/FMP4MediaSourceMuxer.h" -namespace mediakit{ +namespace mediakit { + +class ProtocolOption { +public: + ProtocolOption(); + + //是否开启转换为hls + bool enable_hls = false; + //是否开启MP4录制 + bool enable_mp4 = 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; +}; class MultiMediaSourceMuxer : public MediaSourceEventInterceptor, public MediaSink, public std::enable_shared_from_this{ public: @@ -34,9 +52,8 @@ public: virtual void onAllTrackReady() = 0; }; + MultiMediaSourceMuxer(const std::string &vhost, const std::string &app, const std::string &stream, float dur_sec = 0.0,const ProtocolOption &option = ProtocolOption()); ~MultiMediaSourceMuxer() override = default; - MultiMediaSourceMuxer(const std::string &vhost, const std::string &app, const std::string &stream, float dur_sec = 0.0, - bool enable_rtsp = true, bool enable_rtmp = true, bool enable_hls = true, bool enable_mp4 = false); /** * 设置事件监听器 diff --git a/src/Common/config.h b/src/Common/config.h index fb84be28..468eb59b 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -20,6 +20,8 @@ namespace mediakit { +class ProtocolOption; + //加载配置文件,如果配置文件不存在,那么会导出默认配置并生成配置文件 //加载配置文件成功后会触发kBroadcastUpdateConfig广播 //如果指定的文件名(ini_path)为空,那么会加载默认配置文件 @@ -65,18 +67,16 @@ 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 //推流鉴权结果回调对象 -//如果errMessage为空则代表鉴权成功 -//enableHls: 是否允许转换hls -//enableMP4: 是否运行MP4录制 -typedef std::function PublishAuthInvoker; +//如果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 +#define BroadcastMediaPublishArgs const MediaOriginType &type, const MediaInfo &args, const Broadcast::PublishAuthInvoker &invoker,SockInfo &sender //播放鉴权结果回调对象 -//如果errMessage为空则代表鉴权成功 -typedef std::function AuthInvoker; +//如果err为空则代表鉴权成功 +using AuthInvoker = std::function; //播放rtsp/rtmp/http-flv事件广播,通过该事件控制播放鉴权 extern const std::string kBroadcastMediaPlayed; diff --git a/src/Player/PlayerProxy.cpp b/src/Player/PlayerProxy.cpp index dab199e6..19c892aa 100644 --- a/src/Player/PlayerProxy.cpp +++ b/src/Player/PlayerProxy.cpp @@ -20,14 +20,11 @@ using namespace std; namespace mediakit { -PlayerProxy::PlayerProxy(const string &vhost, const string &app, const string &stream_id, - bool enable_hls, bool enable_mp4, int retry_count, const EventPoller::Ptr &poller) - : MediaPlayer(poller) { +PlayerProxy::PlayerProxy(const string &vhost, const string &app, const string &stream_id, const ProtocolOption &option, + int retry_count, const EventPoller::Ptr &poller) : MediaPlayer(poller) , _option(option) { _vhost = vhost; _app = app; _stream_id = stream_id; - _enable_hls = enable_hls; - _enable_mp4 = enable_mp4; _retry_count = retry_count; _on_close = [](const SockException &) {}; (*this)[Client::kWaitTrackReady] = false; @@ -84,8 +81,8 @@ void PlayerProxy::play(const string &strUrlTmp) { track->delDelegate(strongSelf->_muxer.get()); } - GET_CONFIG(bool, resetWhenRePlay, General::kResetWhenRePlay); - if (resetWhenRePlay) { + GET_CONFIG(bool, reset_when_replay, General::kResetWhenRePlay); + if (reset_when_replay) { strongSelf->_muxer.reset(); } else { strongSelf->_muxer->resetTracks(); @@ -184,21 +181,23 @@ std::shared_ptr PlayerProxy::getOriginSock(MediaSource &sender) const } void PlayerProxy::onPlaySuccess() { - GET_CONFIG(bool, resetWhenRePlay, General::kResetWhenRePlay); + GET_CONFIG(bool, reset_when_replay, General::kResetWhenRePlay); if (dynamic_pointer_cast(_media_src)) { //rtsp拉流代理 - if (resetWhenRePlay || !_muxer) { - _muxer = std::make_shared(_vhost, _app, _stream_id, getDuration(), false, true, _enable_hls, _enable_mp4); + if (reset_when_replay || !_muxer) { + _option.enable_rtsp = false; + _muxer = std::make_shared(_vhost, _app, _stream_id, getDuration(), _option); } } else if (dynamic_pointer_cast(_media_src)) { //rtmp拉流代理 - if (resetWhenRePlay || !_muxer) { - _muxer = std::make_shared(_vhost, _app, _stream_id, getDuration(), true, false, _enable_hls, _enable_mp4); + if (reset_when_replay || !_muxer) { + _option.enable_rtmp = false; + _muxer = std::make_shared(_vhost, _app, _stream_id, getDuration(), _option); } } else { //其他拉流代理 - if (resetWhenRePlay || !_muxer) { - _muxer = std::make_shared(_vhost, _app, _stream_id, getDuration(), true, true, _enable_hls, _enable_mp4); + if (reset_when_replay || !_muxer) { + _muxer = std::make_shared(_vhost, _app, _stream_id, getDuration(), _option); } } _muxer->setMediaListener(shared_from_this()); diff --git a/src/Player/PlayerProxy.h b/src/Player/PlayerProxy.h index 455d325e..718f76a4 100644 --- a/src/Player/PlayerProxy.h +++ b/src/Player/PlayerProxy.h @@ -25,8 +25,7 @@ public: //如果retry_count<0,则一直重试播放;否则重试retry_count次数 //默认一直重试 PlayerProxy(const std::string &vhost, const std::string &app, const std::string &stream_id, - bool enable_hls = true, bool enable_mp4 = false, - int retry_count = -1, const toolkit::EventPoller::Ptr &poller = nullptr); + const ProtocolOption &option, int retry_count = -1, const toolkit::EventPoller::Ptr &poller = nullptr); ~PlayerProxy() override; @@ -66,8 +65,7 @@ private: void setDirectProxy(); private: - bool _enable_hls; - bool _enable_mp4; + ProtocolOption _option; int _retry_count; std::string _vhost; std::string _app; diff --git a/src/Record/MP4Reader.cpp b/src/Record/MP4Reader.cpp index 457ec040..3daccbae 100644 --- a/src/Record/MP4Reader.cpp +++ b/src/Record/MP4Reader.cpp @@ -38,7 +38,11 @@ MP4Reader::MP4Reader(const string &vhost, const string &app, const string &strea if (stream_id.empty()) { return; } - _muxer = std::make_shared(vhost, app, stream_id, _demuxer->getDurationMS() / 1000.0f, true, true, false, false); + ProtocolOption option; + //读取mp4文件并流化时,不重复生成mp4/hls文件 + option.enable_mp4 = false; + option.enable_hls = false; + _muxer = std::make_shared(vhost, app, stream_id, _demuxer->getDurationMS() / 1000.0f, option); auto tracks = _demuxer->getTracks(false); if (tracks.empty()) { throw std::runtime_error(StrPrinter << "该mp4文件没有有效的track:" << _file_path); diff --git a/src/Rtmp/RtmpMediaSourceImp.h b/src/Rtmp/RtmpMediaSourceImp.h index f03068c6..915b8fd1 100644 --- a/src/Rtmp/RtmpMediaSourceImp.h +++ b/src/Rtmp/RtmpMediaSourceImp.h @@ -76,23 +76,28 @@ public: /** * 设置协议转换 - * @param enableHls 是否转换成hls - * @param enableMP4 是否mp4录制 */ - void setProtocolTranslation(bool enableHls, bool enableMP4) { + void setProtocolOption(const ProtocolOption &option) { //不重复生成rtmp - _muxer = std::make_shared(getVhost(), getApp(), getId(), _demuxer->getDuration(), true, false, enableHls, enableMP4); + _option = option; + //不重复生成rtmp协议 + _option.enable_rtmp = false; + _muxer = std::make_shared(getVhost(), getApp(), getId(), _demuxer->getDuration(), _option); _muxer->setMediaListener(getListener()); _muxer->setTrackListener(std::static_pointer_cast(shared_from_this())); //让_muxer对象拦截一部分事件(比如说录像相关事件) MediaSource::setListener(_muxer); - for(auto &track : _demuxer->getTracks(false)){ + for (auto &track : _demuxer->getTracks(false)) { _muxer->addTrack(track); track->addDelegate(_muxer); } } + const ProtocolOption &getProtocolOption() const { + return _option; + } + /** * _demuxer触发的添加Track事件 */ @@ -153,6 +158,7 @@ public: private: bool _all_track_ready = false; bool _recreate_metadata = false; + ProtocolOption _option; AMFValue _metadata; RtmpDemuxer::Ptr _demuxer; MultiMediaSourceMuxer::Ptr _muxer; diff --git a/src/Rtmp/RtmpSession.cpp b/src/Rtmp/RtmpSession.cpp index c35f88b0..be66dd02 100644 --- a/src/Rtmp/RtmpSession.cpp +++ b/src/Rtmp/RtmpSession.cpp @@ -135,7 +135,7 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) { _media_info.parse(_tc_url + "/" + getStreamId(dec.load())); _media_info._schema = RTMP_SCHEMA; - auto on_res = [this, pToken](const string &err, bool enableHls, bool enableMP4) { + auto on_res = [this, pToken](const string &err, const ProtocolOption &option) { if (!err.empty()) { sendStatus({ "level", "error", "code", "NetStream.Publish.BadAuth", @@ -180,7 +180,7 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) { _push_src = std::make_shared(_media_info._vhost, _media_info._app, _media_info._streamid); //获取所有权 _push_src_ownership = _push_src->getOwnership(); - _push_src->setProtocolTranslation(enableHls, enableMP4); + _push_src->setProtocolOption(option); } _push_src->setListener(dynamic_pointer_cast(shared_from_this())); @@ -195,29 +195,27 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) { if(_media_info._app.empty() || _media_info._streamid.empty()){ //不允许莫名其妙的推流url - on_res("rtmp推流url非法", false, false); + on_res("rtmp推流url非法", ProtocolOption()); return; } - Broadcast::PublishAuthInvoker invoker = [weak_self, on_res, pToken](const string &err, bool enableHls, bool enableMP4) { + Broadcast::PublishAuthInvoker invoker = [weak_self, on_res, pToken](const string &err, const ProtocolOption &option) { auto strongSelf = weak_self.lock(); if (!strongSelf) { return; } - strongSelf->async([weak_self, on_res, err, pToken, enableHls, enableMP4]() { + strongSelf->async([weak_self, on_res, err, pToken, option]() { auto strongSelf = weak_self.lock(); if (!strongSelf) { return; } - on_res(err, enableHls, enableMP4); + on_res(err, option); }); }; auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, MediaOriginType::rtmp_push, _media_info, invoker, static_cast(*this)); if(!flag){ //该事件无人监听,默认鉴权成功 - GET_CONFIG(bool,to_hls,General::kPublishToHls); - GET_CONFIG(bool,to_mp4,General::kPublishToMP4); - on_res("", to_hls, to_mp4); + on_res("", ProtocolOption()); } } diff --git a/src/Rtp/RtpProcess.cpp b/src/Rtp/RtpProcess.cpp index 0549c5bf..ba28bcbb 100644 --- a/src/Rtp/RtpProcess.cpp +++ b/src/Rtp/RtpProcess.cpp @@ -233,16 +233,16 @@ void RtpProcess::setListener(const std::weak_ptr &listener) { void RtpProcess::emitOnPublish() { weak_ptr weak_self = shared_from_this(); - Broadcast::PublishAuthInvoker invoker = [weak_self](const string &err, bool enableHls, bool enableMP4) { + Broadcast::PublishAuthInvoker invoker = [weak_self](const string &err, const ProtocolOption &option) { auto strong_self = weak_self.lock(); if (!strong_self) { return; } if (err.empty()) { strong_self->_muxer = std::make_shared(strong_self->_media_info._vhost, - strong_self->_media_info._app, - strong_self->_media_info._streamid, 0.0f, - true, true, enableHls, enableMP4); + strong_self->_media_info._app, + strong_self->_media_info._streamid, 0.0f, + option); strong_self->_muxer->setMediaListener(strong_self); strong_self->doCachedFunc(); InfoP(strong_self) << "允许RTP推流"; @@ -255,9 +255,7 @@ void RtpProcess::emitOnPublish() { auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, MediaOriginType::rtp_push, _media_info, invoker, static_cast(*this)); if (!flag) { //该事件无人监听,默认不鉴权 - GET_CONFIG(bool, toHls, General::kPublishToHls); - GET_CONFIG(bool, toMP4, General::kPublishToMP4); - invoker("", toHls, toMP4); + invoker("", ProtocolOption()); } } diff --git a/src/Rtsp/RtspMediaSourceImp.h b/src/Rtsp/RtspMediaSourceImp.h index 34c82871..a717a832 100644 --- a/src/Rtsp/RtspMediaSourceImp.h +++ b/src/Rtsp/RtspMediaSourceImp.h @@ -73,26 +73,32 @@ public: } /** - * 设置协议转换 - * @param enableHls 是否转换成hls - * @param enableMP4 是否mp4录制 + * 设置协议转换选项 */ - void setProtocolTranslation(bool enableHls,bool enableMP4){ - GET_CONFIG(bool, directProxy, Rtsp::kDirectProxy); + void setProtocolOption(const ProtocolOption &option) { + GET_CONFIG(bool, direct_proxy, Rtsp::kDirectProxy); //开启直接代理模式时,rtsp直接代理,不重复产生;但是有些rtsp推流端,由于sdp中已有sps pps,rtp中就不再包括sps pps, //导致rtc无法播放,所以在rtsp推流rtc播放时,建议关闭直接代理模式 - _muxer = std::make_shared(getVhost(), getApp(), getId(), _demuxer->getDuration(), !directProxy, true, enableHls, enableMP4); + _option = option; + if (!direct_proxy) { + _option.enable_rtsp = true; + } + _muxer = std::make_shared(getVhost(), getApp(), getId(), _demuxer->getDuration(), _option); _muxer->setMediaListener(getListener()); _muxer->setTrackListener(std::static_pointer_cast(shared_from_this())); //让_muxer对象拦截一部分事件(比如说录像相关事件) MediaSource::setListener(_muxer); - for(auto &track : _demuxer->getTracks(false)){ + for (auto &track : _demuxer->getTracks(false)) { _muxer->addTrack(track); track->addDelegate(_muxer); } } + const ProtocolOption &getProtocolOption() const { + return _option; + } + /** * _demuxer触发的添加Track事件 */ @@ -143,9 +149,10 @@ public: } private: + bool _all_track_ready = false; + ProtocolOption _option; RtspDemuxer::Ptr _demuxer; MultiMediaSourceMuxer::Ptr _muxer; - bool _all_track_ready = false; }; } /* namespace mediakit */ diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index c46cf2b2..368a575b 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -219,7 +219,7 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { throw SockException(Err_shutdown, StrPrinter << err << ":" << full_url); } - auto onRes = [this, parser, full_url](const string &err, bool enableHls, bool enableMP4) { + auto onRes = [this, parser, full_url](const string &err, const ProtocolOption &option) { if (!err.empty()) { sendRtspResponse("401 Unauthorized", { "Content-Type", "text/plain" }, err); shutdown(SockException(Err_shutdown, StrPrinter << "401 Unauthorized:" << err)); @@ -275,7 +275,7 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { _push_src = std::make_shared(_media_info._vhost, _media_info._app, _media_info._streamid); //获取所有权 _push_src_ownership = _push_src->getOwnership(); - _push_src->setProtocolTranslation(enableHls, enableMP4); + _push_src->setProtocolOption(option); _push_src->setSdp(parser.Content()); } @@ -284,17 +284,17 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { }; weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); - Broadcast::PublishAuthInvoker invoker = [weakSelf, onRes](const string &err, bool enableHls, bool enableMP4) { + Broadcast::PublishAuthInvoker invoker = [weakSelf, onRes](const string &err, const ProtocolOption &option) { auto strongSelf = weakSelf.lock(); if (!strongSelf) { return; } - strongSelf->async([weakSelf, onRes, err, enableHls, enableMP4]() { + strongSelf->async([weakSelf, onRes, err, option]() { auto strongSelf = weakSelf.lock(); if (!strongSelf) { return; } - onRes(err, enableHls, enableMP4); + onRes(err, option); }); }; @@ -302,9 +302,7 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, MediaOriginType::rtsp_push, _media_info, invoker, static_cast(*this)); if (!flag) { //该事件无人监听,默认不鉴权 - GET_CONFIG(bool, toHls, General::kPublishToHls); - GET_CONFIG(bool, toMP4, General::kPublishToMP4); - onRes("", toHls, toMP4); + onRes("", ProtocolOption()); } } diff --git a/tests/test_bench_proxy.cpp b/tests/test_bench_proxy.cpp index 4a178cea..793b4107 100644 --- a/tests/test_bench_proxy.cpp +++ b/tests/test_bench_proxy.cpp @@ -132,9 +132,12 @@ int main(int argc, char *argv[]) { mINI::Instance()[General::kFMP4Demand] = demand; map proxyMap; + ProtocolOption option; + option.enable_hls = false; + option.enable_mp4 = false; for (auto i = 0; i < proxy_count; ++i) { auto stream = to_string(i); - PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", stream, false, false)); + PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", stream, option)); (*player)[Client::kRtpType] = rtp_type; player->play(in_url); proxyMap.emplace(stream, player); diff --git a/tests/test_bench_push.cpp b/tests/test_bench_push.cpp index 8c1046d3..e5496f66 100644 --- a/tests/test_bench_push.cpp +++ b/tests/test_bench_push.cpp @@ -140,8 +140,12 @@ int main(int argc, char *argv[]) { //设置合并写 mINI::Instance()[General::kMergeWriteMS] = merge_ms; + ProtocolOption option; + option.enable_hls = false; + option.enable_mp4 = false; + //添加拉流代理 - auto proxy = std::make_shared(DEFAULT_VHOST, "app", "test", false, false); + auto proxy = std::make_shared(DEFAULT_VHOST, "app", "test", option); //rtsp拉流代理方式 (*proxy)[Client::kRtpType] = rtp_type; //开始拉流代理 diff --git a/tests/test_pusher.cpp b/tests/test_pusher.cpp index f79d4495..adf85199 100644 --- a/tests/test_pusher.cpp +++ b/tests/test_pusher.cpp @@ -75,7 +75,11 @@ int domain(const string &playUrl, const string &pushUrl) { //拉一个流,生成一个RtmpMediaSource,源的名称是"app/stream" //你也可以以其他方式生成RtmpMediaSource,比如说MP4文件(请查看test_rtmpPusherMp4.cpp代码) MediaInfo info(pushUrl); - PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "app", "stream",false,false,-1 , poller)); + + ProtocolOption option; + option.enable_hls = false; + option.enable_mp4 = false; + PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "app", "stream", option, -1, poller)); //可以指定rtsp拉流方式,支持tcp和udp方式,默认tcp // (*player)[Client::kRtpType] = Rtsp::RTP_UDP; player->play(playUrl.data()); diff --git a/tests/test_server.cpp b/tests/test_server.cpp index 7cd58026..da0d7bd1 100644 --- a/tests/test_server.cpp +++ b/tests/test_server.cpp @@ -141,7 +141,7 @@ void initEventListener() { NoticeCenter::Instance().addListener(nullptr, Broadcast::kBroadcastMediaPublish, [](BroadcastMediaPublishArgs) { DebugL << "推流鉴权:" << args._schema << " " << args._vhost << " " << args._app << " " << args._streamid << " " << args._param_strs; - invoker("", true, false);//鉴权成功 + invoker("", ProtocolOption());//鉴权成功 //invoker("this is auth failed message");//鉴权失败 }); @@ -242,7 +242,7 @@ int main(int argc,char *argv[]) { //rtsp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4 //rtmp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4 - PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", std::string("chn") + to_string(i).data())); + PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", std::string("chn") + to_string(i).data(), ProtocolOption())); //指定RTP over TCP(播放rtsp时有效) (*player)[Client::kRtpType] = Rtsp::RTP_TCP; //开始播放,如果播放失败或者播放中止,将会自动重试若干次,重试次数在配置文件中配置,默认一直重试 diff --git a/webrtc/WebRtcPusher.cpp b/webrtc/WebRtcPusher.cpp index 096efd13..05929dc6 100644 --- a/webrtc/WebRtcPusher.cpp +++ b/webrtc/WebRtcPusher.cpp @@ -14,7 +14,7 @@ using namespace std; using namespace mediakit; WebRtcPusher::Ptr WebRtcPusher::create(const EventPoller::Ptr &poller, - const RtspMediaSource::Ptr &src, + const RtspMediaSourceImp::Ptr &src, const std::shared_ptr &ownership, const MediaInfo &info) { WebRtcPusher::Ptr ret(new WebRtcPusher(poller, src, ownership, info), [](WebRtcPusher *ptr) { @@ -26,7 +26,7 @@ WebRtcPusher::Ptr WebRtcPusher::create(const EventPoller::Ptr &poller, } WebRtcPusher::WebRtcPusher(const EventPoller::Ptr &poller, - const RtspMediaSource::Ptr &src, + const RtspMediaSourceImp::Ptr &src, const std::shared_ptr &ownership, const MediaInfo &info) : WebRtcTransportImp(poller) { _media_info = info; @@ -94,8 +94,7 @@ void WebRtcPusher::onRecvRtp(MediaTrack &track, const string &rid, RtpPacket::Pt auto src_imp = std::make_shared(_push_src->getVhost(), _push_src->getApp(), stream_id); _push_src_sim_ownership[rid] = src_imp->getOwnership(); src_imp->setSdp(_push_src->getSdp()); - src_imp->setProtocolTranslation(_push_src->isRecording(Recorder::type_hls), - _push_src->isRecording(Recorder::type_mp4)); + src_imp->setProtocolOption(_push_src->getProtocolOption()); src_imp->setListener(static_pointer_cast(shared_from_this())); src = src_imp; } diff --git a/webrtc/WebRtcPusher.h b/webrtc/WebRtcPusher.h index ac61484b..9b52c890 100644 --- a/webrtc/WebRtcPusher.h +++ b/webrtc/WebRtcPusher.h @@ -17,7 +17,7 @@ class WebRtcPusher : public WebRtcTransportImp, public mediakit::MediaSourceEven public: using Ptr = std::shared_ptr; ~WebRtcPusher() override = default; - static Ptr create(const EventPoller::Ptr &poller, const mediakit::RtspMediaSource::Ptr &src, + static Ptr create(const EventPoller::Ptr &poller, const mediakit::RtspMediaSourceImp::Ptr &src, const std::shared_ptr &ownership, const mediakit::MediaInfo &info); protected: @@ -41,7 +41,7 @@ protected: std::shared_ptr getOriginSock(mediakit::MediaSource &sender) const override; private: - WebRtcPusher(const EventPoller::Ptr &poller, const mediakit::RtspMediaSource::Ptr &src, + WebRtcPusher(const EventPoller::Ptr &poller, const mediakit::RtspMediaSourceImp::Ptr &src, const std::shared_ptr &ownership, const mediakit::MediaInfo &info); private: @@ -49,7 +49,7 @@ private: //媒体相关元数据 mediakit::MediaInfo _media_info; //推流的rtsp源 - mediakit::RtspMediaSource::Ptr _push_src; + mediakit::RtspMediaSourceImp::Ptr _push_src; //推流所有权 std::shared_ptr _push_src_ownership; //推流的rtsp源,支持simulcast diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 19be2570..845f1f0b 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -971,7 +971,7 @@ void echo_plugin(Session &sender, const string &offer, const WebRtcArgs &args, c void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { MediaInfo info(args["url"]); - Broadcast::PublishAuthInvoker invoker = [cb, offer_sdp, info](const string &err, bool enable_hls, bool enable_mp4) mutable { + Broadcast::PublishAuthInvoker invoker = [cb, offer_sdp, info](const string &err, const ProtocolOption &option) mutable { if (!err.empty()) { cb(WebRtcException(SockException(Err_other, err))); return; @@ -1008,7 +1008,7 @@ void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg if (!push_src) { push_src = std::make_shared(info._vhost, info._app, info._streamid); push_src_ownership = push_src->getOwnership(); - push_src->setProtocolTranslation(enable_hls, enable_mp4); + push_src->setProtocolOption(option); } auto rtc = WebRtcPusher::create(EventPollerPool::Instance().getPoller(), push_src, push_src_ownership, info); push_src->setListener(rtc); @@ -1019,9 +1019,7 @@ void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, MediaOriginType::rtc_push, info, invoker, static_cast(sender)); if (!flag) { //该事件无人监听,默认不鉴权 - GET_CONFIG(bool, to_hls, General::kPublishToHls); - GET_CONFIG(bool, to_mp4, General::kPublishToMP4); - invoker("", to_hls, to_mp4); + invoker("", ProtocolOption()); } }