mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-06 19:58:10 +08:00
实现rtsp/rtmp按需转协议功能
This commit is contained in:
@@ -60,7 +60,7 @@ public:
|
||||
MediaSource(RTMP_SCHEMA, vhost, app, stream_id), _ring_size(ring_size) {
|
||||
}
|
||||
|
||||
virtual ~RtmpMediaSource() {}
|
||||
~RtmpMediaSource() override{}
|
||||
|
||||
/**
|
||||
* 获取媒体源的环形缓冲
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
|
||||
if (!_ring) {
|
||||
weak_ptr<RtmpMediaSource> weakSelf = dynamic_pointer_cast<RtmpMediaSource>(shared_from_this());
|
||||
auto lam = [weakSelf](const EventPoller::Ptr &, int size, bool) {
|
||||
auto lam = [weakSelf](int size) {
|
||||
auto strongSelf = weakSelf.lock();
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
@@ -174,6 +174,11 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void clearCache() override{
|
||||
PacketCache<RtmpPacket>::clearCache();
|
||||
_ring->clearCache();
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* 批量flush rtmp包时触发该函数
|
||||
@@ -185,15 +190,6 @@ private:
|
||||
_ring->write(rtmp_list, _have_video ? key_pos : true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次增减消费者都会触发该函数
|
||||
*/
|
||||
void onReaderChanged(int size) {
|
||||
if (size == 0) {
|
||||
onNoneReader();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool _have_video = false;
|
||||
int _ring_size;
|
||||
|
||||
@@ -77,13 +77,12 @@ public:
|
||||
|
||||
/**
|
||||
* 设置协议转换
|
||||
* @param enableRtsp 是否转换成rtsp
|
||||
* @param enableHls 是否转换成hls
|
||||
* @param enableMP4 是否mp4录制
|
||||
*/
|
||||
void setProtocolTranslation(bool enableRtsp, bool enableHls, bool enableMP4) {
|
||||
void setProtocolTranslation(bool enableHls, bool enableMP4) {
|
||||
//不重复生成rtmp
|
||||
_muxer = std::make_shared<MultiMediaSourceMuxer>(getVhost(), getApp(), getId(), _demuxer->getDuration(), enableRtsp, false, enableHls, enableMP4);
|
||||
_muxer = std::make_shared<MultiMediaSourceMuxer>(getVhost(), getApp(), getId(), _demuxer->getDuration(), true, false, enableHls, enableMP4);
|
||||
_muxer->setMediaListener(getListener());
|
||||
_muxer->setTrackListener(static_pointer_cast<RtmpMediaSourceImp>(shared_from_this()));
|
||||
//让_muxer对象拦截一部分事件(比如说录像相关事件)
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
class RtmpMediaSourceMuxer : public RtmpMuxer {
|
||||
class RtmpMediaSourceMuxer : public RtmpMuxer, public MediaSourceEventInterceptor,
|
||||
public std::enable_shared_from_this<RtmpMediaSourceMuxer> {
|
||||
public:
|
||||
typedef std::shared_ptr<RtmpMediaSourceMuxer> Ptr;
|
||||
|
||||
@@ -27,10 +28,11 @@ public:
|
||||
_media_src = std::make_shared<RtmpMediaSource>(vhost, strApp, strId);
|
||||
getRtmpRing()->setDelegate(_media_src);
|
||||
}
|
||||
virtual ~RtmpMediaSourceMuxer(){}
|
||||
|
||||
~RtmpMediaSourceMuxer() override{}
|
||||
|
||||
void setListener(const std::weak_ptr<MediaSourceEvent> &listener){
|
||||
_media_src->setListener(listener);
|
||||
_listener = listener;
|
||||
}
|
||||
|
||||
void setTimeStamp(uint32_t stamp){
|
||||
@@ -43,10 +45,36 @@ public:
|
||||
|
||||
void onAllTrackReady(){
|
||||
makeConfigPacket();
|
||||
_media_src->setListener(shared_from_this());
|
||||
_media_src->setMetaData(getMetadata());
|
||||
}
|
||||
|
||||
void onReaderChanged(MediaSource &sender, int size) override {
|
||||
_enabled = size;
|
||||
if (!size) {
|
||||
_clear_cache = true;
|
||||
}
|
||||
MediaSourceEventInterceptor::onReaderChanged(sender, size);
|
||||
}
|
||||
|
||||
void inputFrame(const Frame::Ptr &frame) override {
|
||||
if (_clear_cache) {
|
||||
_clear_cache = false;
|
||||
_media_src->clearCache();
|
||||
}
|
||||
if (_enabled) {
|
||||
RtmpMuxer::inputFrame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
bool isEnabled() {
|
||||
//缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存
|
||||
return _clear_cache ? true : _enabled;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _enabled = true;
|
||||
bool _clear_cache = false;
|
||||
RtmpMediaSource::Ptr _media_src;
|
||||
};
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
|
||||
_media_info.parse(_tc_url + "/" + getStreamId(dec.load<std::string>()));
|
||||
_media_info._schema = RTMP_SCHEMA;
|
||||
|
||||
auto on_res = [this,pToken](const string &err, bool enableRtxp, bool enableHls, bool enableMP4){
|
||||
auto on_res = [this,pToken](const string &err, bool enableHls, bool enableMP4){
|
||||
auto src = dynamic_pointer_cast<RtmpMediaSource>(MediaSource::find(RTMP_SCHEMA,
|
||||
_media_info._vhost,
|
||||
_media_info._app,
|
||||
@@ -150,7 +150,7 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
|
||||
_publisher_src.reset(new RtmpMediaSourceImp(_media_info._vhost, _media_info._app, _media_info._streamid));
|
||||
_publisher_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
|
||||
//设置转协议
|
||||
_publisher_src->setProtocolTranslation(enableRtxp, enableHls, enableMP4);
|
||||
_publisher_src->setProtocolTranslation(enableHls, enableMP4);
|
||||
|
||||
//如果是rtmp推流客户端,那么加大TCP接收缓存,这样能提升接收性能
|
||||
getSock()->setReadBuffer(std::make_shared<BufferRaw>(256 * 1024));
|
||||
@@ -159,30 +159,29 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
|
||||
|
||||
if(_media_info._app.empty() || _media_info._streamid.empty()){
|
||||
//不允许莫名其妙的推流url
|
||||
on_res("rtmp推流url非法", false, false, false);
|
||||
on_res("rtmp推流url非法", false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
Broadcast::PublishAuthInvoker invoker = [weak_self,on_res,pToken](const string &err, bool enableRtxp, bool enableHls, bool enableMP4){
|
||||
Broadcast::PublishAuthInvoker invoker = [weak_self, on_res, pToken](const string &err, bool enableHls, bool enableMP4) {
|
||||
auto strongSelf = weak_self.lock();
|
||||
if(!strongSelf){
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
strongSelf->async([weak_self,on_res,err,pToken,enableRtxp,enableHls,enableMP4](){
|
||||
strongSelf->async([weak_self, on_res, err, pToken, enableHls, enableMP4]() {
|
||||
auto strongSelf = weak_self.lock();
|
||||
if(!strongSelf){
|
||||
if (!strongSelf) {
|
||||
return;
|
||||
}
|
||||
on_res(err, enableRtxp, enableHls, enableMP4);
|
||||
on_res(err, enableHls, enableMP4);
|
||||
});
|
||||
};
|
||||
auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, _media_info, invoker, static_cast<SockInfo &>(*this));
|
||||
if(!flag){
|
||||
//该事件无人监听,默认鉴权成功
|
||||
GET_CONFIG(bool,to_rtxp,General::kPublishToRtxp);
|
||||
GET_CONFIG(bool,to_hls,General::kPublishToHls);
|
||||
GET_CONFIG(bool,to_mp4,General::kPublishToMP4);
|
||||
on_res("", to_rtxp, to_hls, to_mp4);
|
||||
on_res("", to_hls, to_mp4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user