当前位置: 首页 > backend >正文

火山 RTC 引擎11----集成创建房间、加入房间、销毁引擎 到互动项目中

一、相关基本知识

0、测试代码

	bytertc::IRTCVideo* m_video = nullptr;bytertc::IRTCRoom* m_room = nullptr;std::unique_ptr<ByteRTCEventHandler> m_handler;std::unique_ptr<ByteRTCRoomHandler> m_roomHandler;

	std::string roomid, uid, token;////roomid = "qq";//uid = "qq2";void CreateByterRtcVideo();void StartCapture();void CreateByterRtcRoom();void JoinRoom_ByteRtc();void SetVideoEncoderConfig(int nWidth,int nHeight,int nRate);int PushExternalVideoFrame(bytertc::IVideoFrame* frame);//cbvoid SetByteRtcCBS();//远端用户发流void OnSigUserPublishStream(const std::string roomid, const std::string uid, bytertc::MediaStreamType type);

1、创建引擎

//火山
void NRTCEngine::CreateByterRtcVideo()
{bytertc::LogConfig log;log.log_level = bytertc::LocalLogLevel::kInfo;bytertc::setLogConfig(log);if (m_video == nullptr) {m_handler.reset(new ByteRTCEventHandler());m_video = bytertc::createRTCVideo(g_appid.c_str(), m_handler.get(), nullptr);if (m_video == nullptr) {return;}}else {return;}CreateByterRtcRoom();SetByteRtcCBS(); //放在room之后,否则room为空StartCapture();JoinRoom_ByteRtc();}

2、创建ROOM

void NRTCEngine::CreateByterRtcRoom()
{if (m_video == nullptr) {return;}if (m_room == nullptr) {int ret = 0;QString str_error;roomid = "qq";uid ="qq2";m_roomHandler = std::make_unique<ByteRTCRoomHandler>(roomid, uid);token = Utils::generateToken(roomid, uid);m_room = m_video->createRTCRoom(roomid.c_str());if (m_room == nullptr) {return;}m_room->setRTCRoomEventHandler(m_roomHandler.get());}}

3、设置采集自定义视频

void NRTCEngine::StartCapture() {if (m_video) {m_video->startAudioCapture();int ret1 = m_video->setVideoSourceType(bytertc::kStreamIndexMain, bytertc::kVideoSourceTypeExternal/*kVideoSourceTypeExternal*/);//	m_video->startVideoCapture();}
}

4、加入房间


bool NRTCEngine::JoinRoom_ByteRtc(std::string userID) {bytertc::UserInfo uinfo;uinfo.uid = uid.c_str();uinfo.extra_info = nullptr;bytertc::RTCRoomConfig config;config.is_auto_publish = true;config.is_auto_subscribe_audio = true;config.is_auto_subscribe_video = true;config.room_profile_type = bytertc::kRoomProfileTypeCommunication;int ret = m_room->joinRoom(token.c_str(), uinfo, config);if (ret < 0) {return false;}return true;}

5、设置编码

void NRTCEngine::SetVideoEncoderConfig(int nWidth, int nHeight, int nRate)
{static int width = 0;static int height = 0;static int rate = 0;if (width == nWidth && height == nHeight&&rate==nRate)return;bytertc::VideoEncoderConfig encodeConfig;encodeConfig.width = nWidth;encodeConfig.height = nHeight;encodeConfig.frame_rate = 25;encodeConfig.encoder_preference = bytertc::kVideoEncodePreferenceBalance;m_video->setVideoEncoderConfig(encodeConfig);
}

6、发送自定义视频

int NRTCEngine::PushExternalVideoFrame(bytertc::IVideoFrame* pFrame) {int ret = m_video->pushExternalVideoFrame(pFrame);if (ret != 0) {}return ret;
}

7、设置CB


void NRTCEngine::SetByteRtcCBS() {UserPublishStreamCallback callback = [this](const std::string& roomId, const std::string& uid, bytertc::MediaStreamType type) {this->OnSigUserPublishStream(roomId, uid, type);};m_roomHandler->setUserPublishStreamCallback(callback);UserJoinedCallback joinCB = [this](const bytertc::UserInfo& user_info, int elapsed) {if (pChatForm){auto task = [this, user_info, elapsed]() {pChatForm->OnUserJoined_ByterRTC(user_info, elapsed);};Post2UI(task);}};m_roomHandler->setUserJoinedCallback(joinCB);UserLeaveCallback leaveCB = [this](const char* uid, bytertc::UserOfflineReason reason) {if (pChatForm){auto task = [this, uid, reason]() {pChatForm->OnUserLeft_ByterRTC(uid, reason);};Post2UI(task);}};m_roomHandler->setUserLeaveCallback(leaveCB);auto leaveRoomCB = [this](const bytertc::RtcRoomStats& stats) {if (pChatForm){auto task = [this,  stats]() {pChatForm->OnLeaveRoom_ByterRTC(stats);};Post2UI(task);}};m_roomHandler->setLeaveRoomCallback(leaveRoomCB);RoomStateChangedCallback RoomStateChangedCB = [this](const std::string& roomid, const std::string& uid, int state, const std::string& extra_info) {if (pChatForm){auto task = [this, roomid,uid,state, extra_info]() {pChatForm->OnJoinChannel_ByterRTC(roomid, uid, state, extra_info);};Post2UI(task);}};m_roomHandler->setRoomStateChangedCallback(RoomStateChangedCB);VideoSinkCB sinkCB = [this](bytertc::IVideoFrame* video_frame) {if (!video_frame)return false;if (pChatForm){auto task = [this, video_frame]() {pChatForm->OnFrameDataCallback_ByterRTC(video_frame);};Post2UI(task);}return true;};m_handler->setVideoSinkCB(sinkCB);
}

二、集合进网易 放在合适的位置

0、网易总体逻辑图

1、加入房间

1)、网易逻辑

1.1)、开始直播按钮

