一、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;}