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

火山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 IRTCVideoEventHandler
    void 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) {
        
        //当分辨率或旋转角度发生变化时,回调 onLocalVideoSizeChanged
        ret = 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;
    }

相关文章:

  • 数据结构基础(2)
  • ubuntu 服务器版本常见问题
  • Node.js多版本共存管理工具NVM(最新版本)详细使用教程(附安装包教程)
  • 重返JAVA之路-初识JAVA
  • 【android bluetooth 协议分析 01】【HCI 层介绍 1】【hci_packets.pdl 介绍】
  • 第十二天 - Flask/Django基础 - REST API开发 - 练习:运维管理后台API
  • Linux环境变量详解
  • 无人机在极端环境材料的选择
  • 热门面试题第15天|最大二叉树 合并二叉树 验证二叉搜索树 二叉搜索树中的搜索
  • 栈与队列-JS
  • 互质的数-蓝桥20245
  • 第二节:React 基础篇-受控组件 vs 非受控组件
  • springboot网站项目+layui框架动态渲染table表格数据信息
  • Apache Doris内存与超时参数配置详解
  • (四)机器学习---逻辑回归及其Python实现
  • cat命令查看文件行数
  • RK3568 基于Gstreamer的多媒体调试记录
  • 2025年工会考试题库及答案
  • 深度学习基础--CNN经典网络之InceptionV1研究与复现(pytorch)
  • 【力扣03】无重复字符的最长子串
  • openwrt安装wordpress/万词优化
  • 网站开发专业有哪些/深圳百度网站排名优化
  • 做旅游网站的目标/徐州seo外包
  • 想找人做网站/百度云客服人工电话
  • 资料网站怎么做/最打动人心的广告语
  • 睢县做网站/如何制作自己的网站教程