diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 4de4449b..4546657d 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -741,6 +741,32 @@ void installWebApi() { val["online"] = (bool) (MediaSource::find(allArgs["schema"],allArgs["vhost"],allArgs["app"],allArgs["stream"])); }); + api_regist("/index/api/getMediaPlayerList",[](API_ARGS_MAP_ASYNC){ + CHECK_SECRET(); + CHECK_ARGS("schema", "vhost", "app", "stream"); + auto src = MediaSource::find(allArgs["schema"], allArgs["vhost"], allArgs["app"], allArgs["stream"]); + if (!src) { + throw ApiRetException("can not find the stream", API::NotFound); + } + src->getPlayerList( + [=](const std::list> &info_list) mutable { + val["code"] = API::Success; + auto &data = val["data"]; + for (auto &info : info_list) { + auto obj = reinterpret_pointer_cast(info); + data.append(std::move(*obj)); + } + invoker(200, headerOut, val.toStyledString()); + }, + [](std::shared_ptr &&info) -> std::shared_ptr { + auto obj = std::make_shared(); + auto session = reinterpret_pointer_cast(info); + (*obj)["peer_ip"] = session->get_peer_ip(); + (*obj)["peer_port"] = session->get_peer_port(); + return obj; + }); + }); + //测试url http://127.0.0.1/index/api/getMediaInfo?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs api_regist("/index/api/getMediaInfo",[](API_ARGS_MAP_ASYNC){ CHECK_SECRET(); diff --git a/src/Common/MediaSource.h b/src/Common/MediaSource.h index 2ea5204d..fbeaa115 100644 --- a/src/Common/MediaSource.h +++ b/src/Common/MediaSource.h @@ -192,52 +192,6 @@ public: std::string _param_strs; }; -class BytesSpeed { -public: - BytesSpeed() = default; - ~BytesSpeed() = default; - - /** - * 添加统计字节 - */ - BytesSpeed& operator += (size_t bytes) { - _bytes += bytes; - if (_bytes > 1024 * 1024) { - //数据大于1MB就计算一次网速 - computeSpeed(); - } - return *this; - } - - /** - * 获取速度,单位bytes/s - */ - int getSpeed() { - if (_ticker.elapsedTime() < 1000) { - //获取频率小于1秒,那么返回上次计算结果 - return _speed; - } - return computeSpeed(); - } - -private: - int computeSpeed() { - auto elapsed = _ticker.elapsedTime(); - if (!elapsed) { - return _speed; - } - _speed = (int)(_bytes * 1000 / elapsed); - _ticker.resetTime(); - _bytes = 0; - return _speed; - } - -private: - int _speed = 0; - size_t _bytes = 0; - toolkit::Ticker _ticker; -}; - /** * 媒体源,任何rtsp/rtmp的直播流都源自该对象 */ @@ -293,6 +247,12 @@ public: virtual int readerCount() = 0; // 观看者个数,包括(hls/rtsp/rtmp) virtual int totalReaderCount(); + // 获取播放器列表 + virtual void getPlayerList(const std::function> &info_list)> &cb, + const std::function(std::shared_ptr &&info)> &on_change) { + assert(cb); + cb(std::list>()); + } // 获取媒体源类型 MediaOriginType getOriginType() const; @@ -350,7 +310,7 @@ private: void emitEvent(bool regist); protected: - BytesSpeed _speed[TrackMax]; + toolkit::BytesSpeed _speed[TrackMax]; private: std::atomic_flag _owned { false }; diff --git a/src/FMP4/FMP4MediaSource.h b/src/FMP4/FMP4MediaSource.h index 65fc7172..e4c6a15f 100644 --- a/src/FMP4/FMP4MediaSource.h +++ b/src/FMP4/FMP4MediaSource.h @@ -51,6 +51,11 @@ public: return _ring; } + void getPlayerList(const std::function> &info_list)> &cb, + const std::function(std::shared_ptr &&info)> &on_change) override { + _ring->getInfoList(cb, on_change); + } + /** * 获取fmp4 init segment */ diff --git a/src/Http/HttpSession.cpp b/src/Http/HttpSession.cpp index c90544b3..88a3be4b 100644 --- a/src/Http/HttpSession.cpp +++ b/src/Http/HttpSession.cpp @@ -285,6 +285,9 @@ bool HttpSession::checkLiveStreamFMP4(const function &cb){ } strong_self->shutdown(SockException(Err_shutdown, "fmp4 ring buffer detached")); }); + + _fmp4_reader->setGetInfoCB([weak_self]() { return weak_self.lock(); }); + _fmp4_reader->setReadCB([weak_self](const FMP4MediaSource::RingDataType &fmp4_list) { auto strong_self = weak_self.lock(); if (!strong_self) { @@ -326,6 +329,9 @@ bool HttpSession::checkLiveStreamTS(const function &cb){ } strong_self->shutdown(SockException(Err_shutdown,"ts ring buffer detached")); }); + + _ts_reader->setGetInfoCB([weak_self]() { return weak_self.lock(); }); + _ts_reader->setReadCB([weak_self](const TSMediaSource::RingDataType &ts_list) { auto strong_self = weak_self.lock(); if (!strong_self) { diff --git a/src/Rtmp/FlvMuxer.cpp b/src/Rtmp/FlvMuxer.cpp index a58dd665..7e54d0f7 100644 --- a/src/Rtmp/FlvMuxer.cpp +++ b/src/Rtmp/FlvMuxer.cpp @@ -54,6 +54,9 @@ void FlvMuxer::start(const EventPoller::Ptr &poller, const RtmpMediaSource::Ptr }); bool check = start_pts > 0; + + _ring_reader->setGetInfoCB([weakSelf]() { return weakSelf.lock(); }); + _ring_reader->setReadCB([weakSelf, start_pts, check](const RtmpMediaSource::RingDataType &pkt) mutable { auto strongSelf = weakSelf.lock(); if (!strongSelf) { diff --git a/src/Rtmp/RtmpMediaSource.h b/src/Rtmp/RtmpMediaSource.h index a08b4e49..f92246c8 100644 --- a/src/Rtmp/RtmpMediaSource.h +++ b/src/Rtmp/RtmpMediaSource.h @@ -69,6 +69,11 @@ public: return _ring; } + void getPlayerList(const std::function> &info_list)> &cb, + const std::function(std::shared_ptr &&info)> &on_change) override { + _ring->getInfoList(cb, on_change); + } + /** * 获取播放器个数 * @return diff --git a/src/Rtmp/RtmpSession.cpp b/src/Rtmp/RtmpSession.cpp index 2135fe9c..e69d9391 100644 --- a/src/Rtmp/RtmpSession.cpp +++ b/src/Rtmp/RtmpSession.cpp @@ -308,6 +308,7 @@ void RtmpSession::sendPlayResponse(const string &err, const RtmpMediaSource::Ptr src->pause(false); _ring_reader = src->getRing()->attach(getPoller()); weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); + _ring_reader->setGetInfoCB([weakSelf]() { return weakSelf.lock(); }); _ring_reader->setReadCB([weakSelf](const RtmpMediaSource::RingDataType &pkt) { auto strongSelf = weakSelf.lock(); if (!strongSelf) { diff --git a/src/Rtsp/RtspMediaSource.h b/src/Rtsp/RtspMediaSource.h index 03fdd1b2..69e3f93b 100644 --- a/src/Rtsp/RtspMediaSource.h +++ b/src/Rtsp/RtspMediaSource.h @@ -65,6 +65,11 @@ public: return _ring; } + void getPlayerList(const std::function> &info_list)> &cb, + const std::function(std::shared_ptr &&info)> &on_change) override { + _ring->getInfoList(cb, on_change); + } + /** * 获取播放器个数 */ diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 5d7d675b..f7a2af93 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -836,6 +836,9 @@ void RtspSession::handleReq_Play(const Parser &parser) { if (!_play_reader && _rtp_type != Rtsp::RTP_MULTICAST) { weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); _play_reader = play_src->getRing()->attach(getPoller(), useGOP); + + _play_reader->setGetInfoCB([weakSelf]() { return weakSelf.lock(); }); + _play_reader->setDetachCB([weakSelf]() { auto strongSelf = weakSelf.lock(); if (!strongSelf) { diff --git a/src/TS/TSMediaSource.h b/src/TS/TSMediaSource.h index bbd2f498..101dda9c 100644 --- a/src/TS/TSMediaSource.h +++ b/src/TS/TSMediaSource.h @@ -51,6 +51,11 @@ public: return _ring; } + void getPlayerList(const std::function> &info_list)> &cb, + const std::function(std::shared_ptr &&info)> &on_change) override { + _ring->getInfoList(cb, on_change); + } + /** * 获取播放器个数 */ diff --git a/srt/SrtTransportImp.cpp b/srt/SrtTransportImp.cpp index aebb6cbf..564bc17e 100644 --- a/srt/SrtTransportImp.cpp +++ b/srt/SrtTransportImp.cpp @@ -234,6 +234,8 @@ void SrtTransportImp::doPlay() { } strong_self->onShutdown(SockException(Err_shutdown)); }); + weak_ptr weak_session = strong_self->getSession(); + strong_self->_ts_reader->setGetInfoCB([weak_session]() { return weak_session.lock(); }); strong_self->_ts_reader->setReadCB([weak_self](const TSMediaSource::RingDataType &ts_list) { auto strong_self = weak_self.lock(); if (!strong_self) { diff --git a/webrtc/WebRtcPlayer.cpp b/webrtc/WebRtcPlayer.cpp index 69a595d4..b9a8eb5e 100644 --- a/webrtc/WebRtcPlayer.cpp +++ b/webrtc/WebRtcPlayer.cpp @@ -39,6 +39,8 @@ void WebRtcPlayer::onStartWebRTC() { _play_src->pause(false); _reader = _play_src->getRing()->attach(getPoller(), true); weak_ptr weak_self = static_pointer_cast(shared_from_this()); + weak_ptr weak_session = getSession(); + _reader->setGetInfoCB([weak_session]() { return weak_session.lock(); }); _reader->setReadCB([weak_self](const RtspMediaSource::RingDataType &pkt) { auto strongSelf = weak_self.lock(); if (!strongSelf) {