You need to enable JavaScript to run this app.
文档中心
实时音视频

实时音视频

复制全文
下载 pdf
自定义视频处理
Electron 端自定义视频处理
复制全文
下载 pdf
Electron 端自定义视频处理
使用 Electron RTC SDK 时,在视频渲染和编码传输前,你可以自定义逻辑,对视频帧进行处理。​
功能简介​
适用场景​
  • 美颜特效,接入自定义美颜插件。​
  • 水印,接入自定义水印插件。​
注意:​
RTC SDK 和 CV SDK 进行了深度整合,联合提供强大且较下述方案更易集成的 RTC-CV 联合集成方案,强烈建议你使用联合方案。​
适用平台​
macOS、Windows 下的 Electron 开发框架​
适用范围​
此功能在视频处理链路的位置如下:​
​Image​​
  • 适用于:内部摄像头采集视频流、外部自定义摄像头采集视频流​
  • 不适用于:内部屏幕采集视频流、外部自定义屏幕采集视频流、静态图​
集成步骤​
你需要自行构建视频处理器插件,并编译成动态库文件。在 Electron 应用项目中,调用 Electron RTC SDK 插件相关接口,指定和使用自定义插件,完成视频自定义处理。​
1. 开发视频处理器插件​
你可以借助 插件示例项目.zip 构建自定义的视频处理插件。​
插件代码结构说明如下:​
​
.​
├──3rd​
│ ├── Common // 公共的资源​
│ │ └── assets​
│ │ ├── *.bundle. // 放模型资源​
│ ├── Mac // Mac 平台的第三方美颜库​
│ │ └── Beauty SDK ​
│ │ ├── include​
│ │ ├── lib​
│ ├── Windows // Windows 平台的第三方美颜库​
│ │ └── Beauty SDK ​
│ │ ├── include​
│ │ ├── lib​
├──scripts​
│ ├── release_win_win32.bat // 编译插件脚本​
├──src​
│ ├── common // 公共的代码,比如日志,utils 等​
│ │ └── log.h​
│ │ └── log.cpp​
│ │ └── rapidjson // rapidjson 用于解析 JSON​
│ ├── windows // Windows 平台特有的代码​
│ │ └── dllmain.cpp // Windows 动态库入口​
│ ├── IVideoPlugin.h // 定义插件,详见下文示例​
│ ├── veRTCFUPlugin.h // 定义处理器方法,详见下文示例​
│ ├── veRTCFUPlugin.cpp //实现处理器方法,详见下文示例​
├──tools // 打包工具​
│ ├── 7z.exe ​
├──CMakeLists.txt // cmake 工程文件​
​
​
  1. 引用视频插件接口头文件 IVideoPlugin.h,实现 IVideoPlugin 纯虚方法,进行视频帧前处理。​
​
/*​
* @brief 视频插件接口类​
*/​
​
#pragma once​
​
#include <stdint.h>​
#if defined(_WIN32)​
#define DLL_EXPORTS __declspec(dllexport)​
#else​
#define DLL_EXPORTS​
#endif​
​
namespace bytertc {​
/**​
* @type keytype​
* @brief 自定义视频插件帧​
*/​
struct VideoPluginFrame {​
int width; // 视频帧宽,单位:像素​
int height; // 视频帧高,单位:像素​
int yStride; // Y 数据行的长度​
int uStride; // U 数据行的长度​
int vStride; // V 数据行的长度​
uint8_t* yBuffer; // Y 数据缓冲区​
uint8_t* uBuffer; // U 数据缓冲区​
uint8_t* vBuffer; // V 数据缓冲区​
int rotation; // 视频帧旋转角度 {0, 90, 180, 270}​
int64_t timestampUs; // 视频帧时间戳,单位:微秒​
};​
​
/**​
* @type api​
* @brief 视频插件 API​
*/​
class IVideoPlugin {​
public:​
virtual bool init(const char* path) = 0;​
virtual void uninit() = 0;​
virtual bool setParameter(const char* param) = 0;​
virtual const char* getParameter(const char* key) = 0;​
virtual void release() = 0;​
​
public:​
virtual bool processVideoFrame(VideoPluginFrame* videoFrame) = 0;​
};​
}​
​
/**​
* @type type​
* @brief 定义函数类型​
*/​
typedef bytertc::IVideoPlugin* (*createByteVideoPlugin)();​
​
/**​
* @type api​
* @brief 创建插件​
*/​
extern "C" DLL_EXPORTS bytertc::IVideoPlugin* createVideoPlugin();​
​
  1. 构建 IVideoPlugin 处理器。示例代码以美颜插件为例。​
  • 视频帧的处理流程如图。​
​Image​​
将 processVideoFrame 放在一个单独的线程中。如果 OpenGL 环境不能切换线程,建议在回调里进行初始化。​
  • veRTCFUPlugin.h​
​
#pragma once​
#include "IVideoPlugin.h"​
​
class VeRTCFUPlugin : public bytertc::IVideoPlugin {​
public:​
VeRTCFUPlugin() {}​
~VeRTCFUPlugin() {}​
​
public:​
bool init(const char* path) override;​
void uninit() override;​
bool setParameter(const char* param) override;​
const char* getParameter(const char* key) override { return nullptr; } // unused​
void release() override {} // unused​
​
public: ​
bool processVideoFrame(bytertc::VideoPluginFrame* videoFrame) override;​
​
private:​
bool initEnv();​
bool initOpenGL();​
void makeCurrent();​
void doneCurrent();​
​
private:​
static bool m_envInited; ​
bool m_inited = false;​
bool m_loadBundles = false;​
bool m_updateBundles = false;​
};​
​
  • veRTCFUPlugin.cpp​
​
#include "veRTCFUPlugin.h"​
​
bytertc::IVideoPlugin* createVideoPlugin()​
{​
return new VeRTCFUPlugin();​
}​
​
bool VeRTCFUPlugin::init(const char* path)​
{​
// Add codes to initialize the plugin.​
return true;​
}​
​
void VeRTCFUPlugin::uninit()​
{​
// Add codes to release memory.​
}​
​
bool VeRTCFUPlugin::setParameter(const char* param)​
{​
// Add code to parse json string.​
return true; ​
}​
​
bool VeRTCFUPlugin::processVideoFrame(bytertc::VideoPluginFrame* videoFrame)​
{​
// Add code to process video frames​
// Initialize OpenGL. Load model, and etc.​
return true;​
}​
​
  1. 编译视频处理器插件。​
2. 注册并启动插件​
​Image​​
调用 Electron SDK 接口,注册和启动插件。​
  1. 创建引擎,开启视频采集。​
​
const { RTCEngine } = require('@volcengine/vertc-electron-sdk');​
const rtcEngine = new RTCEngine();​
rtcEngine.createRTCEngine({ app_id: APP_ID, parameters: '' });​
rtcEngine.startVideoCapture();​
​
  1. 初始化插件管理器​
​
let ret = rtcEngine.initializePluginManager();​
​
  1. 注册插件​
​
// 指定插件目录。即上一步骤中编译好的动态库文件存放路径。​
let libPath = path.resolve(__static, 'vertc-mac-x86-64-fu-plugin/libveRTCFUPlugin.dylib');​
let result = rtcEngine.registerPlugin({​
id: 'fu-mac',​
path: libPath​
});​
​
  1. 获取插件实例​
​
const plugin = rtcEngine.getPlugin('fu-mac');​
if (!plugin) {​
console.warn('plugin is null.')​
return;​
}​
​
  1. 启动插件​
​
let ret = plugin.setEnabled(true);​
​
3. 自定义视频处理​
本文以第三方美颜插件为例,说明如何将数据传入插件,进行自定义视频处理。​
JSON 字符串的 key 和 value 需要与所使用的插件进行协定,本节步骤和代码均为示例。​
  1. 授权​
​
let fuAuth = '<YOUR_AUTH_DATA_JSON_STRING>';​
plugin.setParameter(JSON.stringify({​
"plugin.fu.authdata": JSON.parse(fuAuth)​
})); ​
​
  1. 加载美颜和贴纸模型​
​
plugin.setParameter(JSON.stringify({"plugin.fu.bundles.load": [{​
bundleName: "face_beautification.bundle",​
bundleOptions: {​
"filter_name": "origin", ​
"filter_level": 1.0,​
...​
}​
},{​
bundleName: "bg_segment.bundle",​
bundleOptions: {​
"picture_path": "", ​
}​
}]}));​
​
  1. 更新美颜强度​
​
plugin.setParameter(JSON.stringify({"plugin.fu.bundles.update": {​
bundleName: "face_beautification.bundle",​
bundleOptions: {​
// 滤镜 ​
"filter_name": "lengsediao1",​
"filter_level": 1.0,​
// 美白​
"color_level": 0.3, // 0.0-1.0​
// 磨皮​
"blur_level": 4.2, // 0.0-6.0​
// 大眼​
"eye_enlarging": 0.5, // 0.0-1.0​
...​
}​
}}));​
​
  1. 更新贴纸路径​
​
let vbgPath = path.resolve(__static, 'vertc-mac-x86-64-fu-plugin/bg.png');​
plugin.setParameter(JSON.stringify({"plugin.fu.bundles.update": {​
bundleName: "bg_segment.bundle",​
bundleOptions: {​
"picture_path": vbgPath, ​
}​
}}));​
​
4. 释放插件​
调用 Electron SDK 接口,关闭插件,释放资源。​
  1. 关闭插件。插件卸载之前仍可以随时开启。​
​
let ret = plugin.setEnabled(false);​
​
  1. 卸载插件。之后可以安装其他插件。​
​
let result = rtcEngine.unregisterPlugin('fu-mac');​
​
  1. 释放插件管理器,之后无法启动所有插件。App 关闭时调用本接口释放。​
​
let ret = rtcEngine.releasePluginManager();​
​
​
最近更新时间:2026.10.08 11:23:35
这个页面对您有帮助吗?
有用
有用
无用
无用