mirror of
https://gitee.com/xia-chu/ZLMediaKit.git
synced 2026-05-06 10:57:50 +08:00
listStreamProxy接口支持返回track、status_str信息
This commit is contained in:
parent
4e170e9281
commit
3b54168b44
@ -379,10 +379,53 @@ Value ToJson(const PusherProxy::Ptr& p) {
|
||||
return item;
|
||||
}
|
||||
|
||||
Json::Value dumpTracks(const std::vector<Track::Ptr> &tracks) {
|
||||
Json::Value ret(arrayValue);
|
||||
for (auto &track : tracks) {
|
||||
Value obj;
|
||||
auto codec_type = track->getTrackType();
|
||||
obj["codec_id"] = track->getCodecId();
|
||||
obj["codec_id_name"] = track->getCodecName();
|
||||
obj["ready"] = track->ready();
|
||||
obj["codec_type"] = codec_type;
|
||||
obj["frames"] = track->getFrames();
|
||||
obj["duration"] = track->getDuration();
|
||||
switch (codec_type) {
|
||||
case TrackAudio: {
|
||||
auto audio_track = dynamic_pointer_cast<AudioTrack>(track);
|
||||
obj["sample_rate"] = audio_track->getAudioSampleRate();
|
||||
obj["channels"] = audio_track->getAudioChannel();
|
||||
obj["sample_bit"] = audio_track->getAudioSampleBit();
|
||||
break;
|
||||
}
|
||||
case TrackVideo: {
|
||||
auto video_track = dynamic_pointer_cast<VideoTrack>(track);
|
||||
obj["width"] = video_track->getVideoWidth();
|
||||
obj["height"] = video_track->getVideoHeight();
|
||||
obj["key_frames"] = video_track->getVideoKeyFrames();
|
||||
int gop_size = video_track->getVideoGopSize();
|
||||
int gop_interval_ms = video_track->getVideoGopInterval();
|
||||
float fps = video_track->getVideoFps();
|
||||
if (fps <= 1 && gop_interval_ms) {
|
||||
fps = gop_size * 1000.0 / gop_interval_ms;
|
||||
}
|
||||
obj["fps"] = round(fps);
|
||||
obj["gop_size"] = gop_size;
|
||||
obj["gop_interval_ms"] = gop_interval_ms;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
ret.append(obj);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Value ToJson(const PlayerProxy::Ptr& p) {
|
||||
Value item;
|
||||
item["url"] = p->getUrl();
|
||||
item["status"] = p->getStatus();
|
||||
item["status_str"] = p->getStatusStr();
|
||||
item["liveSecs"] = p->getLiveSecs();
|
||||
item["rePullCount"] = p->getRePullCount();
|
||||
item["totalReaderCount"] = p->totalReaderCount();
|
||||
@ -390,10 +433,11 @@ Value ToJson(const PlayerProxy::Ptr& p) {
|
||||
item["totalBytes"] = (Json::UInt64) p->getRecvTotalBytes();
|
||||
|
||||
dumpMediaTuple(p->getMediaTuple(), item["src"]);
|
||||
item["tracks"] = dumpTracks(p->getTracks(false));
|
||||
return item;
|
||||
}
|
||||
|
||||
Value makeMediaSourceJson(MediaSource &media){
|
||||
Value makeMediaSourceJson(MediaSource &media) {
|
||||
Value item;
|
||||
item["schema"] = media.getSchema();
|
||||
dumpMediaTuple(media.getMediaTuple(), item);
|
||||
@ -421,17 +465,13 @@ Value makeMediaSourceJson(MediaSource &media){
|
||||
auto current_thread = false;
|
||||
try { current_thread = media.getOwnerPoller()->isCurrentThread();} catch (...) {}
|
||||
float last_loss = -1;
|
||||
for(auto &track : media.getTracks(false)){
|
||||
Value obj;
|
||||
auto codec_type = track->getTrackType();
|
||||
obj["codec_id"] = track->getCodecId();
|
||||
obj["codec_id_name"] = track->getCodecName();
|
||||
obj["ready"] = track->ready();
|
||||
obj["codec_type"] = codec_type;
|
||||
if (current_thread) {
|
||||
auto tracks = dumpTracks(media.getTracks(false));
|
||||
if (current_thread) {
|
||||
for (auto &obj : tracks) {
|
||||
// rtp推流只有一个统计器,但是可能有多个track,如果短时间多次获取间隔丢包率,第二次会获取为-1 [AUTO-TRANSLATED:5bfbc951]
|
||||
// RTP push stream has only one statistics, but may have multiple tracks. If you get the interval packet loss rate multiple times in a short time, the second time will get -1
|
||||
auto loss = media.getLossRate(codec_type);
|
||||
// RTP push stream has only one statistics, but may have multiple tracks. If you get the interval packet loss rate multiple times in a short time,
|
||||
// the second time will get -1
|
||||
auto loss = media.getLossRate(getTrackType(static_cast<CodecId>(obj["codec_type"].asInt())));
|
||||
if (loss == -1) {
|
||||
loss = last_loss;
|
||||
} else {
|
||||
@ -439,37 +479,8 @@ Value makeMediaSourceJson(MediaSource &media){
|
||||
}
|
||||
obj["loss"] = loss;
|
||||
}
|
||||
obj["frames"] = track->getFrames();
|
||||
obj["duration"] = track->getDuration();
|
||||
switch(codec_type){
|
||||
case TrackAudio : {
|
||||
auto audio_track = dynamic_pointer_cast<AudioTrack>(track);
|
||||
obj["sample_rate"] = audio_track->getAudioSampleRate();
|
||||
obj["channels"] = audio_track->getAudioChannel();
|
||||
obj["sample_bit"] = audio_track->getAudioSampleBit();
|
||||
break;
|
||||
}
|
||||
case TrackVideo : {
|
||||
auto video_track = dynamic_pointer_cast<VideoTrack>(track);
|
||||
obj["width"] = video_track->getVideoWidth();
|
||||
obj["height"] = video_track->getVideoHeight();
|
||||
obj["key_frames"] = video_track->getVideoKeyFrames();
|
||||
int gop_size = video_track->getVideoGopSize();
|
||||
int gop_interval_ms = video_track->getVideoGopInterval();
|
||||
float fps = video_track->getVideoFps();
|
||||
if (fps <= 1 && gop_interval_ms) {
|
||||
fps = gop_size * 1000.0 / gop_interval_ms;
|
||||
}
|
||||
obj["fps"] = round(fps);
|
||||
obj["gop_size"] = gop_size;
|
||||
obj["gop_interval_ms"] = gop_interval_ms;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
item["tracks"].append(obj);
|
||||
}
|
||||
item["tracks"] = std::move(tracks);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
@ -110,6 +110,7 @@ void PlayerProxy::play(const string &strUrlTmp) {
|
||||
}
|
||||
if (err) {
|
||||
NOTICE_EMIT(BroadcastPlayerProxyFailedArgs, Broadcast::kBroadcastPlayerProxyFailed, *strongSelf, err);
|
||||
strongSelf->_status = std::make_shared<std::string>(std::string("play failed: ") + err.what());
|
||||
}
|
||||
if (strongSelf->_on_play) {
|
||||
strongSelf->_on_play(err);
|
||||
@ -131,6 +132,7 @@ void PlayerProxy::play(const string &strUrlTmp) {
|
||||
strongSelf->_on_connect(strongSelf->_transtalion_info);
|
||||
|
||||
InfoL << "play " << strUrlTmp << " success";
|
||||
strongSelf->_status = std::make_shared<std::string>("playing");
|
||||
} else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) {
|
||||
// 播放失败,延时重试播放 [AUTO-TRANSLATED:d7537c9c]
|
||||
// Play failed, retry playing with delay
|
||||
@ -154,6 +156,7 @@ void PlayerProxy::play(const string &strUrlTmp) {
|
||||
strongSelf->_on_play(err);
|
||||
strongSelf->_on_play = nullptr;
|
||||
}
|
||||
strongSelf->_status = std::make_shared<std::string>(std::string("play shutdown: ") + err.what());
|
||||
|
||||
// 注销直接拉流代理产生的流:#532 [AUTO-TRANSLATED:c6343a3b]
|
||||
// Unregister the stream generated by the direct stream proxy: #532
|
||||
@ -193,8 +196,10 @@ void PlayerProxy::play(const string &strUrlTmp) {
|
||||
}
|
||||
});
|
||||
try {
|
||||
_status = std::make_shared<std::string>("connecting");
|
||||
MediaPlayer::play(strUrlTmp);
|
||||
} catch (std::exception &ex) {
|
||||
_status = std::make_shared<std::string>(std::string("play failed: ") + ex.what());
|
||||
ErrorL << ex.what();
|
||||
onPlayResult(SockException(Err_other, ex.what()));
|
||||
return;
|
||||
@ -365,6 +370,12 @@ void PlayerProxy::onPlaySuccess() {
|
||||
int PlayerProxy::getStatus() {
|
||||
return _live_status.load();
|
||||
}
|
||||
|
||||
std::string PlayerProxy::getStatusStr() const {
|
||||
auto status = _status;
|
||||
return status ? *status : "unknown";
|
||||
}
|
||||
|
||||
uint64_t PlayerProxy::getLiveSecs() {
|
||||
if (_live_status == 0) {
|
||||
return _live_secs + _live_ticker.elapsedTime() / 1000;
|
||||
|
||||
@ -129,6 +129,7 @@ public:
|
||||
int totalReaderCount();
|
||||
|
||||
int getStatus();
|
||||
std::string getStatusStr() const;
|
||||
uint64_t getLiveSecs();
|
||||
uint64_t getRePullCount();
|
||||
|
||||
@ -155,6 +156,7 @@ private:
|
||||
void setTranslationInfo();
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::string> _status;
|
||||
int _retry_count;
|
||||
int _reconnect_delay_min;
|
||||
int _reconnect_delay_max;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user