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