diff --git a/CMakeLists.txt b/CMakeLists.txt index adc5f768..f562d96d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ option(ENABLE_SERVER "Enable Server" ON) option(ENABLE_SERVER_LIB "Enable server as android static library" OFF) option(ENABLE_SRT "Enable SRT" ON) option(ENABLE_TESTS "Enable Tests" ON) +option(ENABLE_SCTP "Enable SCTP" ON) option(ENABLE_WEBRTC "Enable WebRTC" ON) option(ENABLE_X264 "Enable x264" OFF) option(ENABLE_WEPOLL "Enable wepoll" ON) diff --git a/src/Record/MP4Muxer.cpp b/src/Record/MP4Muxer.cpp index 1dfa3a95..51270919 100644 --- a/src/Record/MP4Muxer.cpp +++ b/src/Record/MP4Muxer.cpp @@ -15,6 +15,7 @@ #include "Extension/G711.h" #include "Extension/H264.h" #include "Extension/H265.h" +#include "Extension/JPEG.h" #include "Common/config.h" using namespace std; @@ -145,6 +146,7 @@ static uint8_t getObject(CodecId codecId) { case CodecAAC : return MOV_OBJECT_AAC; case CodecH264 : return MOV_OBJECT_H264; case CodecH265 : return MOV_OBJECT_HEVC; + case CodecJPEG : return MOV_OBJECT_JPEG; default : return 0; } } @@ -302,6 +304,28 @@ bool MP4MuxerInterface::addTrack(const Track::Ptr &track) { break; } + case CodecJPEG: { + auto jpeg_track = dynamic_pointer_cast(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; } diff --git a/src/Rtsp/RtpMultiCaster.cpp b/src/Rtsp/RtpMultiCaster.cpp index 8504b83a..e4aaefa1 100644 --- a/src/Rtsp/RtpMultiCaster.cpp +++ b/src/Rtsp/RtpMultiCaster.cpp @@ -99,13 +99,13 @@ RtpMultiCaster::~RtpMultiCaster() { 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(MediaSource::find(RTSP_SCHEMA, vhost, app, stream)); if (!src) { auto err = StrPrinter << "未找到媒体源:" << vhost << " " << app << " " << stream << endl; throw std::runtime_error(err); } - _multicast_ip = MultiCastAddressMaker::Instance().obtain(); + _multicast_ip = (multicast_ip) ? make_shared(multicast_ip) : MultiCastAddressMaker::Instance().obtain(); if (!_multicast_ip) { throw std::runtime_error("获取组播地址失败"); } @@ -113,7 +113,7 @@ RtpMultiCaster::RtpMultiCaster(SocketHelper &helper, const string &local_ip, con for (auto i = 0; i < 2; ++i) { //创建udp socket, 数组下标为TrackType _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; throw std::runtime_error(err); } @@ -171,11 +171,11 @@ string RtpMultiCaster::getMultiCasterIP() { return SockUtil::inet_ntoa(addr); } -RtpMultiCaster::Ptr RtpMultiCaster::get(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){ +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, uint32_t multicast_ip, uint16_t video_port, uint16_t audio_port){ try { 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]() { delete ptr; }); @@ -194,12 +194,12 @@ RtpMultiCaster::Ptr RtpMultiCaster::get(SocketHelper &helper, const string &loca lock_guard lck(g_mtx); auto it = g_multi_caster_map.find(strKey); 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(); if (!ret) { 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; } diff --git a/src/Rtsp/RtpMultiCaster.h b/src/Rtsp/RtpMultiCaster.h index 022d9d83..98ce46fe 100644 --- a/src/Rtsp/RtpMultiCaster.h +++ b/src/Rtsp/RtpMultiCaster.h @@ -46,14 +46,14 @@ public: ~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); std::string getMultiCasterIP(); uint16_t getMultiCasterPort(TrackType trackType); 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: std::recursive_mutex _mtx; diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 75f64c0e..fa1bf993 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -721,7 +721,7 @@ void RtspSession::handleReq_Setup(const Parser &parser) { break; case Rtsp::RTP_MULTICAST: { 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) { send_NotAcceptable(); throw SockException(Err_shutdown, "can not get a available udp multicast socket"); diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index df2be74f..e6831b7a 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -72,6 +72,22 @@ protected: //收到RTCP包回调 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: //处理options方法,获取服务器能力 void handleReq_Options(const Parser &parser); @@ -130,7 +146,6 @@ private: void updateRtcpContext(const RtpPacket::Ptr &rtp); //回复客户端 bool sendRtspResponse(const std::string &res_code, const std::initializer_list &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标志 void setSocketFlags(); @@ -149,8 +164,6 @@ private: uint64_t _bytes_usage = 0; //ContentBase std::string _content_base; - //Session号 - std::string _sessionid; //记录是否需要rtsp专属鉴权,防止重复触发事件 std::string _rtsp_realm; //登录认证 @@ -158,8 +171,6 @@ private: //用于判断客户端是否超时 toolkit::Ticker _alive_ticker; - //url解析后保存的相关信息 - MediaInfo _media_info; //rtsp推流相关绑定的源 RtspMediaSourceImp::Ptr _push_src; //推流器所有权 @@ -180,9 +191,6 @@ private: toolkit::Socket::Ptr _rtcp_socks[2]; //标记是否收到播放的udp打洞包,收到播放的udp打洞包后才能知道其外网udp端口号 std::unordered_set _udp_connected_flags; - ////////RTP over udp_multicast//////// - //共享的rtp组播对象 - RtpMultiCaster::Ptr _multicaster; ////////RTSP over HTTP //////// //quicktime 请求rtsp会产生两次tcp连接, //一次发送 get 一次发送post,需要通过x-sessioncookie关联起来 diff --git a/webrtc/CMakeLists.txt b/webrtc/CMakeLists.txt index f2c4f65d..a00c0d36 100644 --- a/webrtc/CMakeLists.txt +++ b/webrtc/CMakeLists.txt @@ -38,6 +38,7 @@ set(LINK_LIBRARIES ${SRTP_LIBRARIES}) set(COMPILE_DEFINITIONS) set(INCLUDE_DIRECTORIES) +if(ENABLE_SCTP) find_package(SCTP QUIET) if(SCTP_FOUND) message(STATUS "found library: ${SCTP_INCLUDE_DIRS} ${SCTP_LIBRARIES}") @@ -48,6 +49,7 @@ if(SCTP_FOUND) list(APPEND LINK_LIBRARIES ${SCTP_LIBRARIES}) message(STATUS "WebRTC datachannel 功能已打开") endif() +endif() file(GLOB WEBRTC_SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp