add MediaTuple

This commit is contained in:
Johnny
2023-05-25 16:23:24 +08:00
committed by 夏楚
parent f4ee607feb
commit 0232caf068
41 changed files with 242 additions and 273 deletions

View File

@@ -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;
/**

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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];