StartLiveStream();

	void ChatroomForm::StartLiveStreamBtn(){//点击开始上课按钮QLOG_APP(L"StartLiveStreamBtn");if (livestreaming_){WriteSuccessFuc("StartLiveStreamBtn ... livestreaming_ is true");return;}OnLiveStreamInit(is_Camera_);if (screen_tool_wnd_)		screen_tool_wnd_->SetCaptureWnd(cur_handle_id_, false);StartLiveStream();{start_time_stamp_ = 0;InitIntTime();}}

1.2)、切换布局时

	void ChatroomForm::Layout_ResumeLive()  //切换布局时,继续上课{if (master_){m_bQuicklyResumeAndNotSendStartLiveReq = TRUE;OnLiveStreamInit(is_Camera_);if (screen_tool_wnd_){screen_tool_wnd_->SetCaptureWnd(cur_handle_id_, false);}StartLiveStream();}}

1.3)、继续上课

	void ChatroomForm::ResumeLive() //继续上课{//继续上课时,先清空m_BypassCtrlClass.NullAllBypass();m_BypassCtrlClass.ClearAll();m_BypassCtrlClass.AutoAdjustHideShow(); //隐藏旁路控件if (master_){OnLiveStreamInit(is_Camera_);if (screen_tool_wnd_){screen_tool_wnd_->SetCaptureWnd(cur_handle_id_, false);}StartLiveStream();SetPauseRestoreText(L"暂停上课");}}

