mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 12:37:09 +08:00
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
This commit is contained in:
parent
350e262433
commit
1136b0a3c0
@ -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(
|
|||||||
_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)
|
|||||||
_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) {
|
|||||||
// 播放成功
|
// 播放成功
|
||||||
*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() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
|||||||
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 @@
|
|||||||
|
|
||||||
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:
|
|||||||
// 默认一直重试
|
// 默认一直重试
|
||||||
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;
|
||||||
|
|
||||||
@ -45,6 +84,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:
|
|||||||
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:
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user