listStreamProxy接口支持返回track、status_str信息

This commit is contained in:
xia-chu 2026-03-13 15:13:18 +08:00
parent 4e170e9281
commit 3b54168b44
3 changed files with 65 additions and 41 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;