修复MediaSource::close线程安全问题

主动或无人观看关闭流可能会由于线程安全问题导致崩溃
This commit is contained in:
xia-chu
2025-09-09 21:59:43 +08:00
parent c89caf560a
commit 5686027fc2
9 changed files with 23 additions and 49 deletions

View File

@@ -698,13 +698,13 @@ void MediaSourceEvent::onReaderChanged(MediaSource &sender, int size){
// 此流被标记为无人观看自动关闭流 [AUTO-TRANSLATED:64a0dac3]
// This stream is marked as an automatically closed stream with no viewers.
WarnL << "Auto close stream when none reader: " << strong_sender->getUrl();
strong_sender->close(false);
strong_sender->getOwnerPoller()->async([strong_sender]() { strong_sender->close(false); });
}
} else {
// 这个是mp4点播我们自动关闭 [AUTO-TRANSLATED:8a7b9a90]
// This is an mp4 on-demand, we automatically close it.
WarnL << "MP4点播无人观看,自动关闭:" << strong_sender->getUrl();
strong_sender->close(false);
strong_sender->getOwnerPoller()->async([strong_sender]() { strong_sender->close(false); });
}
return false;
}, specified_poller);

View File

@@ -254,16 +254,9 @@ void PlayerProxy::rePlay(const string &strUrl, int iFailedCnt) {
bool PlayerProxy::close(MediaSource &sender) {
// 通知其停止推流 [AUTO-TRANSLATED:d69d10d8]
// Notify it to stop pushing the stream
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();
strongSelf->setMediaSource(nullptr);
strongSelf->teardown();
});
_muxer = nullptr;
setMediaSource(nullptr);
teardown();
_on_close(SockException(Err_shutdown, "closed by user"));
WarnL << "close media: " << sender.getUrl();
return true;

View File

@@ -591,9 +591,7 @@ void RtmpSession::onSendMedia(const RtmpPacket::Ptr &pkt) {
}
bool RtmpSession::close(MediaSource &sender) {
//此回调在其他线程触发
string err = StrPrinter << "close media: " << sender.getUrl();
safeShutdown(SockException(Err_shutdown, err));
shutdown(SockException(Err_shutdown, "close media: " + sender.getUrl()));
return true;
}

View File

@@ -1175,9 +1175,7 @@ int RtspSession::getTrackIndexByInterleaved(int interleaved) {
}
bool RtspSession::close(MediaSource &sender) {
//此回调在其他线程触发
string err = StrPrinter << "close media: " << sender.getUrl();
safeShutdown(SockException(Err_shutdown,err));
shutdown(SockException(Err_shutdown,"close media: " + sender.getUrl()));
return true;
}

View File

@@ -36,9 +36,9 @@ public:
if (!media) {
break;
}
if (!media->close(true)) {
break;
}
media->getOwnerPoller()->async([media]() {
media->close(true);
});
(*stream) << "\t踢出成功:" << media->getUrl() << "\r\n";
return;
} while (0);