火山RTC 4 音視頻引擎 IRTCVideo,及 音視頻引擎事件回調接口 IRTCVideoEventHandler

一、IRTCVideo、IRTCVideoEventHandler

音視頻引擎 IRTCVideo,及 音視頻引擎事件回調接口 IRTCVideoEventHandler

負責音視頻管理、創建房間/獲得房間實例

1、創建引擎、及事件回調示例

如:

void VideoConfigWidget::initRTCVideo()
{m_handler.reset(new ByteRTCEventHandler());connect(m_handler.get(), &ByteRTCEventHandler::sigLocalVideoSizeChanged, this, &VideoConfigWidget::onSigLocalVideoSizeChanged);m_video = bytertc::createRTCVideo(g_appid.c_str(), m_handler.get(), nullptr);m_video->startAudioCapture();m_video->startVideoCapture();QStringList list = {"createRTCVideo", "startAudioCapture", "startVideoCapture"};appendAPI(list);
}

這里,關注了個本地視頻大小改變回調

? ? connect(m_handler.get(), &ByteRTCEventHandler::sigLocalVideoSizeChanged, this, &VideoConfigWidget::onSigLocalVideoSizeChanged);

1)、音視頻回調接口

/*** @locale zh* @type callback* @brief 音視頻引擎事件回調接口<br>* 注意:回調函數是在 SDK 內部線程(非 UI 線程)同步拋出來的,請不要做耗時操作或直接操作 UI,否則可能導致 app 崩潰。*/
/*** @locale en* @type callback* @brief Audio & video engine event callback interface<br>* Note: Callback functions are thrown synchronously in a non-UI thread within the SDK. Therefore, you must not perform any time-consuming operations or direct UI operations within the callback function, as this may cause the app to crash.*/
class IRTCVideoEventHandler {
public:/*** @locale zh* @type callback* @region 視頻管理* @brief 本地視頻大小或旋轉信息發生改變時,收到此回調。* @param index 流屬性。參看 StreamIndex{@link #StreamIndex}。* @param info 視頻幀信息。參看 VideoFrameInfo{@link #VideoFrameInfo}。*//*** @locale en* @type callback* @region video management* @brief Receive this callback when the local video size or rotation configuration changes.* @param index See StreamIndex{@link #StreamIndex}。* @param info Video frame information. See VideoFrameInfo{@link #VideoFrameInfo}.*/virtual void onLocalVideoSizeChanged(StreamIndex index, const VideoFrameInfo& info) {(void)index;(void)info;}

2)、派生這個回調接口類


class ByteRTCEventHandler : public QObject,public bytertc::IRTCVideoEventHandler,public bytertc::IAudioEffectPlayerEventHandler,public bytertc::IMixedStreamObserver,public bytertc::IMediaPlayerEventHandler{Q_OBJECT
public:struct Stru_RemoteStreamKey {std::string room_id;std::string user_id;bytertc::StreamIndex stream_index;};explicit ByteRTCEventHandler(QObject *parent = nullptr);~ByteRTCEventHandler();void setIsSupportClientPushStream(bool support);private://from IRTCVideoEventHandlervoid onWarning(int warn) override;void onError(int err) override;void onConnectionStateChanged(bytertc::ConnectionState state) override;void onNetworkTypeChanged(bytertc::NetworkType type) override;void onAudioDeviceStateChanged(const char* device_id, bytertc::RTCAudioDeviceType device_type,bytertc::MediaDeviceState device_state, bytertc::MediaDeviceError device_error) override;void onVideoDeviceStateChanged(const char* device_id, bytertc::RTCVideoDeviceType device_type,bytertc::MediaDeviceState device_state, bytertc::MediaDeviceError device_error) override;void onAudioDeviceWarning(const char* device_id, bytertc::RTCAudioDeviceType device_type,bytertc::MediaDeviceWarning device_warning) override;void onVideoDeviceWarning(const char* device_id, bytertc::RTCVideoDeviceType device_type,bytertc::MediaDeviceWarning device_warning) override;void onSysStats(const bytertc::SysStats& stats) override;void onLocalVideoSizeChanged(bytertc::StreamIndex index,const bytertc::VideoFrameInfo& info) override;

3)、設置signals

