mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-30 16:27:36 +08:00
修复FFmpeg拉流代理功能缺陷的问题:#533
This commit is contained in:
parent
67e49cb66e
commit
38a002646d
@ -233,7 +233,7 @@ void FFmpegSource::setOnClose(const function<void()> &cb){
|
||||
}
|
||||
|
||||
bool FFmpegSource::close(MediaSource &sender, bool force) {
|
||||
auto listener = _listener.lock();
|
||||
auto listener = getDelegate();
|
||||
if(listener && !listener->close(sender,force)){
|
||||
//关闭失败
|
||||
return false;
|
||||
@ -258,17 +258,11 @@ std::shared_ptr<SockInfo> FFmpegSource::getOriginSock(MediaSource &sender) const
|
||||
}
|
||||
|
||||
void FFmpegSource::onGetMediaSource(const MediaSource::Ptr &src) {
|
||||
auto listener = src->getListener();
|
||||
auto listener = src->getListener(true);
|
||||
if (listener.lock().get() != this) {
|
||||
//防止多次进入onGetMediaSource函数导致无效递归调用的bug
|
||||
_listener = listener;
|
||||
//防止多次进入onGetMediaSource函数导致无限递归调用的bug
|
||||
setDelegate(listener);
|
||||
src->setListener(shared_from_this());
|
||||
} else {
|
||||
WarnL << "多次触发onGetMediaSource事件:"
|
||||
<< src->getSchema() << "/"
|
||||
<< src->getVhost() << "/"
|
||||
<< src->getApp() << "/"
|
||||
<< src->getId();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,8 +92,19 @@ void MediaSource::setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||
_listener = listener;
|
||||
}
|
||||
|
||||
const std::weak_ptr<MediaSourceEvent>& MediaSource::getListener() const{
|
||||
std::weak_ptr<MediaSourceEvent> MediaSource::getListener(bool next) const{
|
||||
if (!next) {
|
||||
return _listener;
|
||||
}
|
||||
auto listener = dynamic_pointer_cast<MediaSourceEventInterceptor>(_listener.lock());
|
||||
if (!listener) {
|
||||
//不是MediaSourceEventInterceptor对象或者对象已经销毁
|
||||
return _listener;
|
||||
}
|
||||
//获取被拦截的对象
|
||||
auto next_obj = listener->getDelegate();
|
||||
//有则返回之
|
||||
return next_obj ? next_obj : _listener;
|
||||
}
|
||||
|
||||
int MediaSource::totalReaderCount(){
|
||||
@ -644,6 +655,17 @@ bool MediaSourceEventInterceptor::stopSendRtp(MediaSource &sender){
|
||||
return false;
|
||||
}
|
||||
|
||||
void MediaSourceEventInterceptor::setDelegate(const std::weak_ptr<MediaSourceEvent> &listener) {
|
||||
if (listener.lock().get() == this) {
|
||||
throw std::invalid_argument("can not set self as a delegate");
|
||||
}
|
||||
_listener = listener;
|
||||
}
|
||||
|
||||
std::shared_ptr<MediaSourceEvent> MediaSourceEventInterceptor::getDelegate() const{
|
||||
return _listener.lock();
|
||||
}
|
||||
|
||||
/////////////////////////////////////FlushPolicy//////////////////////////////////////
|
||||
|
||||
static bool isFlushAble_default(bool is_video, uint64_t last_stamp, uint64_t new_stamp, int cache_size) {
|
||||
|
@ -97,6 +97,9 @@ public:
|
||||
MediaSourceEventInterceptor(){}
|
||||
~MediaSourceEventInterceptor() override {}
|
||||
|
||||
void setDelegate(const std::weak_ptr<MediaSourceEvent> &listener);
|
||||
std::shared_ptr<MediaSourceEvent> getDelegate() const;
|
||||
|
||||
MediaOriginType getOriginType(MediaSource &sender) const override;
|
||||
string getOriginUrl(MediaSource &sender) const override;
|
||||
std::shared_ptr<SockInfo> getOriginSock(MediaSource &sender) const override;
|
||||
@ -112,7 +115,7 @@ public:
|
||||
void startSendRtp(MediaSource &sender, const string &dst_url, uint16_t dst_port, uint32_t ssrc, bool is_udp, const function<void(const SockException &ex)> &cb) override;
|
||||
bool stopSendRtp(MediaSource &sender) override;
|
||||
|
||||
protected:
|
||||
private:
|
||||
std::weak_ptr<MediaSourceEvent> _listener;
|
||||
};
|
||||
|
||||
@ -226,9 +229,9 @@ public:
|
||||
////////////////MediaSourceEvent相关接口实现////////////////
|
||||
|
||||
// 设置监听者
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener);
|
||||
virtual void setListener(const std::weak_ptr<MediaSourceEvent> &listener);
|
||||
// 获取监听者
|
||||
const std::weak_ptr<MediaSourceEvent>& getListener() const;
|
||||
std::weak_ptr<MediaSourceEvent> getListener(bool next = false) const;
|
||||
|
||||
// 本协议获取观看者个数,可能返回本协议的观看人数,也可能返回总人数
|
||||
virtual int readerCount() = 0;
|
||||
|
@ -291,7 +291,7 @@ MultiMediaSourceMuxer::MultiMediaSourceMuxer(const string &vhost, const string &
|
||||
}
|
||||
|
||||
void MultiMediaSourceMuxer::setMediaListener(const std::weak_ptr<MediaSourceEvent> &listener) {
|
||||
_listener = listener;
|
||||
setDelegate(listener);
|
||||
//拦截事件
|
||||
_muxer->setMediaListener(shared_from_this());
|
||||
}
|
||||
@ -313,7 +313,7 @@ vector<Track::Ptr> MultiMediaSourceMuxer::getTracks(MediaSource &sender, bool tr
|
||||
}
|
||||
|
||||
int MultiMediaSourceMuxer::totalReaderCount(MediaSource &sender) {
|
||||
auto listener = _listener.lock();
|
||||
auto listener = getDelegate();
|
||||
if (!listener) {
|
||||
return totalReaderCount();
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
~FMP4MediaSourceMuxer() override = default;
|
||||
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||
_listener = listener;
|
||||
setDelegate(listener);
|
||||
_media_src->setListener(shared_from_this());
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
}
|
||||
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener) {
|
||||
_listener = listener;
|
||||
setDelegate(listener);
|
||||
_hls->getMediaSource()->setListener(shared_from_this());
|
||||
//先注册媒体流,后续可以按需生成
|
||||
_hls->getMediaSource()->registHls(false);
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
_muxer->setMediaListener(getListener());
|
||||
_muxer->setTrackListener(static_pointer_cast<RtmpMediaSourceImp>(shared_from_this()));
|
||||
//让_muxer对象拦截一部分事件(比如说录像相关事件)
|
||||
setListener(_muxer);
|
||||
MediaSource::setListener(_muxer);
|
||||
|
||||
for(auto &track : _demuxer->getTracks(false)){
|
||||
_muxer->addTrack(track);
|
||||
@ -119,6 +119,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置事件监听器
|
||||
* @param listener 监听器
|
||||
*/
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener) override{
|
||||
if (_muxer) {
|
||||
//_muxer对象不能处理的事件再给listener处理
|
||||
_muxer->setMediaListener(listener);
|
||||
} else {
|
||||
//未创建_muxer对象,事件全部给listener处理
|
||||
MediaSource::setListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool _all_track_ready = false;
|
||||
bool _recreate_metadata = false;
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
~RtmpMediaSourceMuxer() override{}
|
||||
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||
_listener = listener;
|
||||
setDelegate(listener);
|
||||
_media_src->setListener(shared_from_this());
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
_muxer->setMediaListener(getListener());
|
||||
_muxer->setTrackListener(static_pointer_cast<RtspMediaSourceImp>(shared_from_this()));
|
||||
//让_muxer对象拦截一部分事件(比如说录像相关事件)
|
||||
setListener(_muxer);
|
||||
MediaSource::setListener(_muxer);
|
||||
|
||||
for(auto &track : _demuxer->getTracks(false)){
|
||||
_muxer->addTrack(track);
|
||||
@ -102,6 +102,20 @@ public:
|
||||
_all_track_ready = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置事件监听器
|
||||
* @param listener 监听器
|
||||
*/
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener) override{
|
||||
if (_muxer) {
|
||||
//_muxer对象不能处理的事件再给listener处理
|
||||
_muxer->setMediaListener(listener);
|
||||
} else {
|
||||
//未创建_muxer对象,事件全部给listener处理
|
||||
MediaSource::setListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
RtspDemuxer::Ptr _demuxer;
|
||||
MultiMediaSourceMuxer::Ptr _muxer;
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
~RtspMediaSourceMuxer() override{}
|
||||
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||
_listener = listener;
|
||||
setDelegate(listener);
|
||||
_media_src->setListener(shared_from_this());
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
~TSMediaSourceMuxer() override = default;
|
||||
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||
_listener = listener;
|
||||
setDelegate(listener);
|
||||
_media_src->setListener(shared_from_this());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user