mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-28 21:52:22 +08:00
add MediaTuple
This commit is contained in:
@@ -47,10 +47,8 @@ public:
|
||||
using Ptr = std::shared_ptr<DevChannel>;
|
||||
|
||||
//fDuration<=0为直播,否则为点播
|
||||
DevChannel(
|
||||
const std::string &vhost, const std::string &app, const std::string &stream_id, float duration = 0,
|
||||
const ProtocolOption &option = ProtocolOption())
|
||||
: MultiMediaSourceMuxer(vhost, app, stream_id, duration, option) {}
|
||||
DevChannel(const MediaTuple& tuple, float duration = 0, const ProtocolOption &option = ProtocolOption())
|
||||
: MultiMediaSourceMuxer(tuple, duration, option) {}
|
||||
~DevChannel() override = default;
|
||||
|
||||
/**
|
||||
|
||||
@@ -105,7 +105,7 @@ ProtocolOption::ProtocolOption() {
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct MediaSourceNull : public MediaSource {
|
||||
MediaSourceNull() : MediaSource("schema", "vhost", "app", "stream") {};
|
||||
MediaSourceNull() : MediaSource("schema", MediaTuple{"vhost", "app", "stream"}) {};
|
||||
int readerCount() override { return 0; }
|
||||
};
|
||||
|
||||
@@ -114,16 +114,12 @@ MediaSource &MediaSource::NullMediaSource() {
|
||||
return *s_null;
|
||||
}
|
||||
|
||||
MediaSource::MediaSource(const string &schema, const string &vhost, const string &app, const string &stream_id){
|
||||
MediaSource::MediaSource(const string &schema, const MediaTuple& tuple): _tuple(tuple) {
|
||||
GET_CONFIG(bool, enableVhost, General::kEnableVhost);
|
||||
if (!enableVhost) {
|
||||
_vhost = DEFAULT_VHOST;
|
||||
} else {
|
||||
_vhost = vhost.empty() ? DEFAULT_VHOST : vhost;
|
||||
if (!enableVhost || _tuple.vhost.empty()) {
|
||||
_tuple.vhost = DEFAULT_VHOST;
|
||||
}
|
||||
_schema = schema;
|
||||
_app = app;
|
||||
_stream_id = stream_id;
|
||||
_create_stamp = time(NULL);
|
||||
}
|
||||
|
||||
@@ -136,16 +132,16 @@ const string& MediaSource::getSchema() const {
|
||||
}
|
||||
|
||||
const string& MediaSource::getVhost() const {
|
||||
return _vhost;
|
||||
return _tuple.vhost;
|
||||
}
|
||||
|
||||
const string& MediaSource::getApp() const {
|
||||
//获取该源的id
|
||||
return _app;
|
||||
return _tuple.app;
|
||||
}
|
||||
|
||||
const string& MediaSource::getId() const {
|
||||
return _stream_id;
|
||||
return _tuple.stream;
|
||||
}
|
||||
|
||||
std::shared_ptr<void> MediaSource::getOwnership() {
|
||||
@@ -424,7 +420,7 @@ static MediaSource::Ptr find_l(const string &schema, const string &vhost_in, con
|
||||
|
||||
static void findAsync_l(const MediaInfo &info, const std::shared_ptr<Session> &session, bool retry,
|
||||
const function<void(const MediaSource::Ptr &src)> &cb){
|
||||
auto src = find_l(info._schema, info._vhost, info._app, info._streamid, true);
|
||||
auto src = find_l(info.schema, info.vhost, info.app, info.stream, true);
|
||||
if (src || !retry) {
|
||||
cb(src);
|
||||
return;
|
||||
@@ -459,10 +455,10 @@ static void findAsync_l(const MediaInfo &info, const std::shared_ptr<Session> &s
|
||||
weak_ptr<Session> weak_session = session;
|
||||
auto on_register = [weak_session, info, cb_once, cancel_all, poller](BroadcastMediaChangedArgs) {
|
||||
if (!bRegist ||
|
||||
sender.getSchema() != info._schema ||
|
||||
sender.getVhost() != info._vhost ||
|
||||
sender.getApp() != info._app ||
|
||||
sender.getId() != info._streamid) {
|
||||
sender.getSchema() != info.schema ||
|
||||
sender.getVhost() != info.vhost ||
|
||||
sender.getApp() != info.app ||
|
||||
sender.getId() != info.stream) {
|
||||
//不是自己感兴趣的事件,忽略之
|
||||
return;
|
||||
}
|
||||
@@ -527,7 +523,7 @@ void MediaSource::regist() {
|
||||
{
|
||||
//减小互斥锁临界区
|
||||
lock_guard<recursive_mutex> lock(s_media_source_mtx);
|
||||
auto &ref = s_media_source_map[_schema][_vhost][_app][_stream_id];
|
||||
auto &ref = s_media_source_map[_schema][_tuple.vhost][_tuple.app][_tuple.stream];
|
||||
auto src = ref.lock();
|
||||
if (src) {
|
||||
if (src.get() == this) {
|
||||
@@ -570,7 +566,7 @@ bool MediaSource::unregist() {
|
||||
{
|
||||
//减小互斥锁临界区
|
||||
lock_guard<recursive_mutex> lock(s_media_source_mtx);
|
||||
erase_media_source(ret, this, s_media_source_map, _schema, _vhost, _app, _stream_id);
|
||||
erase_media_source(ret, this, s_media_source_map, _schema, _tuple.vhost, _tuple.app, _tuple.stream);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
@@ -582,31 +578,31 @@ bool MediaSource::unregist() {
|
||||
/////////////////////////////////////MediaInfo//////////////////////////////////////
|
||||
|
||||
void MediaInfo::parse(const std::string &url_in){
|
||||
_full_url = url_in;
|
||||
full_url = url_in;
|
||||
auto url = url_in;
|
||||
auto pos = url.find("?");
|
||||
if (pos != string::npos) {
|
||||
_param_strs = url.substr(pos + 1);
|
||||
param_strs = url.substr(pos + 1);
|
||||
url.erase(pos);
|
||||
}
|
||||
|
||||
auto schema_pos = url.find("://");
|
||||
if (schema_pos != string::npos) {
|
||||
_schema = url.substr(0, schema_pos);
|
||||
schema = url.substr(0, schema_pos);
|
||||
} else {
|
||||
schema_pos = -3;
|
||||
}
|
||||
auto split_vec = split(url.substr(schema_pos + 3), "/");
|
||||
if (split_vec.size() > 0) {
|
||||
splitUrl(split_vec[0], _host, _port);
|
||||
_vhost = _host;
|
||||
if (_vhost == "localhost" || isIP(_vhost.data())) {
|
||||
splitUrl(split_vec[0], host, port);
|
||||
vhost = host;
|
||||
if (vhost == "localhost" || isIP(vhost.data())) {
|
||||
//如果访问的是localhost或ip,那么则为默认虚拟主机
|
||||
_vhost = DEFAULT_VHOST;
|
||||
vhost = DEFAULT_VHOST;
|
||||
}
|
||||
}
|
||||
if (split_vec.size() > 1) {
|
||||
_app = split_vec[1];
|
||||
app = split_vec[1];
|
||||
}
|
||||
if (split_vec.size() > 2) {
|
||||
string stream_id;
|
||||
@@ -616,18 +612,18 @@ void MediaInfo::parse(const std::string &url_in){
|
||||
if (stream_id.back() == '/') {
|
||||
stream_id.pop_back();
|
||||
}
|
||||
_streamid = stream_id;
|
||||
stream = stream_id;
|
||||
}
|
||||
|
||||
auto params = Parser::parseArgs(_param_strs);
|
||||
auto params = Parser::parseArgs(param_strs);
|
||||
if (params.find(VHOST_KEY) != params.end()) {
|
||||
_vhost = params[VHOST_KEY];
|
||||
vhost = params[VHOST_KEY];
|
||||
}
|
||||
|
||||
GET_CONFIG(bool, enableVhost, General::kEnableVhost);
|
||||
if (!enableVhost || _vhost.empty()) {
|
||||
if (!enableVhost || vhost.empty()) {
|
||||
//如果关闭虚拟主机或者虚拟主机为空,则设置虚拟主机为默认
|
||||
_vhost = DEFAULT_VHOST;
|
||||
vhost = DEFAULT_VHOST;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -252,24 +252,20 @@ private:
|
||||
/**
|
||||
* 解析url获取媒体相关信息
|
||||
*/
|
||||
class MediaInfo {
|
||||
class MediaInfo: public MediaTuple {
|
||||
public:
|
||||
~MediaInfo() = default;
|
||||
MediaInfo() = default;
|
||||
MediaInfo(const std::string &url) { parse(url); }
|
||||
void parse(const std::string &url);
|
||||
std::string shortUrl() const { return _vhost + "/" + _app + "/" + _streamid; }
|
||||
std::string getUrl() const { return _schema + "://" + shortUrl(); }
|
||||
std::string getUrl() const { return schema + "://" + shortUrl(); }
|
||||
|
||||
public:
|
||||
uint16_t _port = 0;
|
||||
std::string _full_url;
|
||||
std::string _schema;
|
||||
std::string _host;
|
||||
std::string _vhost;
|
||||
std::string _app;
|
||||
std::string _streamid;
|
||||
std::string _param_strs;
|
||||
uint16_t port = 0;
|
||||
std::string full_url;
|
||||
std::string schema;
|
||||
std::string host;
|
||||
std::string param_strs;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -280,7 +276,7 @@ public:
|
||||
static MediaSource& NullMediaSource();
|
||||
using Ptr = std::shared_ptr<MediaSource>;
|
||||
|
||||
MediaSource(const std::string &schema, const std::string &vhost, const std::string &app, const std::string &stream_id);
|
||||
MediaSource(const std::string &schema, const MediaTuple& tuple);
|
||||
virtual ~MediaSource();
|
||||
|
||||
////////////////获取MediaSource相关信息////////////////
|
||||
@@ -294,7 +290,11 @@ public:
|
||||
// 流id
|
||||
const std::string& getId() const;
|
||||
|
||||
std::string shortUrl() const { return _vhost + "/" + _app + "/" + _stream_id; }
|
||||
const MediaTuple& getMediaTuple() const {
|
||||
return _tuple;
|
||||
}
|
||||
|
||||
std::string shortUrl() const { return _tuple.shortUrl(); }
|
||||
|
||||
std::string getUrl() const { return _schema + "://" + shortUrl(); }
|
||||
|
||||
@@ -369,7 +369,7 @@ public:
|
||||
// 同步查找流
|
||||
static Ptr find(const std::string &schema, const std::string &vhost, const std::string &app, const std::string &id, bool from_mp4 = false);
|
||||
static Ptr find(const MediaInfo &info, bool from_mp4 = false) {
|
||||
return find(info._schema, info._vhost, info._app, info._streamid, from_mp4);
|
||||
return find(info.schema, info.vhost, info.app, info.stream, from_mp4);
|
||||
}
|
||||
|
||||
// 忽略schema,同步查找流,可能返回rtmp/rtsp/hls类型
|
||||
@@ -394,15 +394,13 @@ private:
|
||||
|
||||
protected:
|
||||
toolkit::BytesSpeed _speed[TrackMax];
|
||||
MediaTuple _tuple;
|
||||
|
||||
private:
|
||||
std::atomic_flag _owned { false };
|
||||
time_t _create_stamp;
|
||||
toolkit::Ticker _ticker;
|
||||
std::string _schema;
|
||||
std::string _vhost;
|
||||
std::string _app;
|
||||
std::string _stream_id;
|
||||
std::weak_ptr<MediaSourceEvent> _listener;
|
||||
// 对象个数统计
|
||||
toolkit::ObjectStatistic<MediaSource> _statistic;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace {
|
||||
class MediaSourceForMuxer : public MediaSource {
|
||||
public:
|
||||
MediaSourceForMuxer(const MultiMediaSourceMuxer::Ptr &muxer)
|
||||
: MediaSource("muxer", muxer->getVhost(), muxer->getApp(), muxer->getStreamId()) {
|
||||
: MediaSource("muxer", muxer->getMediaTuple()) {
|
||||
MediaSource::setListener(muxer);
|
||||
}
|
||||
int readerCount() override { return 0; }
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
} // namespace
|
||||
|
||||
static std::shared_ptr<MediaSinkInterface> makeRecorder(MediaSource &sender, const vector<Track::Ptr> &tracks, Recorder::type type, const ProtocolOption &option){
|
||||
auto recorder = Recorder::createRecorder(type, sender.getVhost(), sender.getApp(), sender.getId(), option);
|
||||
auto recorder = Recorder::createRecorder(type, sender.getMediaTuple(), option);
|
||||
for (auto &track : tracks) {
|
||||
recorder->addTrack(track);
|
||||
}
|
||||
@@ -71,15 +71,15 @@ static string getTrackInfoStr(const TrackSource *track_src){
|
||||
}
|
||||
|
||||
const std::string &MultiMediaSourceMuxer::getVhost() const {
|
||||
return _vhost;
|
||||
return _tuple.vhost;
|
||||
}
|
||||
|
||||
const std::string &MultiMediaSourceMuxer::getApp() const {
|
||||
return _app;
|
||||
return _tuple.app;
|
||||
}
|
||||
|
||||
const std::string &MultiMediaSourceMuxer::getStreamId() const {
|
||||
return _stream_id;
|
||||
return _tuple.stream;
|
||||
}
|
||||
|
||||
std::string MultiMediaSourceMuxer::shortUrl() const {
|
||||
@@ -87,35 +87,32 @@ std::string MultiMediaSourceMuxer::shortUrl() const {
|
||||
if (!ret.empty()) {
|
||||
return ret;
|
||||
}
|
||||
return _vhost + "/" + _app + "/" + _stream_id;
|
||||
return _tuple.shortUrl();
|
||||
}
|
||||
|
||||
MultiMediaSourceMuxer::MultiMediaSourceMuxer(const string &vhost, const string &app, const string &stream, float dur_sec, const ProtocolOption &option) {
|
||||
MultiMediaSourceMuxer::MultiMediaSourceMuxer(const MediaTuple& tuple, float dur_sec, const ProtocolOption &option): _tuple(tuple) {
|
||||
_poller = EventPollerPool::Instance().getPoller();
|
||||
_create_in_poller = _poller->isCurrentThread();
|
||||
_vhost = vhost;
|
||||
_app = app;
|
||||
_stream_id = stream;
|
||||
_option = option;
|
||||
|
||||
if (option.enable_rtmp) {
|
||||
_rtmp = std::make_shared<RtmpMediaSourceMuxer>(vhost, app, stream, option, std::make_shared<TitleMeta>(dur_sec));
|
||||
_rtmp = std::make_shared<RtmpMediaSourceMuxer>(_tuple, option, std::make_shared<TitleMeta>(dur_sec));
|
||||
}
|
||||
if (option.enable_rtsp) {
|
||||
_rtsp = std::make_shared<RtspMediaSourceMuxer>(vhost, app, stream, option, std::make_shared<TitleSdp>(dur_sec));
|
||||
_rtsp = std::make_shared<RtspMediaSourceMuxer>(_tuple, option, std::make_shared<TitleSdp>(dur_sec));
|
||||
}
|
||||
if (option.enable_hls) {
|
||||
_hls = dynamic_pointer_cast<HlsRecorder>(Recorder::createRecorder(Recorder::type_hls, vhost, app, stream, option));
|
||||
_hls = dynamic_pointer_cast<HlsRecorder>(Recorder::createRecorder(Recorder::type_hls, _tuple, option));
|
||||
}
|
||||
if (option.enable_mp4) {
|
||||
_mp4 = Recorder::createRecorder(Recorder::type_mp4, vhost, app, stream, option);
|
||||
_mp4 = Recorder::createRecorder(Recorder::type_mp4, _tuple, option);
|
||||
}
|
||||
if (option.enable_ts) {
|
||||
_ts = std::make_shared<TSMediaSourceMuxer>(vhost, app, stream, option);
|
||||
_ts = std::make_shared<TSMediaSourceMuxer>(_tuple, option);
|
||||
}
|
||||
#if defined(ENABLE_MP4)
|
||||
if (option.enable_fmp4) {
|
||||
_fmp4 = std::make_shared<FMP4MediaSourceMuxer>(vhost, app, stream, option);
|
||||
_fmp4 = std::make_shared<FMP4MediaSourceMuxer>(_tuple, option);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
virtual void onAllTrackReady() = 0;
|
||||
};
|
||||
|
||||
MultiMediaSourceMuxer(const std::string &vhost, const std::string &app, const std::string &stream, float dur_sec = 0.0,const ProtocolOption &option = ProtocolOption());
|
||||
MultiMediaSourceMuxer(const MediaTuple& tuple, float dur_sec = 0.0,const ProtocolOption &option = ProtocolOption());
|
||||
~MultiMediaSourceMuxer() override = default;
|
||||
|
||||
/**
|
||||
@@ -129,6 +129,9 @@ public:
|
||||
const std::string& getVhost() const;
|
||||
const std::string& getApp() const;
|
||||
const std::string& getStreamId() const;
|
||||
const MediaTuple& getMediaTuple() const {
|
||||
return _tuple;
|
||||
}
|
||||
std::string shortUrl() const;
|
||||
|
||||
protected:
|
||||
@@ -159,9 +162,7 @@ private:
|
||||
bool _is_enable = false;
|
||||
bool _create_in_poller = false;
|
||||
bool _video_key_pos = false;
|
||||
std::string _vhost;
|
||||
std::string _app;
|
||||
std::string _stream_id;
|
||||
MediaTuple _tuple;
|
||||
ProtocolOption _option;
|
||||
toolkit::Ticker _last_check;
|
||||
Stamp _stamp[2];
|
||||
|
||||
Reference in New Issue
Block a user