diff --git a/src/Player/PlayerProxy.cpp b/src/Player/PlayerProxy.cpp index b2b567ff..289c7249 100644 --- a/src/Player/PlayerProxy.cpp +++ b/src/Player/PlayerProxy.cpp @@ -25,7 +25,8 @@ using namespace std; namespace mediakit { PlayerProxy::PlayerProxy( - const string &vhost, const string &app, const string &stream_id, const ProtocolOption &option, int retry_count, const EventPoller::Ptr &poller) + const string &vhost, const string &app, const string &stream_id, const ProtocolOption &option, int retry_count, + const EventPoller::Ptr &poller, int reconnect_delay_min, int reconnect_delay_max, int reconnect_delay_step) : MediaPlayer(poller) , _option(option) { _vhost = vhost; @@ -33,6 +34,12 @@ PlayerProxy::PlayerProxy( _stream_id = stream_id; _retry_count = retry_count; + setOnConnect(nullptr); + setOnDisconnect(nullptr); + + _reconnect_delay_min = reconnect_delay_min > 0 ? reconnect_delay_min : 2; + _reconnect_delay_max = reconnect_delay_max > 0 ? reconnect_delay_max : 60; + _reconnect_delay_step = reconnect_delay_step > 0 ? reconnect_delay_step : 3; _live_secs = 0; _live_status = 1; _repull_count = 0; @@ -48,6 +55,47 @@ void PlayerProxy::setOnClose(const function &cb) _on_close = cb ? cb : [](const SockException &) {}; } +void PlayerProxy::setOnDisconnect(std::function cb) { + _on_disconnect = cb ? std::move(cb) : [] () {}; +} + +void PlayerProxy::setOnConnect(std::function cb) { + _on_connect = cb ? std::move(cb) : [](const TranslationInfo&) {}; +} + +void PlayerProxy::setTranslationInfo() +{ + _transtalion_info.byte_speed = _media_src->getBytesSpeed(); + _transtalion_info.start_time_stamp = _media_src->getCreateStamp(); + _transtalion_info.stream_info.clear(); + auto tracks = _muxer->getTracks(); + for (auto &track : tracks) { + _transtalion_info.stream_info.emplace_back(); + auto &back = _transtalion_info.stream_info.back(); + back.bitrate = track->getBitRate(); + back.codec_type = track->getTrackType(); + back.codec_name = track->getCodecName(); + switch (back.codec_type) { + case TrackAudio : { + auto audio_track = dynamic_pointer_cast(track); + back.audio_sample_rate = audio_track->getAudioSampleRate(); + back.audio_channel = audio_track->getAudioChannel(); + back.audio_sample_bit = audio_track->getAudioSampleBit(); + break; + } + case TrackVideo : { + auto video_track = dynamic_pointer_cast(track); + back.video_width = video_track->getVideoWidth(); + back.video_height = video_track->getVideoHeight(); + back.video_fps = video_track->getVideoFps(); + break; + } + default: + break; + } + } +} + void PlayerProxy::play(const string &strUrlTmp) { weak_ptr weakSelf = shared_from_this(); std::shared_ptr piFailedCnt(new int(0)); // 连续播放失败次数 @@ -70,10 +118,13 @@ void PlayerProxy::play(const string &strUrlTmp) { // 播放成功 *piFailedCnt = 0; // 连续播放失败次数清0 strongSelf->onPlaySuccess(); + strongSelf->setTranslationInfo(); + strongSelf->_on_connect(strongSelf->_transtalion_info); InfoL << "play " << strUrlTmp << " success"; } else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { // 播放失败,延时重试播放 + strongSelf->_on_disconnect(); strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++); } else { // 达到了最大重试次数,回调关闭 @@ -157,7 +208,7 @@ PlayerProxy::~PlayerProxy() { } void PlayerProxy::rePlay(const string &strUrl, int iFailedCnt) { - auto iDelay = MAX(2 * 1000, MIN(iFailedCnt * 3000, 60 * 1000)); + auto iDelay = MAX(_reconnect_delay_min * 1000, MIN(iFailedCnt * _reconnect_delay_step * 1000, _reconnect_delay_max * 1000)); weak_ptr weakSelf = shared_from_this(); _timer = std::make_shared( iDelay / 1000.0f, @@ -216,6 +267,10 @@ float PlayerProxy::getLossRate(MediaSource &sender, TrackType type) { return getPacketLossRate(type); } +TranslationInfo PlayerProxy::getTranslationInfo() { + return _transtalion_info; +} + void PlayerProxy::onPlaySuccess() { GET_CONFIG(bool, reset_when_replay, General::kResetWhenRePlay); if (dynamic_pointer_cast(_media_src)) { diff --git a/src/Player/PlayerProxy.h b/src/Player/PlayerProxy.h index d828f696..1ed625c6 100644 --- a/src/Player/PlayerProxy.h +++ b/src/Player/PlayerProxy.h @@ -18,6 +18,45 @@ namespace mediakit { +struct StreamInfo +{ + TrackType codec_type; + std::string codec_name; + int bitrate; + int audio_sample_rate; + int audio_sample_bit; + int audio_channel; + int video_width; + int video_height; + float video_fps; + + StreamInfo() + { + codec_type = TrackInvalid; + codec_name = "none"; + bitrate = -1; + audio_sample_rate = -1; + audio_channel = -1; + audio_sample_bit = -1; + video_height = -1; + video_width = -1; + video_fps = -1.0; + } +}; + +struct TranslationInfo +{ + std::vector stream_info; + int byte_speed; + uint64_t start_time_stamp; + + TranslationInfo() + { + byte_speed = -1; + start_time_stamp = 0; + } +}; + class PlayerProxy : public MediaPlayer , public MediaSourceEvent @@ -29,7 +68,7 @@ public: // 默认一直重试 PlayerProxy( const std::string &vhost, const std::string &app, const std::string &stream_id, const ProtocolOption &option, int retry_count = -1, - const toolkit::EventPoller::Ptr &poller = nullptr); + const toolkit::EventPoller::Ptr &poller = nullptr, int reconnect_delay_min = 2, int reconnect_delay_max = 60, int reconnect_delay_step = 3); ~PlayerProxy() override; @@ -45,6 +84,18 @@ public: */ void setOnClose(const std::function &cb); + /** + * Set a callback for failed server connection + * @param cb 回调对象 + */ + void setOnDisconnect(std::function cb); + + /** + * Set a callback for a successful connection to the server + * @param cb 回调对象 + */ + void setOnConnect(std::function cb); + /** * 开始拉流播放 * @param strUrl @@ -60,6 +111,9 @@ public: uint64_t getLiveSecs(); uint64_t getRePullCount(); + // Using this only makes sense after a successful connection to the server + TranslationInfo getTranslationInfo(); + private: // MediaSourceEvent override bool close(MediaSource &sender) override; @@ -72,17 +126,24 @@ private: void rePlay(const std::string &strUrl, int iFailedCnt); void onPlaySuccess(); void setDirectProxy(); + void setTranslationInfo(); private: ProtocolOption _option; int _retry_count; + int _reconnect_delay_min; + int _reconnect_delay_max; + int _reconnect_delay_step; std::string _vhost; std::string _app; std::string _stream_id; std::string _pull_url; toolkit::Timer::Ptr _timer; + std::function _on_disconnect; + std::function _on_connect; std::function _on_close; std::function _on_play; + TranslationInfo _transtalion_info; MultiMediaSourceMuxer::Ptr _muxer; toolkit::Ticker _live_ticker;