mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 12:11:36 +08:00
parent
0eb38635ce
commit
d735aa1797
@ -28,7 +28,8 @@ API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create3(const char *vhost, c
|
|||||||
ProtocolOption option;
|
ProtocolOption option;
|
||||||
option.enable_hls = hls_enabled;
|
option.enable_hls = hls_enabled;
|
||||||
option.enable_mp4 = mp4_enabled;
|
option.enable_mp4 = mp4_enabled;
|
||||||
PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(vhost, app, stream, option, retry_count)));
|
MediaTuple tuple = {vhost, app, stream, ""};
|
||||||
|
PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(tuple, option, retry_count)));
|
||||||
return (mk_proxy_player)obj;
|
return (mk_proxy_player)obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +37,8 @@ API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create3(const char *vhost, c
|
|||||||
API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create4(const char *vhost, const char *app, const char *stream, mk_ini ini, int retry_count) {
|
API_EXPORT mk_proxy_player API_CALL mk_proxy_player_create4(const char *vhost, const char *app, const char *stream, mk_ini ini, int retry_count) {
|
||||||
assert(vhost && app && stream);
|
assert(vhost && app && stream);
|
||||||
ProtocolOption option(*((mINI *)ini));
|
ProtocolOption option(*((mINI *)ini));
|
||||||
PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(vhost, app, stream, option, retry_count)));
|
MediaTuple tuple = {vhost, app, stream, ""};
|
||||||
|
PlayerProxy::Ptr *obj(new PlayerProxy::Ptr(new PlayerProxy(tuple, option, retry_count)));
|
||||||
return (mk_proxy_player)obj;
|
return (mk_proxy_player)obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,9 +376,6 @@ static ServiceController<FFmpegSource> s_ffmpeg_src;
|
|||||||
static ServiceController<RtpServer> s_rtp_server;
|
static ServiceController<RtpServer> s_rtp_server;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline string getProxyKey(const string &vhost, const string &app, const string &stream) {
|
|
||||||
return vhost + "/" + app + "/" + stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline string getPusherKey(const string &schema, const string &vhost, const string &app, const string &stream,
|
static inline string getPusherKey(const string &schema, const string &vhost, const string &app, const string &stream,
|
||||||
const string &dst_url) {
|
const string &dst_url) {
|
||||||
@ -582,17 +579,17 @@ void getStatisticJson(const function<void(Value &val)> &cb) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void addStreamProxy(const string &vhost, const string &app, const string &stream, const string &url, int retry_count,
|
void addStreamProxy(const MediaTuple &tuple, const string &url, int retry_count,
|
||||||
const ProtocolOption &option, int rtp_type, float timeout_sec, const mINI &args,
|
const ProtocolOption &option, int rtp_type, float timeout_sec, const mINI &args,
|
||||||
const function<void(const SockException &ex, const string &key)> &cb) {
|
const function<void(const SockException &ex, const string &key)> &cb) {
|
||||||
auto key = getProxyKey(vhost, app, stream);
|
auto key = tuple.shortUrl();
|
||||||
if (s_player_proxy.find(key)) {
|
if (s_player_proxy.find(key)) {
|
||||||
//已经在拉流了
|
//已经在拉流了
|
||||||
cb(SockException(Err_other, "This stream already exists"), key);
|
cb(SockException(Err_other, "This stream already exists"), key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//添加拉流代理
|
//添加拉流代理
|
||||||
auto player = s_player_proxy.make(key, vhost, app, stream, option, retry_count);
|
auto player = s_player_proxy.make(key, tuple, option, retry_count);
|
||||||
|
|
||||||
// 先透传拷贝参数
|
// 先透传拷贝参数
|
||||||
for (auto &pr : args) {
|
for (auto &pr : args) {
|
||||||
@ -1102,9 +1099,13 @@ void installWebApi() {
|
|||||||
|
|
||||||
ProtocolOption option(allArgs);
|
ProtocolOption option(allArgs);
|
||||||
auto retry_count = allArgs["retry_count"].empty()? -1: allArgs["retry_count"].as<int>();
|
auto retry_count = allArgs["retry_count"].empty()? -1: allArgs["retry_count"].as<int>();
|
||||||
addStreamProxy(allArgs["vhost"],
|
|
||||||
allArgs["app"],
|
std::string vhost = DEFAULT_VHOST;
|
||||||
allArgs["stream"],
|
if (!allArgs["vhost"].empty()) {
|
||||||
|
vhost = allArgs["vhost"];
|
||||||
|
}
|
||||||
|
auto tuple = MediaTuple { vhost, allArgs["app"], allArgs["stream"], "" };
|
||||||
|
addStreamProxy(tuple,
|
||||||
allArgs["url"],
|
allArgs["url"],
|
||||||
retry_count,
|
retry_count,
|
||||||
option,
|
option,
|
||||||
@ -1963,8 +1964,8 @@ void installWebApi() {
|
|||||||
option.load(allArgs);
|
option.load(allArgs);
|
||||||
// 强制无人观看时自动关闭
|
// 强制无人观看时自动关闭
|
||||||
option.auto_close = true;
|
option.auto_close = true;
|
||||||
|
auto tuple = MediaTuple{allArgs["vhost"], allArgs["app"], allArgs["stream"], ""};
|
||||||
auto reader = std::make_shared<MP4Reader>(allArgs["vhost"], allArgs["app"], allArgs["stream"], allArgs["file_path"], option);
|
auto reader = std::make_shared<MP4Reader>(tuple, allArgs["file_path"], option);
|
||||||
// sample_ms设置为0,从配置文件加载;file_repeat可以指定,如果配置文件也指定循环解复用,那么强制开启
|
// sample_ms设置为0,从配置文件加载;file_repeat可以指定,如果配置文件也指定循环解复用,那么强制开启
|
||||||
reader->startReadMP4(0, true, allArgs["file_repeat"]);
|
reader->startReadMP4(0, true, allArgs["file_repeat"]);
|
||||||
});
|
});
|
||||||
|
@ -207,7 +207,7 @@ uint16_t openRtpServer(uint16_t local_port, const mediakit::MediaTuple &tuple, i
|
|||||||
|
|
||||||
Json::Value makeMediaSourceJson(mediakit::MediaSource &media);
|
Json::Value makeMediaSourceJson(mediakit::MediaSource &media);
|
||||||
void getStatisticJson(const std::function<void(Json::Value &val)> &cb);
|
void getStatisticJson(const std::function<void(Json::Value &val)> &cb);
|
||||||
void addStreamProxy(const std::string &vhost, const std::string &app, const std::string &stream, const std::string &url, int retry_count,
|
void addStreamProxy(const mediakit::MediaTuple &tuple, const std::string &url, int retry_count,
|
||||||
const mediakit::ProtocolOption &option, int rtp_type, float timeout_sec, const toolkit::mINI &args,
|
const mediakit::ProtocolOption &option, int rtp_type, float timeout_sec, const toolkit::mINI &args,
|
||||||
const std::function<void(const toolkit::SockException &ex, const std::string &key)> &cb);
|
const std::function<void(const toolkit::SockException &ex, const std::string &key)> &cb);
|
||||||
#endif //ZLMEDIAKIT_WEBAPI_H
|
#endif //ZLMEDIAKIT_WEBAPI_H
|
||||||
|
@ -301,7 +301,7 @@ static void pullStreamFromOrigin(const vector<string> &urls, size_t index, size_
|
|||||||
option.enable_hls = option.enable_hls || (args.schema == HLS_SCHEMA);
|
option.enable_hls = option.enable_hls || (args.schema == HLS_SCHEMA);
|
||||||
option.enable_mp4 = false;
|
option.enable_mp4 = false;
|
||||||
|
|
||||||
addStreamProxy(args.vhost, args.app, args.stream, url, retry_count, option, Rtsp::RTP_TCP, timeout_sec, mINI{}, [=](const SockException &ex, const string &key) mutable {
|
addStreamProxy(args, url, retry_count, option, Rtsp::RTP_TCP, timeout_sec, mINI{}, [=](const SockException &ex, const string &key) mutable {
|
||||||
if (!ex) {
|
if (!ex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -595,7 +595,8 @@ MediaSource::Ptr MediaSource::createFromMP4(const string &schema, const string &
|
|||||||
}
|
}
|
||||||
#ifdef ENABLE_MP4
|
#ifdef ENABLE_MP4
|
||||||
try {
|
try {
|
||||||
auto reader = std::make_shared<MP4Reader>(vhost, app, stream, file_path);
|
MediaTuple tuple = {vhost, app, stream, ""};
|
||||||
|
auto reader = std::make_shared<MP4Reader>(tuple, file_path);
|
||||||
reader->startReadMP4();
|
reader->startReadMP4();
|
||||||
return MediaSource::find(schema, vhost, app, stream);
|
return MediaSource::find(schema, vhost, app, stream);
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
|
@ -24,13 +24,9 @@ using namespace std;
|
|||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
PlayerProxy::PlayerProxy(
|
PlayerProxy::PlayerProxy(
|
||||||
const string &vhost, const string &app, const string &stream_id, const ProtocolOption &option, int retry_count,
|
const MediaTuple &tuple, const ProtocolOption &option, int retry_count,
|
||||||
const EventPoller::Ptr &poller, int reconnect_delay_min, int reconnect_delay_max, int reconnect_delay_step)
|
const EventPoller::Ptr &poller, int reconnect_delay_min, int reconnect_delay_max, int reconnect_delay_step)
|
||||||
: MediaPlayer(poller)
|
: MediaPlayer(poller), _tuple(tuple), _option(option) {
|
||||||
, _option(option) {
|
|
||||||
_tuple.vhost = vhost;
|
|
||||||
_tuple.app = app;
|
|
||||||
_tuple.stream = stream_id;
|
|
||||||
_retry_count = retry_count;
|
_retry_count = retry_count;
|
||||||
|
|
||||||
setOnClose(nullptr);
|
setOnClose(nullptr);
|
||||||
|
@ -66,9 +66,9 @@ public:
|
|||||||
|
|
||||||
// 如果retry_count<0,则一直重试播放;否则重试retry_count次数
|
// 如果retry_count<0,则一直重试播放;否则重试retry_count次数
|
||||||
// 默认一直重试
|
// 默认一直重试
|
||||||
PlayerProxy(
|
PlayerProxy(const MediaTuple &tuple, const ProtocolOption &option, int retry_count = -1,
|
||||||
const std::string &vhost, const std::string &app, const std::string &stream_id, const ProtocolOption &option, int retry_count = -1,
|
const toolkit::EventPoller::Ptr &poller = nullptr,
|
||||||
const toolkit::EventPoller::Ptr &poller = nullptr, int reconnect_delay_min = 2, int reconnect_delay_max = 60, int reconnect_delay_step = 3);
|
int reconnect_delay_min = 2, int reconnect_delay_max = 60, int reconnect_delay_step = 3);
|
||||||
|
|
||||||
~PlayerProxy() override;
|
~PlayerProxy() override;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ using namespace toolkit;
|
|||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
MP4Reader::MP4Reader(const std::string &vhost, const std::string &app, const std::string &stream_id, const string &file_path,
|
MP4Reader::MP4Reader(const MediaTuple &tuple, const string &file_path,
|
||||||
toolkit::EventPoller::Ptr poller) {
|
toolkit::EventPoller::Ptr poller) {
|
||||||
ProtocolOption option;
|
ProtocolOption option;
|
||||||
// 读取mp4文件并流化时,不重复生成mp4/hls文件
|
// 读取mp4文件并流化时,不重复生成mp4/hls文件
|
||||||
@ -29,16 +29,15 @@ MP4Reader::MP4Reader(const std::string &vhost, const std::string &app, const std
|
|||||||
option.enable_hls_fmp4 = false;
|
option.enable_hls_fmp4 = false;
|
||||||
// mp4支持多track
|
// mp4支持多track
|
||||||
option.max_track = 16;
|
option.max_track = 16;
|
||||||
setup(vhost, app, stream_id, file_path, option, std::move(poller));
|
setup(tuple, file_path, option, std::move(poller));
|
||||||
}
|
}
|
||||||
|
|
||||||
MP4Reader::MP4Reader(const std::string &vhost, const std::string &app, const std::string &stream_id, const string &file_path, const ProtocolOption &option, toolkit::EventPoller::Ptr poller) {
|
MP4Reader::MP4Reader(const MediaTuple &tuple, const string &file_path, const ProtocolOption &option, toolkit::EventPoller::Ptr poller) {
|
||||||
setup(vhost, app, stream_id, file_path, option, std::move(poller));
|
setup(tuple, file_path, option, std::move(poller));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP4Reader::setup(const std::string &vhost, const std::string &app, const std::string &stream_id, const std::string &file_path, const ProtocolOption &option, toolkit::EventPoller::Ptr poller) {
|
void MP4Reader::setup(const MediaTuple &tuple, const std::string &file_path, const ProtocolOption &option, toolkit::EventPoller::Ptr poller) {
|
||||||
//读写文件建议放在后台线程
|
//读写文件建议放在后台线程
|
||||||
auto tuple = MediaTuple{vhost, app, stream_id, ""};
|
|
||||||
_poller = poller ? std::move(poller) : WorkThreadPool::Instance().getPoller();
|
_poller = poller ? std::move(poller) : WorkThreadPool::Instance().getPoller();
|
||||||
_file_path = file_path;
|
_file_path = file_path;
|
||||||
if (_file_path.empty()) {
|
if (_file_path.empty()) {
|
||||||
|
@ -28,11 +28,9 @@ public:
|
|||||||
* @param stream_id 流id,置空时,只解复用mp4,但是不生成MediaSource
|
* @param stream_id 流id,置空时,只解复用mp4,但是不生成MediaSource
|
||||||
* @param file_path 文件路径,如果为空则根据配置文件和上面参数自动生成,否则使用指定的文件
|
* @param file_path 文件路径,如果为空则根据配置文件和上面参数自动生成,否则使用指定的文件
|
||||||
*/
|
*/
|
||||||
MP4Reader(const std::string &vhost, const std::string &app, const std::string &stream_id,
|
MP4Reader(const MediaTuple &tuple, const std::string &file_path = "", toolkit::EventPoller::Ptr poller = nullptr);
|
||||||
const std::string &file_path = "", toolkit::EventPoller::Ptr poller = nullptr);
|
|
||||||
|
|
||||||
MP4Reader(const std::string &vhost, const std::string &app, const std::string &stream_id,
|
MP4Reader(const MediaTuple &tuple, const std::string &file_path, const ProtocolOption &option, toolkit::EventPoller::Ptr poller = nullptr);
|
||||||
const std::string &file_path, const ProtocolOption &option, toolkit::EventPoller::Ptr poller = nullptr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始解复用MP4文件
|
* 开始解复用MP4文件
|
||||||
@ -69,7 +67,7 @@ private:
|
|||||||
void setCurrentStamp(uint32_t stamp);
|
void setCurrentStamp(uint32_t stamp);
|
||||||
bool seekTo(uint32_t stamp_seek);
|
bool seekTo(uint32_t stamp_seek);
|
||||||
|
|
||||||
void setup(const std::string &vhost, const std::string &app, const std::string &stream_id, const std::string &file_path, const ProtocolOption &option, toolkit::EventPoller::Ptr poller);
|
void setup(const MediaTuple &tuple, const std::string &file_path, const ProtocolOption &option, toolkit::EventPoller::Ptr poller);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _file_repeat = false;
|
bool _file_repeat = false;
|
||||||
|
@ -99,10 +99,10 @@ RtpMultiCaster::~RtpMultiCaster() {
|
|||||||
DebugL;
|
DebugL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port) {
|
RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, const MediaTuple &tuple, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port) {
|
||||||
auto src = dynamic_pointer_cast<RtspMediaSource>(MediaSource::find(RTSP_SCHEMA, vhost, app, stream));
|
auto src = dynamic_pointer_cast<RtspMediaSource>(MediaSource::find(RTSP_SCHEMA, tuple.vhost, tuple.app, tuple.stream));
|
||||||
if (!src) {
|
if (!src) {
|
||||||
auto err = StrPrinter << "未找到媒体源:" << vhost << " " << app << " " << stream << endl;
|
auto err = StrPrinter << "未找到媒体源:" << tuple.shortUrl() << endl;
|
||||||
throw std::runtime_error(err);
|
throw std::runtime_error(err);
|
||||||
}
|
}
|
||||||
_multicast_ip = (multicast_ip) ? make_shared<uint32_t>(multicast_ip) : MultiCastAddressMaker::Instance().obtain();
|
_multicast_ip = (multicast_ip) ? make_shared<uint32_t>(multicast_ip) : MultiCastAddressMaker::Instance().obtain();
|
||||||
@ -144,7 +144,7 @@ RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, con
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
string strKey = StrPrinter << local_ip << " " << vhost << " " << app << " " << stream << endl;
|
string strKey = StrPrinter << local_ip << " " << tuple.vhost << " " << tuple.app << " " << tuple.stream << endl;
|
||||||
_rtp_reader->setDetachCB([this, strKey]() {
|
_rtp_reader->setDetachCB([this, strKey]() {
|
||||||
{
|
{
|
||||||
lock_guard<recursive_mutex> lck(g_mtx);
|
lock_guard<recursive_mutex> lck(g_mtx);
|
||||||
@ -167,7 +167,7 @@ RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, con
|
|||||||
DebugL << MultiCastAddressMaker::toString(*_multicast_ip) << " "
|
DebugL << MultiCastAddressMaker::toString(*_multicast_ip) << " "
|
||||||
<< _udp_sock[0]->get_local_port() << " "
|
<< _udp_sock[0]->get_local_port() << " "
|
||||||
<< _udp_sock[1]->get_local_port() << " "
|
<< _udp_sock[1]->get_local_port() << " "
|
||||||
<< vhost << " " << app << " " << stream;
|
<< tuple.shortUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t RtpMultiCaster::getMultiCasterPort(TrackType trackType) {
|
uint16_t RtpMultiCaster::getMultiCasterPort(TrackType trackType) {
|
||||||
@ -180,17 +180,17 @@ string RtpMultiCaster::getMultiCasterIP() {
|
|||||||
return SockUtil::inet_ntoa(addr);
|
return SockUtil::inet_ntoa(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpMultiCaster::Ptr RtpMultiCaster::get(SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port) {
|
RtpMultiCaster::Ptr RtpMultiCaster::get(SocketHelper &helper, const string &local_ip, const MediaTuple &tuple, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port) {
|
||||||
static auto on_create = [](SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port){
|
static auto on_create = [](SocketHelper &helper, const string &local_ip, const MediaTuple &tuple, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port){
|
||||||
try {
|
try {
|
||||||
auto poller = helper.getPoller();
|
auto poller = helper.getPoller();
|
||||||
auto ret = RtpMultiCaster::Ptr(new RtpMultiCaster(helper, local_ip, vhost, app, stream, multicast_ip, video_port, audio_port), [poller](RtpMultiCaster *ptr) {
|
auto ret = RtpMultiCaster::Ptr(new RtpMultiCaster(helper, local_ip, tuple, multicast_ip, video_port, audio_port), [poller](RtpMultiCaster *ptr) {
|
||||||
poller->async([ptr]() {
|
poller->async([ptr]() {
|
||||||
delete ptr;
|
delete ptr;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
lock_guard<recursive_mutex> lck(g_mtx);
|
lock_guard<recursive_mutex> lck(g_mtx);
|
||||||
string strKey = StrPrinter << local_ip << " " << vhost << " " << app << " " << stream << endl;
|
string strKey = StrPrinter << local_ip << " " << tuple.vhost << " " << tuple.app << " " << tuple.stream << endl;
|
||||||
g_multi_caster_map.emplace(strKey, ret);
|
g_multi_caster_map.emplace(strKey, ret);
|
||||||
return ret;
|
return ret;
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
@ -199,16 +199,16 @@ RtpMultiCaster::Ptr RtpMultiCaster::get(SocketHelper &helper, const string &loca
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
string strKey = StrPrinter << local_ip << " " << vhost << " " << app << " " << stream << endl;
|
string strKey = StrPrinter << local_ip << " " << tuple.vhost << " " << tuple.app << " " << tuple.stream << endl;
|
||||||
lock_guard<recursive_mutex> lck(g_mtx);
|
lock_guard<recursive_mutex> lck(g_mtx);
|
||||||
auto it = g_multi_caster_map.find(strKey);
|
auto it = g_multi_caster_map.find(strKey);
|
||||||
if (it == g_multi_caster_map.end()) {
|
if (it == g_multi_caster_map.end()) {
|
||||||
return on_create(helper, local_ip, vhost, app, stream, multicast_ip, video_port, audio_port);
|
return on_create(helper, local_ip, tuple, multicast_ip, video_port, audio_port);
|
||||||
}
|
}
|
||||||
auto ret = it->second.lock();
|
auto ret = it->second.lock();
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
g_multi_caster_map.erase(it);
|
g_multi_caster_map.erase(it);
|
||||||
return on_create(helper, local_ip, vhost, app, stream, multicast_ip, video_port, audio_port);
|
return on_create(helper, local_ip, tuple, multicast_ip, video_port, audio_port);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -45,14 +45,14 @@ public:
|
|||||||
|
|
||||||
~RtpMultiCaster();
|
~RtpMultiCaster();
|
||||||
|
|
||||||
static Ptr get(toolkit::SocketHelper &helper, const std::string &local_ip, const std::string &vhost, const std::string &app, const std::string &stream, uint32_t multicast_ip = 0, uint16_t video_port = 0, uint16_t audio_port = 0);
|
static Ptr get(toolkit::SocketHelper &helper, const std::string &local_ip, const MediaTuple &tuple, uint32_t multicast_ip = 0, uint16_t video_port = 0, uint16_t audio_port = 0);
|
||||||
void setDetachCB(void *listener,const onDetach &cb);
|
void setDetachCB(void *listener,const onDetach &cb);
|
||||||
|
|
||||||
std::string getMultiCasterIP();
|
std::string getMultiCasterIP();
|
||||||
uint16_t getMultiCasterPort(TrackType trackType);
|
uint16_t getMultiCasterPort(TrackType trackType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RtpMultiCaster(toolkit::SocketHelper &helper, const std::string &local_ip, const std::string &vhost, const std::string &app, const std::string &stream, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port);
|
RtpMultiCaster(toolkit::SocketHelper &helper, const std::string &local_ip, const MediaTuple &tuple, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::recursive_mutex _mtx;
|
std::recursive_mutex _mtx;
|
||||||
|
@ -742,7 +742,7 @@ void RtspSession::handleReq_Setup(const Parser &parser) {
|
|||||||
break;
|
break;
|
||||||
case Rtsp::RTP_MULTICAST: {
|
case Rtsp::RTP_MULTICAST: {
|
||||||
if(!_multicaster){
|
if(!_multicaster){
|
||||||
_multicaster = RtpMultiCaster::get(*this, get_local_ip(), _media_info.vhost, _media_info.app, _media_info.stream, _multicast_ip, _multicast_video_port, _multicast_audio_port);
|
_multicaster = RtpMultiCaster::get(*this, get_local_ip(), _media_info, _multicast_ip, _multicast_video_port, _multicast_audio_port);
|
||||||
if (!_multicaster) {
|
if (!_multicaster) {
|
||||||
send_NotAcceptable();
|
send_NotAcceptable();
|
||||||
throw SockException(Err_shutdown, "can not get a available udp multicast socket");
|
throw SockException(Err_shutdown, "can not get a available udp multicast socket");
|
||||||
|
@ -224,7 +224,8 @@ int main(int argc, char *argv[]) {
|
|||||||
option.enable_mp4 = false;
|
option.enable_mp4 = false;
|
||||||
option.modify_stamp = (int)ProtocolOption::kModifyStampRelative;
|
option.modify_stamp = (int)ProtocolOption::kModifyStampRelative;
|
||||||
//添加拉流代理
|
//添加拉流代理
|
||||||
auto proxy = std::make_shared<PlayerProxy>(DEFAULT_VHOST, "app", std::to_string(i), option, -1, nullptr, 1);
|
auto tuple = MediaTuple{DEFAULT_VHOST, "app", std::to_string(i)};
|
||||||
|
auto proxy = std::make_shared<PlayerProxy>(tuple, option, -1, nullptr, 1);
|
||||||
//开始拉流代理
|
//开始拉流代理
|
||||||
proxy->play(input_urls[i]);
|
proxy->play(input_urls[i]);
|
||||||
proxy_map.emplace(i, std::move(proxy));
|
proxy_map.emplace(i, std::move(proxy));
|
||||||
|
@ -137,7 +137,8 @@ int main(int argc, char *argv[]) {
|
|||||||
option.enable_mp4 = false;
|
option.enable_mp4 = false;
|
||||||
for (auto i = 0; i < proxy_count; ++i) {
|
for (auto i = 0; i < proxy_count; ++i) {
|
||||||
auto stream = to_string(i);
|
auto stream = to_string(i);
|
||||||
PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", stream, option));
|
auto tuple = MediaTuple{DEFAULT_VHOST, "live", stream, ""};
|
||||||
|
PlayerProxy::Ptr player(new PlayerProxy(tuple, option));
|
||||||
(*player)[Client::kRtpType] = rtp_type;
|
(*player)[Client::kRtpType] = rtp_type;
|
||||||
player->play(in_url);
|
player->play(in_url);
|
||||||
proxyMap.emplace(stream, player);
|
proxyMap.emplace(stream, player);
|
||||||
|
@ -148,9 +148,10 @@ int main(int argc, char *argv[]) {
|
|||||||
MediaSource::Ptr src = nullptr;
|
MediaSource::Ptr src = nullptr;
|
||||||
PlayerProxy::Ptr proxy = nullptr;;
|
PlayerProxy::Ptr proxy = nullptr;;
|
||||||
|
|
||||||
|
auto tuple = MediaTuple{DEFAULT_VHOST, app, stream};
|
||||||
if (end_with(in_url, ".mp4")) {
|
if (end_with(in_url, ".mp4")) {
|
||||||
// create MediaSource from mp4file
|
// create MediaSource from mp4file
|
||||||
auto reader = std::make_shared<MP4Reader>(DEFAULT_VHOST, app, stream, in_url);
|
auto reader = std::make_shared<MP4Reader>(tuple, in_url);
|
||||||
//mp4 repeat
|
//mp4 repeat
|
||||||
reader->startReadMP4(0, true, true);
|
reader->startReadMP4(0, true, true);
|
||||||
src = MediaSource::find(schema, DEFAULT_VHOST, app, stream, false);
|
src = MediaSource::find(schema, DEFAULT_VHOST, app, stream, false);
|
||||||
@ -161,7 +162,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//添加拉流代理
|
//添加拉流代理
|
||||||
proxy = std::make_shared<PlayerProxy>(DEFAULT_VHOST, app, stream, option);
|
proxy = std::make_shared<PlayerProxy>(tuple, option);
|
||||||
//rtsp拉流代理方式
|
//rtsp拉流代理方式
|
||||||
(*proxy)[Client::kRtpType] = rtp_type;
|
(*proxy)[Client::kRtpType] = rtp_type;
|
||||||
//开始拉流代理
|
//开始拉流代理
|
||||||
|
@ -79,7 +79,8 @@ int domain(const string &playUrl, const string &pushUrl) {
|
|||||||
ProtocolOption option;
|
ProtocolOption option;
|
||||||
option.enable_hls = false;
|
option.enable_hls = false;
|
||||||
option.enable_mp4 = false;
|
option.enable_mp4 = false;
|
||||||
PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "app", "stream", option, -1, poller));
|
auto tuple = MediaTuple{DEFAULT_VHOST, "app", "stream", ""};
|
||||||
|
PlayerProxy::Ptr player(new PlayerProxy(tuple, option, -1, poller));
|
||||||
//可以指定rtsp拉流方式,支持tcp和udp方式,默认tcp
|
//可以指定rtsp拉流方式,支持tcp和udp方式,默认tcp
|
||||||
// (*player)[Client::kRtpType] = Rtsp::RTP_UDP;
|
// (*player)[Client::kRtpType] = Rtsp::RTP_UDP;
|
||||||
player->play(playUrl.data());
|
player->play(playUrl.data());
|
||||||
|
@ -43,7 +43,8 @@ int domain(const string &file, const string &url) {
|
|||||||
mINI::Instance()["protocol.enable_" + schema] = 1;
|
mINI::Instance()["protocol.enable_" + schema] = 1;
|
||||||
|
|
||||||
// 从mp4文件加载生成MediaSource对象
|
// 从mp4文件加载生成MediaSource对象
|
||||||
auto reader = std::make_shared<MP4Reader>(DEFAULT_VHOST, "live", "stream", file);
|
auto tuple = MediaTuple {DEFAULT_VHOST, "live", "stream", ""};
|
||||||
|
auto reader = std::make_shared<MP4Reader>(tuple, file);
|
||||||
// 开始加载mp4,ref_self设置为false,这样reader对象设置为nullptr就能注销了,file_repeat可以设置为空,这样文件读完了就停止推流了
|
// 开始加载mp4,ref_self设置为false,这样reader对象设置为nullptr就能注销了,file_repeat可以设置为空,这样文件读完了就停止推流了
|
||||||
reader->startReadMP4(100, false, true);
|
reader->startReadMP4(100, false, true);
|
||||||
auto src = MediaSource::find(schema, DEFAULT_VHOST, "live", "stream", false);
|
auto src = MediaSource::find(schema, DEFAULT_VHOST, "live", "stream", false);
|
||||||
|
@ -230,8 +230,8 @@ int main(int argc,char *argv[]) {
|
|||||||
//http://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
//http://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
||||||
//rtsp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
//rtsp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
||||||
//rtmp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
//rtmp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
||||||
|
auto tuple = MediaTuple{DEFAULT_VHOST, "live", std::string("chn") + to_string(i).data(), ""};
|
||||||
PlayerProxy::Ptr player(new PlayerProxy(DEFAULT_VHOST, "live", std::string("chn") + to_string(i).data(), ProtocolOption()));
|
PlayerProxy::Ptr player(new PlayerProxy(tuple, ProtocolOption()));
|
||||||
//指定RTP over TCP(播放rtsp时有效)
|
//指定RTP over TCP(播放rtsp时有效)
|
||||||
(*player)[Client::kRtpType] = Rtsp::RTP_TCP;
|
(*player)[Client::kRtpType] = Rtsp::RTP_TCP;
|
||||||
//开始播放,如果播放失败或者播放中止,将会自动重试若干次,重试次数在配置文件中配置,默认一直重试
|
//开始播放,如果播放失败或者播放中止,将会自动重试若干次,重试次数在配置文件中配置,默认一直重试
|
||||||
|
Loading…
Reference in New Issue
Block a user