2017-10-09 22:11:01 +08:00
|
|
|
|
/*
|
2023-12-09 16:23:51 +08:00
|
|
|
|
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
2017-09-27 16:20:30 +08:00
|
|
|
|
*
|
2023-12-09 16:23:51 +08:00
|
|
|
|
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
2017-09-27 16:20:30 +08:00
|
|
|
|
*
|
2023-12-09 16:23:51 +08:00
|
|
|
|
* Use of this source code is governed by MIT-like license that can be found in the
|
2020-04-04 20:30:09 +08:00
|
|
|
|
* LICENSE file in the root of the source tree. All contributing project authors
|
|
|
|
|
* may be found in the AUTHORS file in the root of the source tree.
|
2017-04-01 16:35:56 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "PlayerProxy.h"
|
2023-05-03 21:46:25 +08:00
|
|
|
|
#include "Common/config.h"
|
2022-11-29 11:07:13 +08:00
|
|
|
|
#include "Rtmp/RtmpMediaSource.h"
|
|
|
|
|
#include "Rtmp/RtmpPlayer.h"
|
2023-05-03 21:46:25 +08:00
|
|
|
|
#include "Rtsp/RtspMediaSource.h"
|
2022-11-29 11:07:13 +08:00
|
|
|
|
#include "Rtsp/RtspPlayer.h"
|
2023-05-03 21:46:25 +08:00
|
|
|
|
#include "Util/MD5.h"
|
|
|
|
|
#include "Util/logger.h"
|
|
|
|
|
#include "Util/mini.h"
|
2017-04-01 16:35:56 +08:00
|
|
|
|
|
2018-10-24 17:17:55 +08:00
|
|
|
|
using namespace toolkit;
|
2022-02-02 20:34:50 +08:00
|
|
|
|
using namespace std;
|
2017-04-01 16:35:56 +08:00
|
|
|
|
|
2018-10-24 17:17:55 +08:00
|
|
|
|
namespace mediakit {
|
2017-04-01 16:35:56 +08:00
|
|
|
|
|
2023-05-03 21:46:25 +08:00
|
|
|
|
PlayerProxy::PlayerProxy(
|
2024-07-14 09:32:41 +08:00
|
|
|
|
const MediaTuple &tuple, const ProtocolOption &option, int retry_count,
|
2023-05-12 11:20:31 +08:00
|
|
|
|
const EventPoller::Ptr &poller, int reconnect_delay_min, int reconnect_delay_max, int reconnect_delay_step)
|
2024-07-14 09:32:41 +08:00
|
|
|
|
: MediaPlayer(poller), _tuple(tuple), _option(option) {
|
2020-08-01 10:22:12 +08:00
|
|
|
|
_retry_count = retry_count;
|
2023-05-03 21:46:25 +08:00
|
|
|
|
|
2023-05-13 00:14:35 +08:00
|
|
|
|
setOnClose(nullptr);
|
2023-05-12 11:20:31 +08:00
|
|
|
|
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;
|
2023-05-03 18:52:11 +08:00
|
|
|
|
_live_secs = 0;
|
|
|
|
|
_live_status = 1;
|
|
|
|
|
_repull_count = 0;
|
2021-11-10 13:56:58 +08:00
|
|
|
|
(*this)[Client::kWaitTrackReady] = false;
|
2017-04-01 16:35:56 +08:00
|
|
|
|
}
|
2019-05-20 18:08:55 +08:00
|
|
|
|
|
2023-05-13 00:14:35 +08:00
|
|
|
|
void PlayerProxy::setPlayCallbackOnce(function<void(const SockException &ex)> cb) {
|
|
|
|
|
_on_play = std::move(cb);
|
2019-05-20 18:08:55 +08:00
|
|
|
|
}
|
2019-05-27 14:14:42 +08:00
|
|
|
|
|
2023-05-13 00:14:35 +08:00
|
|
|
|
void PlayerProxy::setOnClose(function<void(const SockException &ex)> cb) {
|
|
|
|
|
_on_close = cb ? std::move(cb) : [](const SockException &) {};
|
2019-05-27 14:14:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-12 11:20:31 +08:00
|
|
|
|
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()
|
|
|
|
|
{
|
2023-05-13 00:02:06 +08:00
|
|
|
|
_transtalion_info.byte_speed = _media_src ? _media_src->getBytesSpeed() : -1;
|
|
|
|
|
_transtalion_info.start_time_stamp = _media_src ? _media_src->getCreateStamp() : 0;
|
2023-05-12 11:20:31 +08:00
|
|
|
|
_transtalion_info.stream_info.clear();
|
|
|
|
|
auto tracks = _muxer->getTracks();
|
|
|
|
|
for (auto &track : tracks) {
|
2023-11-07 23:36:41 +08:00
|
|
|
|
track->update();
|
2023-05-12 11:20:31 +08:00
|
|
|
|
_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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-09 22:34:22 +08:00
|
|
|
|
static int getMaxTrackSize(const std::string &url) {
|
|
|
|
|
if (url.find(".m3u8") != std::string::npos || url.find(".ts") != std::string::npos) {
|
|
|
|
|
// hls和ts协议才开放多track支持
|
|
|
|
|
return 16;
|
|
|
|
|
}
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-27 18:41:52 +08:00
|
|
|
|
void PlayerProxy::play(const string &strUrlTmp) {
|
2023-12-09 22:34:22 +08:00
|
|
|
|
_option.max_track = getMaxTrackSize(strUrlTmp);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
2023-05-03 21:46:25 +08:00
|
|
|
|
std::shared_ptr<int> piFailedCnt(new int(0)); // 连续播放失败次数
|
2021-06-09 15:01:45 +08:00
|
|
|
|
setOnPlayResult([weakSelf, strUrlTmp, piFailedCnt](const SockException &err) {
|
2020-03-20 11:51:24 +08:00
|
|
|
|
auto strongSelf = weakSelf.lock();
|
2021-06-09 15:01:45 +08:00
|
|
|
|
if (!strongSelf) {
|
2020-03-20 11:51:24 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-20 18:08:55 +08:00
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
if (strongSelf->_on_play) {
|
2020-08-01 10:22:12 +08:00
|
|
|
|
strongSelf->_on_play(err);
|
|
|
|
|
strongSelf->_on_play = nullptr;
|
2019-05-20 18:08:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
if (!err) {
|
2022-03-12 09:44:47 +08:00
|
|
|
|
// 取消定时器,避免hls拉流索引文件因为网络波动失败重连成功后出现循环重试的情况
|
2023-05-03 18:52:11 +08:00
|
|
|
|
strongSelf->_timer.reset();
|
|
|
|
|
strongSelf->_live_ticker.resetTime();
|
|
|
|
|
strongSelf->_live_status = 0;
|
2020-03-20 11:51:24 +08:00
|
|
|
|
// 播放成功
|
2023-05-03 21:46:25 +08:00
|
|
|
|
*piFailedCnt = 0; // 连续播放失败次数清0
|
2020-03-20 11:51:24 +08:00
|
|
|
|
strongSelf->onPlaySuccess();
|
2023-05-12 11:20:31 +08:00
|
|
|
|
strongSelf->setTranslationInfo();
|
|
|
|
|
strongSelf->_on_connect(strongSelf->_transtalion_info);
|
2023-05-03 18:52:11 +08:00
|
|
|
|
|
|
|
|
|
InfoL << "play " << strUrlTmp << " success";
|
2021-06-09 15:01:45 +08:00
|
|
|
|
} else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) {
|
2020-03-20 11:51:24 +08:00
|
|
|
|
// 播放失败,延时重试播放
|
2023-05-12 11:20:31 +08:00
|
|
|
|
strongSelf->_on_disconnect();
|
2021-06-09 15:01:45 +08:00
|
|
|
|
strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++);
|
|
|
|
|
} else {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 达到了最大重试次数,回调关闭
|
2021-06-09 15:01:45 +08:00
|
|
|
|
strongSelf->_on_close(err);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
2021-06-09 15:01:45 +08:00
|
|
|
|
setOnShutdown([weakSelf, strUrlTmp, piFailedCnt](const SockException &err) {
|
2020-03-20 11:51:24 +08:00
|
|
|
|
auto strongSelf = weakSelf.lock();
|
2021-06-09 15:01:45 +08:00
|
|
|
|
if (!strongSelf) {
|
2020-03-20 11:51:24 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
2020-10-24 23:30:25 +08:00
|
|
|
|
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 注销直接拉流代理产生的流:#532
|
2020-10-24 23:30:25 +08:00
|
|
|
|
strongSelf->setMediaSource(nullptr);
|
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
if (strongSelf->_muxer) {
|
2020-09-06 17:54:52 +08:00
|
|
|
|
auto tracks = strongSelf->MediaPlayer::getTracks(false);
|
2021-06-09 15:01:45 +08:00
|
|
|
|
for (auto &track : tracks) {
|
2020-08-01 10:22:12 +08:00
|
|
|
|
track->delDelegate(strongSelf->_muxer.get());
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
2019-10-11 16:51:10 +08:00
|
|
|
|
|
2022-03-12 13:19:21 +08:00
|
|
|
|
GET_CONFIG(bool, reset_when_replay, General::kResetWhenRePlay);
|
|
|
|
|
if (reset_when_replay) {
|
2020-08-01 10:22:12 +08:00
|
|
|
|
strongSelf->_muxer.reset();
|
2020-03-20 11:51:24 +08:00
|
|
|
|
} else {
|
2020-08-01 10:22:12 +08:00
|
|
|
|
strongSelf->_muxer->resetTracks();
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-03 18:52:11 +08:00
|
|
|
|
|
2023-05-03 21:46:25 +08:00
|
|
|
|
if (*piFailedCnt == 0) {
|
2023-05-03 18:52:11 +08:00
|
|
|
|
// 第一次重拉更新时长
|
2023-05-03 21:46:25 +08:00
|
|
|
|
strongSelf->_live_secs += strongSelf->_live_ticker.elapsedTime() / 1000;
|
2023-05-03 18:52:11 +08:00
|
|
|
|
strongSelf->_live_ticker.resetTime();
|
2023-05-03 21:46:25 +08:00
|
|
|
|
TraceL << " live secs " << strongSelf->_live_secs;
|
2023-05-03 18:52:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 播放异常中断,延时重试播放
|
2021-06-09 15:01:45 +08:00
|
|
|
|
if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) {
|
2023-05-03 18:52:11 +08:00
|
|
|
|
strongSelf->_repull_count++;
|
2021-06-09 15:01:45 +08:00
|
|
|
|
strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++);
|
|
|
|
|
} else {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 达到了最大重试次数,回调关闭
|
2021-06-09 15:01:45 +08:00
|
|
|
|
strongSelf->_on_close(err);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
2023-04-24 14:32:34 +08:00
|
|
|
|
try {
|
|
|
|
|
MediaPlayer::play(strUrlTmp);
|
|
|
|
|
} catch (std::exception &ex) {
|
|
|
|
|
ErrorL << ex.what();
|
2023-05-13 00:14:35 +08:00
|
|
|
|
onPlayResult(SockException(Err_other, ex.what()));
|
2023-04-24 14:32:34 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
2020-09-27 11:32:49 +08:00
|
|
|
|
_pull_url = strUrlTmp;
|
2021-01-17 10:22:51 +08:00
|
|
|
|
setDirectProxy();
|
|
|
|
|
}
|
2019-07-19 11:30:39 +08:00
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
void PlayerProxy::setDirectProxy() {
|
2020-03-20 11:51:24 +08:00
|
|
|
|
MediaSource::Ptr mediaSource;
|
2021-01-17 10:22:51 +08:00
|
|
|
|
if (dynamic_pointer_cast<RtspPlayer>(_delegate)) {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// rtsp拉流
|
2021-01-17 10:22:51 +08:00
|
|
|
|
GET_CONFIG(bool, directProxy, Rtsp::kDirectProxy);
|
2024-08-02 21:32:32 +08:00
|
|
|
|
if (directProxy && _option.enable_rtsp) {
|
2023-05-25 16:23:24 +08:00
|
|
|
|
mediaSource = std::make_shared<RtspMediaSource>(_tuple);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
2021-01-17 10:22:51 +08:00
|
|
|
|
} else if (dynamic_pointer_cast<RtmpPlayer>(_delegate)) {
|
2023-12-09 16:23:51 +08:00
|
|
|
|
// rtmp拉流
|
|
|
|
|
GET_CONFIG(bool, directProxy, Rtmp::kDirectProxy);
|
2024-08-02 21:32:32 +08:00
|
|
|
|
if (directProxy && _option.enable_rtmp) {
|
2023-12-09 16:23:51 +08:00
|
|
|
|
mediaSource = std::make_shared<RtmpMediaSource>(_tuple);
|
|
|
|
|
}
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
2021-01-17 10:22:51 +08:00
|
|
|
|
if (mediaSource) {
|
2020-10-24 23:30:06 +08:00
|
|
|
|
setMediaSource(mediaSource);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
2017-04-01 16:35:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PlayerProxy::~PlayerProxy() {
|
2020-03-20 11:51:24 +08:00
|
|
|
|
_timer.reset();
|
2022-04-01 20:59:58 +08:00
|
|
|
|
// 避免析构时, 忘记回调api请求
|
2023-05-03 21:46:25 +08:00
|
|
|
|
if (_on_play) {
|
2023-06-11 22:07:15 +08:00
|
|
|
|
try {
|
|
|
|
|
_on_play(SockException(Err_shutdown, "player proxy close"));
|
|
|
|
|
} catch (std::exception &ex) {
|
|
|
|
|
WarnL << "Exception occurred: " << ex.what();
|
|
|
|
|
}
|
2022-04-01 20:59:58 +08:00
|
|
|
|
_on_play = nullptr;
|
|
|
|
|
}
|
2017-04-01 16:35:56 +08:00
|
|
|
|
}
|
2020-08-01 10:22:12 +08:00
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
void PlayerProxy::rePlay(const string &strUrl, int iFailedCnt) {
|
2023-05-12 11:20:31 +08:00
|
|
|
|
auto iDelay = MAX(_reconnect_delay_min * 1000, MIN(iFailedCnt * _reconnect_delay_step * 1000, _reconnect_delay_max * 1000));
|
2020-03-20 11:51:24 +08:00
|
|
|
|
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
2023-05-03 21:46:25 +08:00
|
|
|
|
_timer = std::make_shared<Timer>(
|
|
|
|
|
iDelay / 1000.0f,
|
|
|
|
|
[weakSelf, strUrl, iFailedCnt]() {
|
|
|
|
|
// 播放失败次数越多,则延时越长
|
|
|
|
|
auto strongPlayer = weakSelf.lock();
|
|
|
|
|
if (!strongPlayer) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
WarnL << "重试播放[" << iFailedCnt << "]:" << strUrl;
|
|
|
|
|
strongPlayer->MediaPlayer::play(strUrl);
|
|
|
|
|
strongPlayer->setDirectProxy();
|
2020-03-20 11:51:24 +08:00
|
|
|
|
return false;
|
2023-05-03 21:46:25 +08:00
|
|
|
|
},
|
|
|
|
|
getPoller());
|
2017-04-01 16:35:56 +08:00
|
|
|
|
}
|
2019-07-19 11:30:39 +08:00
|
|
|
|
|
2022-09-18 20:36:47 +08:00
|
|
|
|
bool PlayerProxy::close(MediaSource &sender) {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 通知其停止推流
|
2020-08-01 10:22:12 +08:00
|
|
|
|
weak_ptr<PlayerProxy> weakSelf = dynamic_pointer_cast<PlayerProxy>(shared_from_this());
|
|
|
|
|
getPoller()->async_first([weakSelf]() {
|
|
|
|
|
auto strongSelf = weakSelf.lock();
|
|
|
|
|
if (!strongSelf) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
strongSelf->_muxer.reset();
|
2020-10-24 23:30:06 +08:00
|
|
|
|
strongSelf->setMediaSource(nullptr);
|
2020-08-01 10:22:12 +08:00
|
|
|
|
strongSelf->teardown();
|
2020-03-20 11:51:24 +08:00
|
|
|
|
});
|
2021-06-09 15:01:45 +08:00
|
|
|
|
_on_close(SockException(Err_shutdown, "closed by user"));
|
2022-09-18 20:36:47 +08:00
|
|
|
|
WarnL << "close media: " << sender.getUrl();
|
2018-02-08 17:24:42 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2017-04-01 16:35:56 +08:00
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
int PlayerProxy::totalReaderCount() {
|
2021-11-10 10:58:43 +08:00
|
|
|
|
return (_muxer ? _muxer->totalReaderCount() : 0) + (_media_src ? _media_src->readerCount() : 0);
|
2019-12-28 16:48:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int PlayerProxy::totalReaderCount(MediaSource &sender) {
|
2020-03-20 11:51:24 +08:00
|
|
|
|
return totalReaderCount();
|
2019-12-28 16:48:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
MediaOriginType PlayerProxy::getOriginType(MediaSource &sender) const {
|
2020-09-27 11:32:49 +08:00
|
|
|
|
return MediaOriginType::pull;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
string PlayerProxy::getOriginUrl(MediaSource &sender) const {
|
2020-09-27 11:32:49 +08:00
|
|
|
|
return _pull_url;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-09 15:01:45 +08:00
|
|
|
|
std::shared_ptr<SockInfo> PlayerProxy::getOriginSock(MediaSource &sender) const {
|
2020-09-27 11:32:49 +08:00
|
|
|
|
return getSockInfo();
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-03 15:53:01 +08:00
|
|
|
|
float PlayerProxy::getLossRate(MediaSource &sender, TrackType type) {
|
|
|
|
|
return getPacketLossRate(type);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-12 11:20:31 +08:00
|
|
|
|
TranslationInfo PlayerProxy::getTranslationInfo() {
|
|
|
|
|
return _transtalion_info;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-26 17:14:39 +08:00
|
|
|
|
void PlayerProxy::onPlaySuccess() {
|
2022-03-12 13:19:21 +08:00
|
|
|
|
GET_CONFIG(bool, reset_when_replay, General::kResetWhenRePlay);
|
2021-11-10 10:58:43 +08:00
|
|
|
|
if (dynamic_pointer_cast<RtspMediaSource>(_media_src)) {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// rtsp拉流代理
|
2022-03-12 13:19:21 +08:00
|
|
|
|
if (reset_when_replay || !_muxer) {
|
|
|
|
|
_option.enable_rtsp = false;
|
2023-05-25 16:23:24 +08:00
|
|
|
|
_muxer = std::make_shared<MultiMediaSourceMuxer>(_tuple, getDuration(), _option);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
2021-11-10 10:58:43 +08:00
|
|
|
|
} else if (dynamic_pointer_cast<RtmpMediaSource>(_media_src)) {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// rtmp拉流代理
|
2022-03-12 13:19:21 +08:00
|
|
|
|
if (reset_when_replay || !_muxer) {
|
|
|
|
|
_option.enable_rtmp = false;
|
2023-05-25 16:23:24 +08:00
|
|
|
|
_muxer = std::make_shared<MultiMediaSourceMuxer>(_tuple, getDuration(), _option);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 其他拉流代理
|
2022-03-12 13:19:21 +08:00
|
|
|
|
if (reset_when_replay || !_muxer) {
|
2023-05-25 16:23:24 +08:00
|
|
|
|
_muxer = std::make_shared<MultiMediaSourceMuxer>(_tuple, getDuration(), _option);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-01 10:22:12 +08:00
|
|
|
|
_muxer->setMediaListener(shared_from_this());
|
2018-10-26 17:14:39 +08:00
|
|
|
|
|
2020-08-01 10:22:12 +08:00
|
|
|
|
auto videoTrack = getTrack(TrackVideo, false);
|
|
|
|
|
if (videoTrack) {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 添加视频
|
2020-08-01 10:22:12 +08:00
|
|
|
|
_muxer->addTrack(videoTrack);
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 视频数据写入_mediaMuxer
|
2020-08-01 10:22:12 +08:00
|
|
|
|
videoTrack->addDelegate(_muxer);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
2018-10-26 17:14:39 +08:00
|
|
|
|
|
2020-03-20 11:51:24 +08:00
|
|
|
|
auto audioTrack = getTrack(TrackAudio, false);
|
2020-08-01 10:22:12 +08:00
|
|
|
|
if (audioTrack) {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 添加音频
|
2020-08-01 10:22:12 +08:00
|
|
|
|
_muxer->addTrack(audioTrack);
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 音频数据写入_mediaMuxer
|
2020-08-01 10:22:12 +08:00
|
|
|
|
audioTrack->addDelegate(_muxer);
|
2020-03-20 11:51:24 +08:00
|
|
|
|
}
|
2019-12-17 09:05:34 +08:00
|
|
|
|
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 添加完毕所有track,防止单track情况下最大等待3秒
|
2020-08-01 10:22:12 +08:00
|
|
|
|
_muxer->addTrackCompleted();
|
2020-02-25 14:59:40 +08:00
|
|
|
|
|
2021-11-10 10:58:43 +08:00
|
|
|
|
if (_media_src) {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
// 让_muxer对象拦截一部分事件(比如说录像相关事件)
|
2021-11-10 10:58:43 +08:00
|
|
|
|
_media_src->setListener(_muxer);
|
2019-12-17 09:05:34 +08:00
|
|
|
|
}
|
2018-06-30 23:02:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-03 18:52:11 +08:00
|
|
|
|
int PlayerProxy::getStatus() {
|
|
|
|
|
return _live_status.load();
|
|
|
|
|
}
|
|
|
|
|
uint64_t PlayerProxy::getLiveSecs() {
|
2023-05-03 21:46:25 +08:00
|
|
|
|
if (_live_status == 0) {
|
|
|
|
|
return _live_secs + _live_ticker.elapsedTime() / 1000;
|
2023-05-03 18:52:11 +08:00
|
|
|
|
}
|
2023-05-13 00:14:35 +08:00
|
|
|
|
return _live_secs;
|
2023-05-03 18:52:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-03 21:46:25 +08:00
|
|
|
|
uint64_t PlayerProxy::getRePullCount() {
|
2023-05-03 18:52:11 +08:00
|
|
|
|
return _repull_count;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-24 17:17:55 +08:00
|
|
|
|
} /* namespace mediakit */
|