signals:void sigLocalVideoSizeChanged(bytertc::StreamIndex index,const bytertc::VideoFrameInfo info);

4)、綁定信息

    m_handler.reset(new ByteRTCEventHandler());connect(m_handler.get(), &ByteRTCEventHandler::sigLocalVideoSizeChanged, this, &VideoConfigWidget::onSigLocalVideoSizeChanged);

5)、收到回調 觸發信號

void ByteRTCEventHandler::onLocalVideoSizeChanged(bytertc::StreamIndex index, const bytertc::VideoFrameInfo &info)
{qDebug() << Q_FUNC_INFO << "index:" << index << ",w=" << info.width << ",h=" << info.height << ",rotation=" << info.rotation;emit sigLocalVideoSizeChanged(index, info);
}

6)、處理


void VideoConfigWidget::onSigLocalVideoSizeChanged(bytertc::StreamIndex index, const bytertc::VideoFrameInfo info)
{QString str = "onLocalVideoSizeChanged, w=" + QString::number(info.width) + ",h=" + QString::number(info.height) + ",rotation=" + QString::number(info.rotation);appendCallback(str);
}

2、本地視頻采集設置

void VideoConfigWidget::onBtnCaptureClicked()
{int ret = 0;bytertc::VideoCaptureConfig config;config.width = ui->spinBox_c_w->value(); //采集寬度config.height = ui->spinBox_c_h->value(); //采集高度config.frame_rate = ui->spinBox_c_fps->value(); //采集幀率config.capture_preference = getCapturePreference(); //采集偏好設置if (m_video) {//當分辨率或旋轉角度發生變化時,回調 onLocalVideoSizeChangedret = m_video->setVideoCaptureConfig(config);if (ret < 0) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QString("setVideoCaptureConfig error"), QMessageBox::Ok);box.exec();return;}appendAPI("setVideoCaptureConfig");}
}

3、編碼參數設置

void VideoConfigWidget::onBtnEncoderClicked()
{int ret = 0;if (m_video) {bytertc::VideoEncoderConfig config;config.width = ui->spinBox_e_w->value();config.height = ui->spinBox_e_h->value();config.frame_rate = ui->spinBox_e_fps->value();config.encoder_preference = getEncoderPreference();config.min_bitrate = ui->spinBox_e_bps_min->value();config.max_bitrate = ui->spinBox_e_bps_max->value();ret = m_video->setVideoEncoderConfig(config);if (ret < 0) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QString("setVideoEncoderConfig error"), QMessageBox::Ok);box.exec();return;}appendAPI("setVideoEncoderConfig");}
}

4、設置鏡像

void VideoConfigWidget::onComboMirrorClicked(const QString& text) //鏡像
{if (m_video) {bytertc::MirrorType type = getMirrorType();int ret = m_video->setLocalVideoMirrorType(type);if (ret < 0) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QString("setLocalVideoMirrorType error"), QMessageBox::Ok);box.exec();}appendAPI("setLocalVideoMirrorType");}
}

5、設置本地渲染

