Commit 1136b0a3 by codeRATny Committed by GitHub

Adding new features for proxy player (#2448)

Add some functions for the proxy player, such as:
getting stream information (basic video/audio information)
callbacks for any connection and disconnection from the server
And now you can set delay between reconnections. See proxy player
constructor
parent 350e2624
...@@ -25,7 +25,8 @@ using namespace std; ...@@ -25,7 +25,8 @@ using namespace std;
namespace mediakit { namespace mediakit {
PlayerProxy::PlayerProxy( 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) : MediaPlayer(poller)
, _option(option) { , _option(option) {
_vhost = vhost; _vhost = vhost;
...@@ -33,6 +34,12 @@ PlayerProxy::PlayerProxy( ...@@ -33,6 +34,12 @@ PlayerProxy::PlayerProxy(
_stream_id = stream_id; _stream_id = stream_id;
_retry_count = retry_count; _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_secs = 0;
_live_status = 1; _live_status = 1;
_repull_count = 0; _repull_count = 0;
...@@ -48,6 +55,47 @@ void PlayerProxy::setOnClose(const function<void(const SockException &ex)> &cb) ...@@ -48,6 +55,47 @@ void PlayerProxy::setOnClose(const function<void(const SockException &ex)> &cb)
_on_close = cb ? cb : [](const SockException &) {}; _on_close = cb ? cb : [](const SockException &) {};
} }
void PlayerProxy::setOnDisconnect(std::function<void()> cb) {
_on_disconnect = cb ? std::move(cb) : [] () {};
}
void PlayerProxy::setOnConnect(std::function<void(const TranslationInfo&)> 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<AudioTrack>(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<VideoTrack>(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) { void PlayerProxy::play(const string &strUrlTmp) {
weak_ptr<PlayerProxy> weakSelf = shared_from_this(); weak_ptr<PlayerProxy> weakSelf = shared_from_this();
std::shared_ptr<int> piFailedCnt(new int(0)); // 连续播放失败次数 std::shared_ptr<int> piFailedCnt(new int(0)); // 连续播放失败次数
...@@ -70,10 +118,13 @@ void PlayerProxy::play(const string &strUrlTmp) { ...@@ -70,10 +118,13 @@ void PlayerProxy::play(const string &strUrlTmp) {
// 播放成功 // 播放成功
*piFailedCnt = 0; // 连续播放失败次数清0 *piFailedCnt = 0; // 连续播放失败次数清0
strongSelf->onPlaySuccess(); strongSelf->onPlaySuccess();
strongSelf->setTranslationInfo();
strongSelf->_on_connect(strongSelf->_transtalion_info);
InfoL << "play " << strUrlTmp << " success"; InfoL << "play " << strUrlTmp << " success";
} else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { } else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) {
// 播放失败,延时重试播放 // 播放失败,延时重试播放
strongSelf->_on_disconnect();
strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++); strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++);
} else { } else {
// 达到了最大重试次数,回调关闭 // 达到了最大重试次数,回调关闭
...@@ -157,7 +208,7 @@ PlayerProxy::~PlayerProxy() { ...@@ -157,7 +208,7 @@ PlayerProxy::~PlayerProxy() {
} }
void PlayerProxy::rePlay(const string &strUrl, int iFailedCnt) { 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<PlayerProxy> weakSelf = shared_from_this(); weak_ptr<PlayerProxy> weakSelf = shared_from_this();
_timer = std::make_shared<Timer>( _timer = std::make_shared<Timer>(
iDelay / 1000.0f, iDelay / 1000.0f,
...@@ -216,6 +267,10 @@ float PlayerProxy::getLossRate(MediaSource &sender, TrackType type) { ...@@ -216,6 +267,10 @@ float PlayerProxy::getLossRate(MediaSource &sender, TrackType type) {
return getPacketLossRate(type); return getPacketLossRate(type);
} }
TranslationInfo PlayerProxy::getTranslationInfo() {
return _transtalion_info;
}
void PlayerProxy::onPlaySuccess() { void PlayerProxy::onPlaySuccess() {
GET_CONFIG(bool, reset_when_replay, General::kResetWhenRePlay); GET_CONFIG(bool, reset_when_replay, General::kResetWhenRePlay);
if (dynamic_pointer_cast<RtspMediaSource>(_media_src)) { if (dynamic_pointer_cast<RtspMediaSource>(_media_src)) {
......
...@@ -18,6 +18,45 @@ ...@@ -18,6 +18,45 @@
namespace mediakit { 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<StreamInfo> stream_info;
int byte_speed;
uint64_t start_time_stamp;
TranslationInfo()
{
byte_speed = -1;
start_time_stamp = 0;
}
};
class PlayerProxy class PlayerProxy
: public MediaPlayer : public MediaPlayer
, public MediaSourceEvent , public MediaSourceEvent
...@@ -29,7 +68,7 @@ public: ...@@ -29,7 +68,7 @@ public:
// 默认一直重试 // 默认一直重试
PlayerProxy( PlayerProxy(
const std::string &vhost, const std::string &app, const std::string &stream_id, const ProtocolOption &option, int retry_count = -1, 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; ~PlayerProxy() override;
...@@ -46,6 +85,18 @@ public: ...@@ -46,6 +85,18 @@ public:
void setOnClose(const std::function<void(const toolkit::SockException &ex)> &cb); void setOnClose(const std::function<void(const toolkit::SockException &ex)> &cb);
/** /**
* Set a callback for failed server connection
* @param cb 回调对象
*/
void setOnDisconnect(std::function<void()> cb);
/**
* Set a callback for a successful connection to the server
* @param cb 回调对象
*/
void setOnConnect(std::function<void(const TranslationInfo&)> cb);
/**
* 开始拉流播放 * 开始拉流播放
* @param strUrl * @param strUrl
*/ */
...@@ -60,6 +111,9 @@ public: ...@@ -60,6 +111,9 @@ public:
uint64_t getLiveSecs(); uint64_t getLiveSecs();
uint64_t getRePullCount(); uint64_t getRePullCount();
// Using this only makes sense after a successful connection to the server
TranslationInfo getTranslationInfo();
private: private:
// MediaSourceEvent override // MediaSourceEvent override
bool close(MediaSource &sender) override; bool close(MediaSource &sender) override;
...@@ -72,17 +126,24 @@ private: ...@@ -72,17 +126,24 @@ private:
void rePlay(const std::string &strUrl, int iFailedCnt); void rePlay(const std::string &strUrl, int iFailedCnt);
void onPlaySuccess(); void onPlaySuccess();
void setDirectProxy(); void setDirectProxy();
void setTranslationInfo();
private: private:
ProtocolOption _option; ProtocolOption _option;
int _retry_count; int _retry_count;
int _reconnect_delay_min;
int _reconnect_delay_max;
int _reconnect_delay_step;
std::string _vhost; std::string _vhost;
std::string _app; std::string _app;
std::string _stream_id; std::string _stream_id;
std::string _pull_url; std::string _pull_url;
toolkit::Timer::Ptr _timer; toolkit::Timer::Ptr _timer;
std::function<void()> _on_disconnect;
std::function<void(const TranslationInfo &info)> _on_connect;
std::function<void(const toolkit::SockException &ex)> _on_close; std::function<void(const toolkit::SockException &ex)> _on_close;
std::function<void(const toolkit::SockException &ex)> _on_play; std::function<void(const toolkit::SockException &ex)> _on_play;
TranslationInfo _transtalion_info;
MultiMediaSourceMuxer::Ptr _muxer; MultiMediaSourceMuxer::Ptr _muxer;
toolkit::Ticker _live_ticker; toolkit::Ticker _live_ticker;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论