diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..eb8cf36 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.10) +project(rtc_plugins) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Boost 1.70 REQUIRED COMPONENTS python) + +include_directories(include) +include_directories(util) + +add_executable(rtc_plugins + include/IMRTCEngine.hpp + include/IMRTCEngineFactory.hpp + include/MRTCEngineDefine.hpp + include/MRTCEnginePlatForm.hpp + util/RTCContext.cpp + rtc_plugins.cpp + util/RTCContext.cpp) + +add_library(rtc_plugins_lib SHARED rtc_plugins.cpp + util/RTCContext.cpp) + +target_include_directories(rtc_plugins_lib + PRIVATE + ${Boost_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/include # 你的自定义头文件路径 +) + +# 链接库 +target_link_libraries(rtc_plugins + PRIVATE + Boost::python + ${OTHER_LIBS} # 其他依赖库(如libMRTCEngine) +) \ No newline at end of file diff --git a/rtc_plugins.cpp b/rtc_plugins.cpp index 858af84..7d4e141 100644 --- a/rtc_plugins.cpp +++ b/rtc_plugins.cpp @@ -1,11 +1,47 @@ -#include "./include/IMRTCEngine.hpp" -#include "./include/IMRTCEngineFactory.hpp" -#include "./include/MRTCEngineDefine.hpp" -#include "./include/MRTCEnginePlatForm.hpp" +#include +#include #include -#include -int main() { - std::cout << "aaaaaaaaaaaaaa" << std::endl; - return 0; + +#include "./util/RTCContext.h" + +void setPyCallback(boost::python::object callback) { + RTCContext::instance().setPyCallback(callback); } +int init(const char* selfUserId, const char* selfDisplayName, const char* selfRoomId) { + bool res = RTCContext::instance().init(selfUserId, selfDisplayName, selfRoomId); + if (res) { + return 0; + } else { + return -1; + } +} +int initRecv(const char* destRoomId, const char* srcUserId, const int16_t destChannelIndex) { + bool res = RTCContext::instance().initRecv(destRoomId, srcUserId, destChannelIndex); + if (res) { + return 0; + } else { + return -1; + } +} +int initSend(const char* destRoomId, const int16_t destChannelIndex) { + bool res = RTCContext::instance().initSend(destRoomId, destChannelIndex); + if (res) { + return 0; + } else { + return -1; + } +} +int sendCustomAudioData(const int16_t channelIndex, void* customData, int32_t sampleRate, uint64_t channelNum, + uint64_t dataLen) { + return RTCContext::instance().sendCustomAudioData(channelIndex, customData, sampleRate, channelNum, dataLen); +} + +BOOST_PYTHON_MODULE(rtc_plugins) { + namespace py = boost::python; + py::def("setPyCallback", &setPyCallback); + py::def("init", &init); + py::def("initRecv", &initRecv); + py::def("initSend", &initSend); + py::def("sendCustomAudioData", &sendCustomAudioData); +} \ No newline at end of file diff --git a/util/RTCContext.cpp b/util/RTCContext.cpp new file mode 100644 index 0000000..daf8074 --- /dev/null +++ b/util/RTCContext.cpp @@ -0,0 +1,203 @@ +#include "RTCContext.h" + +void RTCContext::onRoom(uint32_t typeId, RTCENGINE_NAMESPACE::MRTCRoomInfo& roomInfo) { + //std::cout << "RTCContext::onRoom():" << roomInfo.roomId << "," << roomInfo.displayName << "," << roomInfo.userId << "," << roomInfo.message; + std::cout << "RTCContext::onRoom()" << std::endl; + std::lock_guard lock(mutex_); + isOnRoom_ = true; +} +void RTCContext::onConsumer(uint32_t msgId, const char* roomId, const char* peerId, RTCENGINE_NAMESPACE::MRTCConsumerInfo& consumerInfo) { + std::cout << "RTCContext::onConsumer():" << consumerInfo.roomId << "," << consumerInfo.displayName << "," << consumerInfo.channelIndex; + std::lock_guard lock(mutex_); + isOnConsumer_ = true; + //std::cout << "RTCContext::onConsumer()" << std::endl; +} +void RTCContext::onRender(const char* roomId, const char* peerId, + RTCENGINE_NAMESPACE::MRTCVideoSourceType sourceType, const RTCENGINE_NAMESPACE::MRTCVideoFrame& videoFrame) { + std::cout << "RTCContext::onRender()" << std::endl; +} +void RTCContext::onCallBackMessage(uint32_t msgId, const char* msg) { + + std::lock_guard lock(mutex_); + if (msgId == (uint32_t)mrtc::JOIN_MULTI_ROOM_SUCCESS) { + std::cout << "receive join multi room callback" << msgId; + isJoinMultiRoom_ = true; + } + + std::cout << "RTCContext::onCallBackMessage(), msgId:" << msgId << ", msg:" << msg; + //std::cout << "RTCContext::onCallBackMessage()" << std::endl; +} +void RTCContext::onCallBackCustomData(RTCENGINE_NAMESPACE::MRTCCustomDataObject object) { + //std::cout << "RTCContext::onCallBackCustomData(), obj:" << object.peerId << "," << object.data << "," << object.data_length; + std::cout << "RTCContext::onCallBackCustomData()" << std::endl; +} +void RTCContext::onSoundLevelUpdate(const char* roomId, const char* peerId, uint16_t audioSourceType, + uint8_t channelIndex, uint16_t volume, int32_t vad) +{ + std::cout << "RTCContext::onSoundLevelUpdate()" << std::endl; +} +void RTCContext::onAudioProcess(const char* roomId, const char* peerId, + mrtc::MRTCAudioFrame& audioFrame, mrtc::MRTCAudioSourceType audioSourceType) +{ + std::cout << "-----------------------------------" << std::endl; + std::cout << "dataCount:" << audioFrame.dataCount << audioSourceType; + if (!py_callback_.is_none()) { + std::cout << "python callback" << std::endl; + py_callback_(audioFrame.data, audioFrame.dataCount, audioFrame.sampleRate, audioFrame.numChannels, + audioFrame.channelIndex); + } + //sendAudioData(audioFrame.channelIndex, audioFrame.data, audioFrame.sampleRate, audioFrame.numChannels, + // audioFrame.dataCount); +} +void RTCContext::onProducer(uint32_t msgId, mrtc::MRTCProducerInfo& info) +{ + std::cout << "-----------------------------------" << std::endl; + std::cout << "RTCContext::onProducer()" << std::endl; +} +bool RTCContext::init(const char* selfUserId, const char* selfDisplayName, const char* selfRoomId) +{ + mrtc::IMRTCEngineFactory * rtcFactory = mrtc::getMRTCEngineFactory(); + if (!rtcFactory) + { + return false; + } + rtcEngine_ = rtcFactory->produceMRTCEngine(); + if (!rtcEngine_) + { + return false; + } + mrtc::MRTCEngineConfig engineConfig; + strcpy(engineConfig.domain, domain); + strcpy(engineConfig.applicationId, appid); + strcpy(engineConfig.appSecrectKey, appSecrectKey); + engineConfig.port = port; + if (0 != rtcEngine_->init(engineConfig, this)) + { + std::cout << "RTCContext::instance().init() failed" << std::endl; + return false; + } + + if (0 != rtcEngine_->setUserInfo(selfUserId, selfDisplayName, selfRoomId)) + { + std::cout << "RTCContext::instance().setUserInfo() failed" << std::endl; + return false; + } + mrtc::MRTCJoinAuthority authority; + strcpy(authority.applicationId, appid); + strcpy(authority.appSecretKey, appSecrectKey); + mrtc::MRTCJoinConfig loginConfig; + if (0!= rtcEngine_->joinRoom(authority, loginConfig)) + { + std::cout << "RTCContext::instance().joinRoom() failed" << std::endl; + return false; + } + if (0 != rtcEngine_->registerListener(mrtc::MRTCListenerType::TYPE_LISTENER_ROOM, this)) + { + std::cout << "RTCContext::instance().registerListener() failed" << std::endl; + return false; + } + if (0 != rtcEngine_->registerListener(mrtc::MRTCListenerType::TYPE_LISTENER_CONSUMER, this)) + { + std::cout << "RTCContext::instance().registerListener() failed" << std::endl; + return false; + } + + return true; +} +bool RTCContext::initRecv(const char* destRoomId, const char* srcUserId, const int16_t destChannelIndex) +{ + while (!isOnConsumer_) + { + std::cout << "wait for OnConsumer" << std::endl; + sleep(3); + } + std::cout << "registerSoundLevelListener" << std::endl; + int16_t ret1 = rtcEngine_->registerSoundLevelListener(mrtc::TYPE_AUDIO_SOURCE_CUSTOM, destRoomId, + srcUserId, destChannelIndex, this); + if (0 != ret1) + { + std::cout << "RTCContext::instance().registerSoundLevelListener() inUser failed, ret:" << ret1; + return false; + } + std::cout << "muteAudio" << std::endl; + int16_t ret2 = rtcEngine_->muteAudio(destRoomId, srcUserId, mrtc::TYPE_AUDIO_SOURCE_CUSTOM, false, destChannelIndex); + if (0 != ret2) + { + std::cout << "RTCContext::instance().muteAudio() failed, ret:" << ret2; + return false; + } + std::cout << "init recv succ" << std::endl; + return true; + +} +bool RTCContext::initSend(const char* destRoomId, const int16_t destChannelIndex) +{ + while (!isOnRoom_) + { + std::cout << "wait for OnRoom" << std::endl; + sleep(3); + } + std::cout << "join multi room" << std::endl; + int16_t ret1 = rtcEngine_->joinMultiRoom(destRoomId); + if (ret1 != 0) + { + std::cout << "joinMultiRoom fail, ret:" << ret1; + return false; + } + + mrtc::MRTCAudioOption option; + strcpy(option.dstRoomId, destRoomId); + option.channelIndex = destChannelIndex; + std::cout << "startCustomAudio" << std::endl; + int16_t ret2 = rtcEngine_->startCustomAudio(option); + if (ret2 != 0) + { + std::cout << "startCustomAudio fail, ret:" << ret2; + return false; + } + std::cout << "init send succ" << std::endl; + return true; +} + +void RTCContext::destorySend(const int16_t selfChannelIndex) +{ + rtcEngine_->stopCustomAudio(selfChannelIndex); +} +int16_t RTCContext::sendAudioData(uint8_t channelIndex, const void* pData, int32_t nSampleRate, uint64_t nNumberOfChannels, uint64_t dataLength) +{ + std::lock_guard lock(mutex_); + if (pData_) + { + return rtcEngine_->sendCustomAudioData(channelIndex, pData, nSampleRate, nNumberOfChannels, dataLength); + } + return 0; +} +int16_t RTCContext::sendCustomAudioData(const int16_t channelIndex, void* customData, int32_t sampleRate, + uint64_t channelNum, uint64_t dataLen) +{ + while(!isOnRoom_ || !isJoinMultiRoom_) { + std::cout << "wait for room and multi room before send" << std::endl; + sleep(3); + } + std::lock_guard lock(mutex_); + return rtcEngine_->sendCustomAudioData(channelIndex, customData, sampleRate, channelNum, dataLen); +} +mrtc::IMRTCEngine* RTCContext::getRtcEngine() const +{ + std::lock_guard lock(mutex_); + return rtcEngine_; +} +void* RTCContext::getpData() const +{ + std::lock_guard lock(mutex_); + return pData_; +} +void RTCContext::setpData(void* pData) +{ + std::lock_guard lock(mutex_); + pData_ = pData; +} +void RTCContext::setPyCallback(boost::python::object callback) { + std::lock_guard lock(mutex_); + py_callback_ = callback; +} diff --git a/util/RTCContext.h b/util/RTCContext.h new file mode 100644 index 0000000..7c6b71a --- /dev/null +++ b/util/RTCContext.h @@ -0,0 +1,76 @@ +#include "IMRTCEngine.hpp" +#include "MRTCEngineDefine.hpp" +#include "IMRTCEngineFactory.hpp" +#include +#include +#include // C++17 +#include +#include +#include +namespace fs = std::filesystem; +#define ENV_PRODUCT +//#define SEND_MODE + +class RTCContext : + public RTCENGINE_NAMESPACE::IMRTCRoomCallBack, + public RTCENGINE_NAMESPACE::IMRTCConsumerCallBack, + public RTCENGINE_NAMESPACE::IMRTCVideoRenderCallBack, + public RTCENGINE_NAMESPACE::IMRTCMessageCallBack, + public RTCENGINE_NAMESPACE::IMRTCReceivedAudioInfoCallBack, + public RTCENGINE_NAMESPACE::IMRTCProduerCallBack +{ +public: +#ifdef ENV_PRODUCT + const char* appid = "1357389261426393088"; + const char* appSecrectKey = "gytr3qrrznsgac2lbdchfg0l4ltqx4x3nf4my0yt1dbx7riz1gnnsnhblrlc2j4o1lx4vdu495lifv8s7jyrmfxtq9lif9rusxnur5smdn5cjopstxp5dim7p52xrezp"; + const char* domain = "rtc.migu.cn"; + const unsigned short port = 34443; +#else + const char* appid = "1357413779192676352"; + const char* appSecrectKey = "q04ex8bivag3mn8ncf504t5lw4asldbc1k2rfbhoy54u7lsqqkmkzp33x0h4d9ww9z3f1deiel34m191lj4k5dc7utidom9s1izg88jhouv1bwy62q372ly9dmd63g4u"; + const char* domain = "dorytest.migu.cn"; + const unsigned short port = 34443; +#endif + static RTCContext& instance() + { + static RTCContext instance; + return instance; + } + RTCContext(const RTCContext&) = delete; + RTCContext& operator=(const RTCContext&) = delete; + mrtc::IMRTCEngine* getRtcEngine() const; + bool init(const char* selfUserId, const char* selfDisplayName, const char* selfRoomId); + bool initRecv(const char* destRoomId, const char* srcUserId, const int16_t destChannelIndex); + bool initSend(const char* destRoomId, const int16_t destChannelIndex); + + void* getpData() const; + void setpData(void* pData); + void setPyCallback(boost::python::object callback); + + int16_t sendAudioData(uint8_t channelIndex = 0, const void* pData = nullptr, int32_t nSampleRate = 48000, uint64_t nNumberOfChannels = 2, uint64_t dataLength = 0); + int16_t sendCustomAudioData(const int16_t channelIndex, void* customData, int32_t sampleRate, + uint64_t channelNum, uint64_t dataLen); + void destorySend(const int16_t selfChannelIndex); + +private: + RTCContext() + { + } + mutable std::mutex mutex_; + mrtc::IMRTCEngine * rtcEngine_ = nullptr; + void* pData_ = nullptr; + bool isOnRoom_ = false; + bool isOnConsumer_ = false; + bool isJoinMultiRoom_ = false; + boost::python::object py_callback_; + void onRoom(uint32_t typeId, RTCENGINE_NAMESPACE::MRTCRoomInfo& roomInfo); + void onConsumer(uint32_t msgId, const char* roomId, const char* peerId, RTCENGINE_NAMESPACE::MRTCConsumerInfo& consumerInfo); + void onRender(const char* roomId, const char* peerId, + RTCENGINE_NAMESPACE::MRTCVideoSourceType sourceType, const RTCENGINE_NAMESPACE::MRTCVideoFrame& videoFrame); + void onCallBackMessage(uint32_t msgId, const char* msg); + void onCallBackCustomData(RTCENGINE_NAMESPACE::MRTCCustomDataObject object); + void onSoundLevelUpdate(const char* roomId, const char* peerId, uint16_t audioSourceType,uint8_t channelIndex, uint16_t volume, int32_t vad); + void onAudioProcess(const char* roomId, const char* peerId, + mrtc::MRTCAudioFrame& audioFrame, mrtc::MRTCAudioSourceType audioSourceType); + void onProducer(uint32_t msgId, mrtc::MRTCProducerInfo& info); +};