void VideoConfigWidget::onComboLocalRenderTextChanged(const QString &text) //本地渲染模式
{if (m_video) {int ret = 0;bytertc::VideoCanvas cas;cas.view = nullptr;m_video->setLocalVideoCanvas(bytertc::kStreamIndexMain, cas);cas.view = (void*)ui->widget->getWinId();cas.render_mode = getRenderMode(ui->comboBox_c_render);cas.background_color = 0xFFFFFF00;// cas.background_color = 0xFFFFFF00; //默認黑色背景ret = m_video->setLocalVideoCanvas(bytertc::kStreamIndexMain, cas);if (ret < 0) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QString("setLocalVideoCanvas error"), QMessageBox::Ok);box.exec();}appendAPI("setLocalVideoCanvas, mode=" + QString::number(cas.render_mode));}
}

6、遠端渲染設置

void VideoConfigWidget::onComboRemoteRenderTextChanged(const QString &text) //遠端渲染模式
{if (m_rendering.empty()) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QStringLiteral("沒有遠端流,無法修改渲染模式 error"), QMessageBox::Ok);box.exec();}if (m_video) {int ret = 0;bytertc::VideoCanvas cas;bytertc::RemoteStreamKey key;key.room_id = m_roomid.c_str();key.stream_index = bytertc::kStreamIndexMain;key.user_id = m_rendering.c_str();cas.background_color = 0;cas.render_mode = getRenderMode(ui->comboBox_remote_render);cas.view = nullptr;m_video->setRemoteVideoCanvas(key, cas);cas.view = (void*)ui->widget_2->getWinId();ret = m_video->setRemoteVideoCanvas(key, cas);ui->widget_2->setUserInfo(m_roomid, m_rendering);if (ret < 0) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QString("setRemoteVideoCanvas error"), QMessageBox::Ok);box.exec();}appendAPI("setRemoteVideoCanvas");}
}

7、水印