1.4)、拉流转互动时

			//停止拉流pull_stream_stopped_cb_.reset(new nbase::WeakCallback<StdClosure>(ToWeakCallback([this](){bSwitingToInt_ = true;//恢复初始状态, 主控件显示采集video_show_ctrl_->SetVideoFrameMng(&local_video_frame_mng_);video_show_ctrl_->SetAccount(GetLoginAccount());//恢复初始对应状况bypass_show_ctrl1_->SetVideoFrameMng(&nim_comp::VideoManager::GetInstance()->video_frame_mng_);bypass_show_ctrl2_->SetVideoFrameMng(&nim_comp::VideoManager::GetInstance()->video_frame_mng_);bypass_show_ctrl3_->SetVideoFrameMng(&nim_comp::VideoManager::GetInstance()->video_frame_mng_);bypass_show_ctrl4_->SetVideoFrameMng(&nim_comp::VideoManager::GetInstance()->video_frame_mng_);m_BypassCtrlClass.NullAllBypass();m_BypassCtrlClass.ClearAll();//m_BypassCtrlClass.SetMainVideoFrame(creater_id_);//开始互动StartLiveStream();pull_stream_stopped_cb_.reset();})));

2)、火山对比

这里面的核心函数就是开始互动

开始互动的操作,就是加入房间中

2.1)、核心加入房间函数

	bool ChatroomForm::StartLiveStream(){JoinChannel_NERTC(GetRoomName());return true;}

	void ChatroomForm::JoinChannel_NERTC(std::string roomid){if (BAudioLive())m_engine->SetLiveStreamMode(false);elsem_engine->SetLiveStreamMode(true);JoinChannel_NERTC(roomid, GetLoginAccount_NERTC());}

2.2)、加入房间 

2.2.1)、网易

	void ChatroomForm::JoinChannel_NERTC(std::string roomid, std::string userID){if (roomid.empty()){//有连麦者无法切换MsgboxCallback cb = [this](MsgBoxRet ret) {if (ret == MB_YES){}};ShowMsgBox(m_hWnd, L"", ToWeakCallback(cb), L"roomid 为空", L"确定", L"", L""/*, g_CefHwnd*/);return;}m_engine->SetChatForm(this); //上一个窗口析构后会置0 此处确保下if (BAudioLive()){//音频模式m_engine->setupLocalVideo(nullptr); //设置本地画布int errorCode = m_engine->joinChannel("", roomid, userID, false, true, 2);if (errorCode == 0) //调用加入房间成功{}int i = 0;i++;}else{void *hWnd = GetHWND();//		m_engine->setupLocalVideo(nullptr, onVirtualBkFrameDataCallback); //设置本地画布m_engine->setVideoDevice(kNERtcExternalVideoDeviceID);m_engine->GetRtcEngine()->setExternalVideoSource(true); //设置使用自定义数据源m_engine->enableLocalVideo(true);std::string json=ToHeadModeJson(StudentIntType_== XNWStudentIntType_HeadImg);int errorCode = m_engine->joinChannel("", roomid, userID, true, true, 2,json);if (errorCode == 0) //调用加入房间成功{}}//if (0)//{//	void *hWnd = GetHWND();//	m_engine->setupLocalVideo(hWnd); //设置本地画布//	//	int errorCode=m_engine->GetRtcEngine()->startVideoPreview();//	m_engine->joinChannel("", roomid, userID, true, true, 2);//	m_engine->enableLocalVideo(true);//}}

2.2.2)、火山

void ChatroomForm::JoinChannel_ByterRTC(std::string roomid, std::string userID){if (roomid.empty()){//有连麦者无法切换MsgboxCallback cb = [this](MsgBoxRet ret) {if (ret == MB_YES){}};ShowMsgBox(m_hWnd, L"", ToWeakCallback(cb), L"roomid 为空", L"确定", L"", L""/*, g_CefHwnd*/);return;}m_engine->SetChatForm(this); //上一个窗口析构后会置0 此处确保下m_engine->CreateByterRtcRoom(roomid, userID);m_engine->JoinRoom_ByteRtc(userID);m_engine->StartAudioCapture_ByterRTC();if (BAudioLive()){}else {void* hWnd = GetHWND();m_engine->StartVideoCapture_ByterRTC();std::string json = ToHeadModeJson(StudentIntType_ == XNWStudentIntType_HeadImg);m_engine->SendSEIMessage_ByterRTC(json);}}

3)、兼容改造

使用 g_bUseNeRtcSDK 区分 火山还是网易

JoinChannel_NERTC  改造成 JoinRoom

	void ChatroomForm::JoinRoom(std::string roomid){if (BAudioLive())m_engine->SetLiveStreamMode(false);elsem_engine->SetLiveStreamMode(true);if (g_bUseNeRtcSDK)JoinChannel_NERTC(roomid, GetLoginAccount_NERTC());elseJoinChannel_ByterRTC(roomid, GetLoginAccount_NERTC());}

2、离开房间

1)、离开房间

	void ChatroomForm::StopIntect(){  LeaveChannel_NERTC();WriteSuccessFuc("ResetStudentUI");}

2)、离开房间时机

