mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
合并代码
This commit is contained in:
commit
8cbec43ee8
@ -1 +1 @@
|
|||||||
Subproject commit d5de1d4f0c86139fe8f0b6d956e45dee3b151783
|
Subproject commit b04d132139399637cbb201c2832dd98dc2786e82
|
@ -512,6 +512,12 @@
|
|||||||
"value": null,
|
"value": null,
|
||||||
"description": "rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播",
|
"description": "rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播",
|
||||||
"disabled": true
|
"disabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "timeout_sec",
|
||||||
|
"value": "10",
|
||||||
|
"description": "拉流超时时间,单位秒,float类型",
|
||||||
|
"disabled": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -600,6 +600,7 @@ void installWebApi() {
|
|||||||
bool enable_hls,
|
bool enable_hls,
|
||||||
bool enable_mp4,
|
bool enable_mp4,
|
||||||
int rtp_type,
|
int rtp_type,
|
||||||
|
float timeoutSec,
|
||||||
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 = getProxyKey(vhost,app,stream);
|
||||||
lock_guard<recursive_mutex> lck(s_proxyMapMtx);
|
lock_guard<recursive_mutex> lck(s_proxyMapMtx);
|
||||||
@ -614,6 +615,12 @@ void installWebApi() {
|
|||||||
|
|
||||||
//指定RTP over TCP(播放rtsp时有效)
|
//指定RTP over TCP(播放rtsp时有效)
|
||||||
(*player)[kRtpType] = rtp_type;
|
(*player)[kRtpType] = rtp_type;
|
||||||
|
|
||||||
|
if (timeoutSec > 0.1) {
|
||||||
|
//播放握手超时时间
|
||||||
|
(*player)[kTimeoutMS] = timeoutSec * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
//开始播放,如果播放失败或者播放中止,将会自动重试若干次,默认一直重试
|
//开始播放,如果播放失败或者播放中止,将会自动重试若干次,默认一直重试
|
||||||
player->setPlayCallbackOnce([cb,key](const SockException &ex){
|
player->setPlayCallbackOnce([cb,key](const SockException &ex){
|
||||||
if(ex){
|
if(ex){
|
||||||
@ -643,6 +650,7 @@ void installWebApi() {
|
|||||||
allArgs["enable_hls"],/* 是否hls转发 */
|
allArgs["enable_hls"],/* 是否hls转发 */
|
||||||
allArgs["enable_mp4"],/* 是否MP4录制 */
|
allArgs["enable_mp4"],/* 是否MP4录制 */
|
||||||
allArgs["rtp_type"],
|
allArgs["rtp_type"],
|
||||||
|
allArgs["timeout_sec"],
|
||||||
[invoker,val,headerOut](const SockException &ex,const string &key) mutable{
|
[invoker,val,headerOut](const SockException &ex,const string &key) mutable{
|
||||||
if (ex) {
|
if (ex) {
|
||||||
val["code"] = API::OtherFailed;
|
val["code"] = API::OtherFailed;
|
||||||
@ -1133,6 +1141,7 @@ void installWebApi() {
|
|||||||
true,/* 开启hls转发 */
|
true,/* 开启hls转发 */
|
||||||
false,/* 禁用MP4录制 */
|
false,/* 禁用MP4录制 */
|
||||||
0,//rtp over tcp方式拉流
|
0,//rtp over tcp方式拉流
|
||||||
|
10,//10秒超时
|
||||||
[invoker,val,headerOut](const SockException &ex,const string &key) mutable{
|
[invoker,val,headerOut](const SockException &ex,const string &key) mutable{
|
||||||
if(ex){
|
if(ex){
|
||||||
val["code"] = API::OtherFailed;
|
val["code"] = API::OtherFailed;
|
||||||
|
@ -202,82 +202,58 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
|
|||||||
_media_info._vhost,
|
_media_info._vhost,
|
||||||
_media_info._app,
|
_media_info._app,
|
||||||
_media_info._streamid));
|
_media_info._streamid));
|
||||||
if(src){
|
if (src) {
|
||||||
sendRtspResponse("406 Not Acceptable", {"Content-Type", "text/plain"}, "Already publishing.");
|
sendRtspResponse("406 Not Acceptable", {"Content-Type", "text/plain"}, "Already publishing.");
|
||||||
string err = StrPrinter << "ANNOUNCE:"
|
string err = StrPrinter << "ANNOUNCE:"
|
||||||
<< "Already publishing:"
|
<< "Already publishing:"
|
||||||
<< _media_info._vhost << " "
|
<< _media_info._vhost << " "
|
||||||
<< _media_info._app << " "
|
<< _media_info._app << " "
|
||||||
<< _media_info._streamid << endl;
|
<< _media_info._streamid << endl;
|
||||||
throw SockException(Err_shutdown,err);
|
throw SockException(Err_shutdown, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto full_url = parser.FullUrl();
|
auto full_url = parser.FullUrl();
|
||||||
_content_base = full_url;
|
_content_base = full_url;
|
||||||
if(end_with(full_url,".sdp")){
|
if (end_with(full_url, ".sdp")) {
|
||||||
//去除.sdp后缀,防止EasyDarwin推流器强制添加.sdp后缀
|
//去除.sdp后缀,防止EasyDarwin推流器强制添加.sdp后缀
|
||||||
full_url = full_url.substr(0,full_url.length() - 4);
|
full_url = full_url.substr(0, full_url.length() - 4);
|
||||||
_media_info.parse(full_url);
|
_media_info.parse(full_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_media_info._app.empty() || _media_info._streamid.empty()){
|
if (_media_info._app.empty() || _media_info._streamid.empty()) {
|
||||||
//推流rtsp url必须最少两级(rtsp://host/app/stream_id),不允许莫名其妙的推流url
|
//推流rtsp url必须最少两级(rtsp://host/app/stream_id),不允许莫名其妙的推流url
|
||||||
static constexpr auto err = "rtsp推流url非法,最少确保两级rtsp url";
|
static constexpr auto err = "rtsp推流url非法,最少确保两级rtsp url";
|
||||||
sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err);
|
sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err);
|
||||||
throw SockException(Err_shutdown, StrPrinter << err << ":" << full_url);
|
throw SockException(Err_shutdown, StrPrinter << err << ":" << full_url);
|
||||||
}
|
}
|
||||||
|
|
||||||
SdpParser sdpParser(parser.Content());
|
auto onRes = [this, parser, full_url](const string &err, bool enableHls, bool enableMP4){
|
||||||
_sessionid = makeRandStr(12);
|
|
||||||
_sdp_track = sdpParser.getAvailableTrack();
|
|
||||||
if (_sdp_track.empty()) {
|
|
||||||
//sdp无效
|
|
||||||
static constexpr auto err = "sdp中无有效track";
|
|
||||||
sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err);
|
|
||||||
throw SockException(Err_shutdown,StrPrinter << err << ":" << full_url);
|
|
||||||
}
|
|
||||||
_rtcp_context.clear();
|
|
||||||
for (auto &track : _sdp_track) {
|
|
||||||
_rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate, true));
|
|
||||||
}
|
|
||||||
_push_src = std::make_shared<RtspMediaSourceImp>(_media_info._vhost, _media_info._app, _media_info._streamid);
|
|
||||||
_push_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
|
|
||||||
_push_src->setSdp(sdpParser.toString());
|
|
||||||
sendRtspResponse("200 OK");
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtspSession::handleReq_RECORD(const Parser &parser){
|
|
||||||
if (_sdp_track.empty() || parser["Session"] != _sessionid) {
|
|
||||||
send_SessionNotFound();
|
|
||||||
throw SockException(Err_shutdown, _sdp_track.empty() ? "can not find any availabe track when record" : "session not found when record");
|
|
||||||
}
|
|
||||||
auto onRes = [this](const string &err, bool enableHls, bool enableMP4){
|
|
||||||
bool authSuccess = err.empty();
|
bool authSuccess = err.empty();
|
||||||
if(!authSuccess){
|
if (!authSuccess) {
|
||||||
sendRtspResponse("401 Unauthorized", {"Content-Type", "text/plain"}, err);
|
sendRtspResponse("401 Unauthorized", {"Content-Type", "text/plain"}, err);
|
||||||
shutdown(SockException(Err_shutdown,StrPrinter << "401 Unauthorized:" << err));
|
shutdown(SockException(Err_shutdown, StrPrinter << "401 Unauthorized:" << err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//设置转协议
|
SdpParser sdpParser(parser.Content());
|
||||||
|
_sessionid = makeRandStr(12);
|
||||||
|
_sdp_track = sdpParser.getAvailableTrack();
|
||||||
|
if (_sdp_track.empty()) {
|
||||||
|
//sdp无效
|
||||||
|
static constexpr auto err = "sdp中无有效track";
|
||||||
|
sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err);
|
||||||
|
shutdown(SockException(Err_shutdown, StrPrinter << err << ":" << full_url));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_rtcp_context.clear();
|
||||||
|
for (auto &track : _sdp_track) {
|
||||||
|
_rtcp_context.emplace_back(std::make_shared<RtcpContext>(track->_samplerate, true));
|
||||||
|
}
|
||||||
|
_push_src = std::make_shared<RtspMediaSourceImp>(_media_info._vhost, _media_info._app, _media_info._streamid);
|
||||||
|
_push_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
|
||||||
_push_src->setProtocolTranslation(enableHls, enableMP4);
|
_push_src->setProtocolTranslation(enableHls, enableMP4);
|
||||||
|
_push_src->setSdp(sdpParser.toString());
|
||||||
_StrPrinter rtp_info;
|
sendRtspResponse("200 OK");
|
||||||
for(auto &track : _sdp_track){
|
|
||||||
if (track->_inited == false) {
|
|
||||||
//还有track没有setup
|
|
||||||
shutdown(SockException(Err_shutdown,"track not setuped"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rtp_info << "url=" << track->getControlUrl(_content_base) << ",";
|
|
||||||
}
|
|
||||||
|
|
||||||
rtp_info.pop_back();
|
|
||||||
sendRtspResponse("200 OK", {"RTP-Info",rtp_info});
|
|
||||||
if(_rtp_type == Rtsp::RTP_TCP){
|
|
||||||
//如果是rtsp推流服务器,并且是TCP推流,设置socket flags,,这样能提升接收性能
|
|
||||||
setSocketFlags();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
weak_ptr<RtspSession> weakSelf = dynamic_pointer_cast<RtspSession>(shared_from_this());
|
weak_ptr<RtspSession> weakSelf = dynamic_pointer_cast<RtspSession>(shared_from_this());
|
||||||
@ -297,11 +273,34 @@ void RtspSession::handleReq_RECORD(const Parser &parser){
|
|||||||
|
|
||||||
//rtsp推流需要鉴权
|
//rtsp推流需要鉴权
|
||||||
auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, _media_info, invoker, static_cast<SockInfo &>(*this));
|
auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, _media_info, invoker, static_cast<SockInfo &>(*this));
|
||||||
if(!flag){
|
if (!flag) {
|
||||||
//该事件无人监听,默认不鉴权
|
//该事件无人监听,默认不鉴权
|
||||||
GET_CONFIG(bool,toHls,General::kPublishToHls);
|
GET_CONFIG(bool, toHls, General::kPublishToHls);
|
||||||
GET_CONFIG(bool,toMP4,General::kPublishToMP4);
|
GET_CONFIG(bool, toMP4, General::kPublishToMP4);
|
||||||
onRes("",toHls,toMP4);
|
onRes("", toHls, toMP4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtspSession::handleReq_RECORD(const Parser &parser){
|
||||||
|
if (_sdp_track.empty() || parser["Session"] != _sessionid) {
|
||||||
|
send_SessionNotFound();
|
||||||
|
throw SockException(Err_shutdown, _sdp_track.empty() ? "can not find any availabe track when record" : "session not found when record");
|
||||||
|
}
|
||||||
|
|
||||||
|
_StrPrinter rtp_info;
|
||||||
|
for (auto &track : _sdp_track) {
|
||||||
|
if (track->_inited == false) {
|
||||||
|
//还有track没有setup
|
||||||
|
shutdown(SockException(Err_shutdown, "track not setuped"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rtp_info << "url=" << track->getControlUrl(_content_base) << ",";
|
||||||
|
}
|
||||||
|
rtp_info.pop_back();
|
||||||
|
sendRtspResponse("200 OK", {"RTP-Info", rtp_info});
|
||||||
|
if (_rtp_type == Rtsp::RTP_TCP) {
|
||||||
|
//如果是rtsp推流服务器,并且是TCP推流,设置socket flags,,这样能提升接收性能
|
||||||
|
setSocketFlags();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user