void VideoConfigWidget::onCheckWaterClicked(int state) { //水印if (m_video == nullptr) {return;}int ret = 0;bytertc::RTCWatermarkConfig config;if (ui->checkBox_water->isChecked()) {std::string path = QApplication::applicationDirPath().toStdString() + APIDemo::str_Video_Watermark;bytertc::ByteWatermark mark;config.visible_in_preview = true;mark.x = 0;mark.y = 0;mark.width = 0.1;mark.height = 0.1;config.position_in_landscape_mode = mark;config.position_in_portrait_mode = mark;ret = m_video->setVideoWatermark(bytertc::kStreamIndexMain, path.c_str(), config);if (ret < 0) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QString("setVideoWatermark error:") + QString::number(ret), QMessageBox::Ok);box.exec();}appendAPI("setVideoWatermark");}else {ret = m_video->clearVideoWatermark(bytertc::kStreamIndexMain);if (ret < 0) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QString("clearVideoWatermark error") + QString::number(ret), QMessageBox::Ok);box.exec();}appendAPI("clearVideoWatermark");}}

8、背景音樂

    bytertc::MediaPlayerConfig config;config.auto_play = true; config.callback_on_progress_interval = 500;config.play_count = 1;config.start_pos = 0;config.sync_progress_to_record_frame = true;config.type = bytertc::kAudioMixingTypePlayoutAndPublish;int ret = player->open(url.c_str(), config);appendAPI("open");if (ret < 0) {QMessageBox box(QMessageBox::Warning, QStringLiteral("提示"), QString("open error:") + QString::number(ret), QMessageBox::Ok);box.exec();return;}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75372.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75372.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75372.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端獲取不到后端新加的字段 解決方案

前端獲取不到后端新加的字段 解決方案 sql 返回的是 FileInfo 對象 private String lastUpdateTimeStr;// 自定義 setLastUpdateTime 方法&#xff0c;確保在設置 lastUpdateTime 時自動格式化為字符串public void setLastUpdateTime(LocalDateTime lastUpdateTime) {this.las…

30天學Java第九天——線程

并行與并發的區別 并行是多核 CPU 上的多任務處理&#xff0c;多個任務在同一時間真正的同時執行并發是單核 CPU 上的多任務處理&#xff0c;多個任務在同一時間段內交替執行&#xff0c;通過時間片輪轉實現交替執行&#xff0c;用于解決 IO 密集型任務的瓶頸 線程的創建方式…

論壇系統(測試報告)

文章目錄 一、項目介紹二、設計測試用例三、自動化測試用例的部分展示用戶名或密碼錯誤登錄成功編輯自己的帖子成功修改個人信息成功回復帖子信息成功 四、性能測試總結 一、項目介紹 本平臺是用Java開發&#xff0c;基于SpringBoot、SpringMVC、MyBatis框架搭建的小型論壇系統…

智膳優選 | AI賦能的智慧食堂管理專家 —— 基于飛書多維表格和扣子(Coze)的智能解決方案

智膳優選 | AI賦能的智慧食堂管理專家 基于飛書多維表格和扣子&#xff08;Coze&#xff09;的智能解決方案 數據驅動餐飲管理&#xff0c;讓每一餐都是營養與經濟的完美平衡&#xff01; “智膳優選”通過整合飛書與Coze&#xff0c;將數據智能引入校園餐飲管理&#xff0…

練習(含指針數組與數組指針的學習)

數組指針是一個指向數組的指針&#xff0c;而指針數組是一個存儲指針的數組。 ?數組指針?&#xff1a;是一個指針&#xff0c;指向一個數組的首地址&#xff0c;它用于指向整個數組&#xff0c;而不是數組中的某個元素。例如&#xff0c;int (*p)表示 p 是一個指向包含 5 個整…

NSS#Round30 Web

小桃的PHP挑戰 <?php include jeer.php; highlight_file(__FILE__); error_reporting(0); $A 0; $B 0; $C 0;//第一關 if (isset($_GET[one])){$str $_GET[str] ?? 0;$add substr($str, 0, 1); $add;if (strlen($add) > 1 ) {$A 1;} else {echo $one; } } else…

MCP基礎學習二:MCP服務搭建與配置

文章目錄 MCP服務搭建與配置一&#xff0c;學習目標&#xff1a;二&#xff0c;學習內容&#xff1a;1. 如何搭建MCP服務端服務端初始化與配置MCP服務架構與數據流交互圖核心實現注冊服務功能服務器啟動與API暴露 2. 本地應用與MCP服務的集成客戶端SDK實現客戶端應用實現功能演…

ZKmall開源商城服務端驗證:Jakarta Validation 詳解

ZKmall開源商城基于Spring Boot 3構建&#xff0c;其服務端數據驗證采用Jakarta Validation API?&#xff08;原JSR 380規范&#xff09;&#xff0c;通過聲明式注解與自定義擴展機制實現高效、靈活的數據校驗體系。以下從技術實現、核心能力、場景優化三個維度展開解析&#…

使用Docker創建postgres

準備工作&#xff1a; 1. 檢查網絡 檢查網絡連接&#xff1a;確保你的服務器網絡連接正常&#xff0c;可嘗試使用 ping 命令測試與 Docker Hub 服務器&#xff08;如 ping registry-1.docker.io&#xff09;的連通性。 ping registry-1.docker.io 檢查防火墻&#xff1a;確…

32 python json

在辦公室忙碌的日常里,我們經常需要和各種數據打交道。想象一下,你是辦公室里負責處理員工信息、項目數據的 “數據小管家”,每天都要面對大量格式各異的數據。 這時候,JSON(JavaScript Object Notation)就像是你得力的數據助手,它是一種輕量級的數據交換格式,簡單又高…

Java 實現 List<String> 與 String 互轉

在 Java 開發過程中&#xff0c;有時需要將 List<String> 轉為 String 存儲&#xff0c;后續使用時再還原回去。此時就需要 Java 實現 List<String> 與 String 互轉。以下是一種互轉方式。 采用如下工具包實現。 <dependency><groupId>org.apache.com…

NO.87十六屆藍橋杯備戰|動態規劃-完全背包|瘋狂的采藥|Buying Hay|紀念品(C++)

完全背包 先解決第?問 狀態表?&#xff1a; dp[i][j]表?&#xff1a;從前i個物品中挑選&#xff0c;總體積不超過j&#xff0c;所有的選法中&#xff0c;能挑選出來的最?價 值。&#xff08;這?是和01背包?樣噠&#xff09; 那我們的最終結果就是dp[n][V] 。狀態轉移?…

第十三天 - Ansible基礎架構 - YAML語法與Playbook - 練習:批量配置部署

Ansible自動化運維實戰&#xff1a;從入門到批量配置部署 前言&#xff1a;自動化運維的時代選擇 在服務器規模呈指數級增長的今天&#xff0c;手工操作已無法滿足運維需求。本文將手把手教你使用Ansible這個明星級自動化工具&#xff0c;通過YAML語法和Playbook實現批量配置…

Redis的過期和內存淘汰策略

文章目錄 惰性刪除定期刪除內存滿了&#xff0c;數據淘汰策略 Redis 提供了兩種刪除策略&#xff1a; 惰性刪除 、定期刪除 惰性刪除 定期刪除 兩種清除模式: 內存滿了&#xff0c;數據淘汰策略 Redis 提供了八種數據淘汰策略&#xff1a; 1. 默認是不淘汰任何的 key&#x…

用PHPExcel 封裝的導出方法,支持導出無限列

用PHPExcel 封裝的導出方法&#xff0c;支持導出無限列 避免PHPExcel_Exception Invalid cell coordinate [1 異常錯誤 /*** EXCEL導出* param [string] $file_name 保存的文件名及表格工作區名&#xff0c;不加excel后綴名* param [array] $fields 二維數組* param [array] $…

WHAT - React 元素接收的 ref 詳解

目錄 1. ref 的基本概念2. 如何使用 ref2.1 基本用法2.2 類組件使用 createRef 3. forwardRef 轉發 ref4. ref 的應用場景5. ref 和函數組件總結 在 React 中&#xff0c;ref&#xff08;引用&#xff09;用于訪問 DOM 元素或類組件實例。它允許我們直接與元素進行交互&#xf…

【QT】QT的消息盒子和對話框(自定義對話框)

QT的消息盒子和對話框&#xff08;自定義對話框&#xff09; 一、消息盒子QMessageBox1、彈出警告盒子示例代碼&#xff1a;現象&#xff1a; 2、致命錯誤盒子示例代碼&#xff1a;現象&#xff1a; 3、幫助盒子示例代碼&#xff1a;現象&#xff1a; 4、示例代碼&#xff1a; …

依靠視頻設備軌跡回放平臺EasyCVR構建視頻監控,為幼教連鎖園區安全護航

一、項目背景 幼教行業連鎖化發展態勢越發明顯。在此趨勢下&#xff0c;幼兒園管理者對于深入了解園內日常教學與生活情況的需求愈發緊迫&#xff0c;將這些數據作為提升管理水平、優化教育服務的重要依據。同時&#xff0c;安裝監控系統不僅有效緩解家長對孩子在校安全與生活…

Stable Diffusion+Pyqt5: 實現圖像生成與管理界面(帶保存 + 歷史記錄 + 刪除功能)——我的實驗記錄(結尾附系統效果圖)

目錄 &#x1f9e0; 前言 &#x1f9fe; 我的需求 &#x1f527; 實現過程&#xff08;按功能一步步來&#xff09; &#x1f6b6;?♂? Step 1&#xff1a;基本圖像生成界面 &#x1f5c3;? Step 2&#xff1a;保存圖片并顯示歷史記錄 &#x1f4cf; Step 3&#xff1a…

量子計算未來的潛力和挑戰

據麥肯錫預測&#xff0c;到 2035 年或 2040 年&#xff0c;量子計算市場規模可能增長至約 800 億美元。目前&#xff0c;許多量子比特技術正競相成為首臺通用、無差錯量子計算機的基礎&#xff0c;但仍面臨諸多挑戰。 我們將探討量子計算的未來前景、潛力&#xff0c;以及它對…