2.1)、学生端、老师关闭了学生互动PUSH

		case SubExe_SendAnchorPushMsg:case 3://关闭学生互动if (pCurChatForm){pCurChatForm->StopIntect();}break;

2.2)、点击CEF窗口 关闭按钮时

ChatroomForm::CEF_Close(){CloseDevTool();MsgboxCallback cb = [this](MsgBoxRet ret){if (ret == MB_YES){			HideHorverForm();if (BVideoTapeMode()){bool g_bVideoTapeInWeb = true;if (!g_bVideoTapeInWeb){ui::Control* pClassingBox_videoTape = FindControl(L"ClassingBox_videoTape");if (pClassingBox_videoTape&&pClassingBox_videoTape->IsVisible())PauseLive(); //上课中,终止else{//还未上课 }ShowChatWindow(SW_HIDE);//::ShowWindow(GetHWND(), SW_HIDE);								}else{//web 播放//	m_pCefForm->LoadLocalHtml();  //窗口隐藏后,加载不成功}GetFontPage()->ShowMyClass();}else{if (!BStudentApp()){BOOL bClassing = false;ui::Control* pClassingBox_liveModel = pClassingBox_; //FindControl(L"ClassingBox_liveModel");if (pClassingBox_liveModel&&pClassingBox_liveModel->IsVisible())bClassing = TRUE;if (bClassing)PauseLive(); //上课中,终止else{//还未上课 }AudioHookForm* audioBkForm = GetAudioForm();if (audioBkForm){audioBkForm->LoadBlankWeb();}}else{if (livestreaming_){//下麦//SendStudentIntReq(StuCloseInt);StopIntect();}PausePull();}

2.3)、主动下麦

	void ChatroomForm::StudentIntEnd(){//下麦//StopIntect();}

2.4)、点击关闭按钮,返回我的课

void ChatroomForm::CloseInteractWindow()//点击关闭按钮,关闭互动窗口{if (livestreaming_){std::wstring valueStr;ReadSetIni(L"NeedPad", L"BNeed", valueStr);bool bNeed = _ttoi(valueStr.c_str());if (bNeed&&m_studentInRoomSet.size() > 0){//有连麦者无法切换MsgboxCallback cb = [this](MsgBoxRet ret){if (ret == MB_YES){}};ShowMsgBox(m_hWnd, L"有连麦者,无法关闭互动,请结束所有通话后,再试", ToWeakCallback(cb), L"提示", L"确定", L"", L""/*, g_CefHwnd*/);return;}}//关闭,返回我的课MsgboxCallback cb = [this](MsgBoxRet ret){if (ret == MB_YES){if (livestreaming_&&BStudentApp()){//学生互动中 先下麦//SendStudentIntReq(StuCloseInt);StopIntect();}//跳到我的课界面EndWndDirectly(false);}};std::wstring closeInfo;if (BStudentApp())closeInfo = L"确定要暂离直播间吗?";elsecloseInfo = L"关闭后直播将中断,确定关闭吗?";ShowMsgBox(this->GetHWND(), closeInfo, ToWeakCallback(cb), L"确认", L"确定", L"取消",L""/*,g_CefHwnd*/);}

2.5 )、关闭互动

			else if (btnText == L"关闭互动"){pBtn->SetText(L"申请互动");StopIntect();GetFontPage()->SendCopyDataMsg(GetFontPage()->m_hParentWnd, "3", SubExe_SendSendStudent); //}

3)、兼容改造

3.1)原来

	void ChatroomForm::StopIntect(){  LeaveChannel_NERTC();WriteSuccessFuc("ResetStudentUI");}

3.2)、优化

	void ChatroomForm::StopIntect(){ if(g_bUseNeRtcSDK)LeaveChannel_NERTC();elseLeaveChannel_ByterRTC();WriteSuccessFuc("StopIntect");}

	void ChatroomForm::LeaveChannel_NERTC(){//m_engine->stopLiveStream(m_currentTaskId.toUtf8());if (livestreaming_){m_engine->stopAudioMixing();m_engine->leaveChannel();m_engine->GetRtcEngine()->enableAudioVolumeIndication(false, 200);}}void ChatroomForm::LeaveChannel_ByterRTC() {if (livestreaming_){m_engine->LeaveRoom_ByterRTC();}}

void NRTCEngine::LeaveRoom_ByterRTC()
{if (m_video == nullptr) {return;}if (m_room) {m_room->leaveRoom();m_room->destroy();m_room = nullptr;}m_video->stopAudioCapture();m_video->stopVideoCapture();
}

3、销毁引擎

3.1)、原销毁引擎

void NRTCEngine::Uninit(){if (rtc_engine_){Sleep(500);//等待底层异步关闭//同步退出rtc_engine_->release(true);destroyNERtcEngine((void *&)rtc_engine_);rtc_engine_ = nullptr;}
}

3.2)、优化


void NRTCEngine::Uninit(){if (rtc_engine_){Sleep(500);//等待底层异步关闭//同步退出rtc_engine_->release(true);destroyNERtcEngine((void *&)rtc_engine_);rtc_engine_ = nullptr;}if (!g_bUseNeRtcSDK){LeaveRoom_ByterRTC();DestroyVideoRTC();}}

http://www.xdnf.cn/news/13157.html

相关文章:

  • [Java 基础]Object 类
  • 【题解-洛谷】B4292 [蓝桥杯青少年组省赛 2022] 路线
  • R语言速释制剂QBD解决方案之二
  • 网站指纹识别
  • 博图 SCL 编程技巧:灵活实现上升沿与下降沿检测案例分享(下)
  • 交通自动气象站的作用
  • [Linux] 命令行管理文件
  • 国产三维CAD皇冠CAD(CrownCAD)建模教程:压力变送器
  • 如何开发ONLYOFFICE协作空间插件:完整教程
  • AI高考志愿助手应用架构设计并上线实施运行
  • 使用python进行图像处理—图像变换(6)
  • 前端开发面试题总结-vue2框架篇(一)
  • MES系统如何解决电机制造业自动化生产管理?
  • 回溯算法学习
  • PCIe-8622工业级网卡特性解析
  • Linux中《基础IO》详细介绍
  • leetcode刷题经验
  • 云安全与网络安全:核心区别与协同作用解析
  • 统计学(第8版)——统计抽样学习笔记(考试用)
  • 使用 Python 正则表达式实现文本替换与电话号码规范化
  • 位运算求最大值的子集数目问题
  • Ace网络验证软件卡密系统-免费免搭建 记录整理
  • 如何让非 TCP/IP 协议驱动屏蔽 IPv4/IPv6 和 ARP 报文?
  • 搭建仿真yolo环境
  • Docker安装、基础知识、项目部署笔记
  • Ubuntu里面单独编译某一个模块
  • iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享
  • nacos开启鉴权密码登录
  • FFmpeg:Windows系统小白安装及其使用
  • R语言速释制剂QBD解决方案之三