Commit 08c47ff4 by ziyue

Merge branch 'feature/editable_rtsp_sdp' of github.com:a-ucontrol/ZLMediaKit

parents 77e46353 afa64651
...@@ -50,6 +50,7 @@ option(ENABLE_SERVER "Enable Server" ON) ...@@ -50,6 +50,7 @@ option(ENABLE_SERVER "Enable Server" ON)
option(ENABLE_SERVER_LIB "Enable server as android static library" OFF) option(ENABLE_SERVER_LIB "Enable server as android static library" OFF)
option(ENABLE_SRT "Enable SRT" ON) option(ENABLE_SRT "Enable SRT" ON)
option(ENABLE_TESTS "Enable Tests" ON) option(ENABLE_TESTS "Enable Tests" ON)
option(ENABLE_SCTP "Enable SCTP" ON)
option(ENABLE_WEBRTC "Enable WebRTC" ON) option(ENABLE_WEBRTC "Enable WebRTC" ON)
option(ENABLE_X264 "Enable x264" OFF) option(ENABLE_X264 "Enable x264" OFF)
option(ENABLE_WEPOLL "Enable wepoll" ON) option(ENABLE_WEPOLL "Enable wepoll" ON)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "Extension/G711.h" #include "Extension/G711.h"
#include "Extension/H264.h" #include "Extension/H264.h"
#include "Extension/H265.h" #include "Extension/H265.h"
#include "Extension/JPEG.h"
#include "Common/config.h" #include "Common/config.h"
using namespace std; using namespace std;
...@@ -145,6 +146,7 @@ static uint8_t getObject(CodecId codecId) { ...@@ -145,6 +146,7 @@ static uint8_t getObject(CodecId codecId) {
case CodecAAC : return MOV_OBJECT_AAC; case CodecAAC : return MOV_OBJECT_AAC;
case CodecH264 : return MOV_OBJECT_H264; case CodecH264 : return MOV_OBJECT_H264;
case CodecH265 : return MOV_OBJECT_HEVC; case CodecH265 : return MOV_OBJECT_HEVC;
case CodecJPEG : return MOV_OBJECT_JPEG;
default : return 0; default : return 0;
} }
} }
...@@ -302,6 +304,28 @@ bool MP4MuxerInterface::addTrack(const Track::Ptr &track) { ...@@ -302,6 +304,28 @@ bool MP4MuxerInterface::addTrack(const Track::Ptr &track) {
break; break;
} }
case CodecJPEG: {
auto jpeg_track = dynamic_pointer_cast<JPEGTrack>(track);
if (!jpeg_track) {
WarnL << "不是JPEG Track";
return false;
}
auto track_id = mp4_writer_add_video(_mov_writter.get(),
mp4_object,
jpeg_track->getVideoWidth(),
jpeg_track->getVideoHeight(),
nullptr,
0);
if (track_id < 0) {
WarnL << "添加JPEG Track失败:" << track_id;
return false;
}
_codec_to_trackid[track->getCodecId()].track_id = track_id;
_have_video = true;
break;
}
default: WarnL << "MP4录制不支持该编码格式:" << track->getCodecName(); return false; default: WarnL << "MP4录制不支持该编码格式:" << track->getCodecName(); return false;
} }
......
...@@ -99,13 +99,13 @@ RtpMultiCaster::~RtpMultiCaster() { ...@@ -99,13 +99,13 @@ RtpMultiCaster::~RtpMultiCaster() {
DebugL; DebugL;
} }
RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream) { 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) {
auto src = dynamic_pointer_cast<RtspMediaSource>(MediaSource::find(RTSP_SCHEMA, vhost, app, stream)); auto src = dynamic_pointer_cast<RtspMediaSource>(MediaSource::find(RTSP_SCHEMA, vhost, app, stream));
if (!src) { if (!src) {
auto err = StrPrinter << "未找到媒体源:" << vhost << " " << app << " " << stream << endl; auto err = StrPrinter << "未找到媒体源:" << vhost << " " << app << " " << stream << endl;
throw std::runtime_error(err); throw std::runtime_error(err);
} }
_multicast_ip = MultiCastAddressMaker::Instance().obtain(); _multicast_ip = (multicast_ip) ? make_shared<uint32_t>(multicast_ip) : MultiCastAddressMaker::Instance().obtain();
if (!_multicast_ip) { if (!_multicast_ip) {
throw std::runtime_error("获取组播地址失败"); throw std::runtime_error("获取组播地址失败");
} }
...@@ -113,7 +113,7 @@ RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, con ...@@ -113,7 +113,7 @@ RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, con
for (auto i = 0; i < 2; ++i) { for (auto i = 0; i < 2; ++i) {
//创建udp socket, 数组下标为TrackType //创建udp socket, 数组下标为TrackType
_udp_sock[i] = helper.createSocket(); _udp_sock[i] = helper.createSocket();
if (!_udp_sock[i]->bindUdpSock(0, local_ip.data())) { if (!_udp_sock[i]->bindUdpSock((i == TrackVideo) ? video_port : audio_port, local_ip.data())) {
auto err = StrPrinter << "绑定UDP端口失败:" << local_ip << endl; auto err = StrPrinter << "绑定UDP端口失败:" << local_ip << endl;
throw std::runtime_error(err); throw std::runtime_error(err);
} }
...@@ -171,11 +171,11 @@ string RtpMultiCaster::getMultiCasterIP() { ...@@ -171,11 +171,11 @@ 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) { 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) {
static auto on_create = [](SocketHelper &helper, const string &local_ip, const string &vhost, const string &app, const string &stream){ 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){
try { try {
auto poller = helper.getPoller(); auto poller = helper.getPoller();
auto ret = RtpMultiCaster::Ptr(new RtpMultiCaster(helper, local_ip, vhost, app, stream), [poller](RtpMultiCaster *ptr) { auto ret = RtpMultiCaster::Ptr(new RtpMultiCaster(helper, local_ip, vhost, app, stream, multicast_ip, video_port, audio_port), [poller](RtpMultiCaster *ptr) {
poller->async([ptr]() { poller->async([ptr]() {
delete ptr; delete ptr;
}); });
...@@ -194,12 +194,12 @@ RtpMultiCaster::Ptr RtpMultiCaster::get(SocketHelper &helper, const string &loca ...@@ -194,12 +194,12 @@ RtpMultiCaster::Ptr RtpMultiCaster::get(SocketHelper &helper, const string &loca
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); return on_create(helper, local_ip, vhost, app, stream, 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); return on_create(helper, local_ip, vhost, app, stream, multicast_ip, video_port, audio_port);
} }
return ret; return ret;
} }
......
...@@ -46,14 +46,14 @@ public: ...@@ -46,14 +46,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); 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);
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); 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);
private: private:
std::recursive_mutex _mtx; std::recursive_mutex _mtx;
......
...@@ -721,7 +721,7 @@ void RtspSession::handleReq_Setup(const Parser &parser) { ...@@ -721,7 +721,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._streamid); _multicaster = RtpMultiCaster::get(*this, get_local_ip(), _media_info._vhost, _media_info._app, _media_info._streamid, _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");
......
...@@ -72,6 +72,22 @@ protected: ...@@ -72,6 +72,22 @@ protected:
//收到RTCP包回调 //收到RTCP包回调
virtual void onRtcpPacket(int track_idx, SdpTrack::Ptr &track, const char *data, size_t len); virtual void onRtcpPacket(int track_idx, SdpTrack::Ptr &track, const char *data, size_t len);
//回复客户端
virtual bool sendRtspResponse(const std::string &res_code, const StrCaseMap &header = StrCaseMap(), const std::string &sdp = "", const char *protocol = "RTSP/1.0");
//url解析后保存的相关信息
MediaInfo _media_info;
////////RTP over udp_multicast////////
//共享的rtp组播对象
RtpMultiCaster::Ptr _multicaster;
//Session号
std::string _sessionid;
uint32_t _multicast_ip = 0;
uint16_t _multicast_video_port = 0;
uint16_t _multicast_audio_port = 0;
private: private:
//处理options方法,获取服务器能力 //处理options方法,获取服务器能力
void handleReq_Options(const Parser &parser); void handleReq_Options(const Parser &parser);
...@@ -130,7 +146,6 @@ private: ...@@ -130,7 +146,6 @@ private:
void updateRtcpContext(const RtpPacket::Ptr &rtp); void updateRtcpContext(const RtpPacket::Ptr &rtp);
//回复客户端 //回复客户端
bool sendRtspResponse(const std::string &res_code, const std::initializer_list<std::string> &header, const std::string &sdp = "", const char *protocol = "RTSP/1.0"); bool sendRtspResponse(const std::string &res_code, const std::initializer_list<std::string> &header, const std::string &sdp = "", const char *protocol = "RTSP/1.0");
bool sendRtspResponse(const std::string &res_code, const StrCaseMap &header = StrCaseMap(), const std::string &sdp = "", const char *protocol = "RTSP/1.0");
//设置socket标志 //设置socket标志
void setSocketFlags(); void setSocketFlags();
...@@ -149,8 +164,6 @@ private: ...@@ -149,8 +164,6 @@ private:
uint64_t _bytes_usage = 0; uint64_t _bytes_usage = 0;
//ContentBase //ContentBase
std::string _content_base; std::string _content_base;
//Session号
std::string _sessionid;
//记录是否需要rtsp专属鉴权,防止重复触发事件 //记录是否需要rtsp专属鉴权,防止重复触发事件
std::string _rtsp_realm; std::string _rtsp_realm;
//登录认证 //登录认证
...@@ -158,8 +171,6 @@ private: ...@@ -158,8 +171,6 @@ private:
//用于判断客户端是否超时 //用于判断客户端是否超时
toolkit::Ticker _alive_ticker; toolkit::Ticker _alive_ticker;
//url解析后保存的相关信息
MediaInfo _media_info;
//rtsp推流相关绑定的源 //rtsp推流相关绑定的源
RtspMediaSourceImp::Ptr _push_src; RtspMediaSourceImp::Ptr _push_src;
//推流器所有权 //推流器所有权
...@@ -180,9 +191,6 @@ private: ...@@ -180,9 +191,6 @@ private:
toolkit::Socket::Ptr _rtcp_socks[2]; toolkit::Socket::Ptr _rtcp_socks[2];
//标记是否收到播放的udp打洞包,收到播放的udp打洞包后才能知道其外网udp端口号 //标记是否收到播放的udp打洞包,收到播放的udp打洞包后才能知道其外网udp端口号
std::unordered_set<int> _udp_connected_flags; std::unordered_set<int> _udp_connected_flags;
////////RTP over udp_multicast////////
//共享的rtp组播对象
RtpMultiCaster::Ptr _multicaster;
////////RTSP over HTTP //////// ////////RTSP over HTTP ////////
//quicktime 请求rtsp会产生两次tcp连接, //quicktime 请求rtsp会产生两次tcp连接,
//一次发送 get 一次发送post,需要通过x-sessioncookie关联起来 //一次发送 get 一次发送post,需要通过x-sessioncookie关联起来
......
...@@ -38,6 +38,7 @@ set(LINK_LIBRARIES ${SRTP_LIBRARIES}) ...@@ -38,6 +38,7 @@ set(LINK_LIBRARIES ${SRTP_LIBRARIES})
set(COMPILE_DEFINITIONS) set(COMPILE_DEFINITIONS)
set(INCLUDE_DIRECTORIES) set(INCLUDE_DIRECTORIES)
if(ENABLE_SCTP)
find_package(SCTP QUIET) find_package(SCTP QUIET)
if(SCTP_FOUND) if(SCTP_FOUND)
message(STATUS "found library: ${SCTP_INCLUDE_DIRS} ${SCTP_LIBRARIES}") message(STATUS "found library: ${SCTP_INCLUDE_DIRS} ${SCTP_LIBRARIES}")
...@@ -48,6 +49,7 @@ if(SCTP_FOUND) ...@@ -48,6 +49,7 @@ if(SCTP_FOUND)
list(APPEND LINK_LIBRARIES ${SCTP_LIBRARIES}) list(APPEND LINK_LIBRARIES ${SCTP_LIBRARIES})
message(STATUS "WebRTC datachannel 功能已打开") message(STATUS "WebRTC datachannel 功能已打开")
endif() endif()
endif()
file(GLOB WEBRTC_SRC_LIST file(GLOB WEBRTC_SRC_LIST
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论