火山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.mzph.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;以及它对…