本文介绍如何实现音视频数据的自定义加解密
原理说明
TRTC Electron SDK 从 11.7.602 版本开始,支持以动态库插件的方式,实现用户对音视频数据的自定义加密。
实现步骤:
- 基于 TRTC Electron SDK 提供的 C++ 头文件,开发自定义加解密库。
- Javascript 层调用
addPlugin()
接口添加自定义加解密插件,传入构建好的自定义加解密库文件路径;再用插件的 enable() 接口开启自定义加解密。
开发自定义加解密插件(C++)
SDK 提供了两个 C++ 头文件实现自定义加解密:
ITRTCPlugin.h
头文件声明了插件对象的创建、销毁、初始化、设置参数等接口,用于管理插件的生命周期。IMediaEncryptDecryptPlugin.h
头文件定义了监听 SDK 音视频编解码回调的接口,用于完成对音视频数据的加解密。
MediaEncryptDecryptPlugin.zip是一个示例工程,实现了一个简单的加解密插件,支持 Windows 和 Mac OS 下构建。
ITRTCPlugin.h
class ITRTCPlugin {
public:
virtual ~ITRTCPlugin() {}
/**
* 初始化插件
*
* 创建插件后,会立刻触发该初始化函数,用户可以在这里做一些初始化操作。
* @return true: 插件初始化成功,false: 插件初始化失败。
* 如果返回 false 表示初始化失败,Javascript 层通过 setPluginCallback() 函数设置回调函数会收到错误码:-4.
*/
virtual bool init() = 0;
/**
* 反初始化插件
*
* 插件销毁时,会触发该函数,用户可以在这里做一些清理操作。
*
* @return true: 插件反初始化成功,false: 插件反初始化失败。
*/
virtual bool uninit() = 0;
/**
* 资源加载
*
* 会在 init() 函数之后被调用。
*
* @param path 插件资源目录。该目录为当前插件库文件所在目录,如果插件有其它资源文件依赖,可以放在插件库文件同目录下,在这里加载。
* @return true: 资源加载成功,false: 资源加载失败。
* 如果返回 false 表示资源加载失败,Javascript 层通过 setPluginCallback() 函数设置回调函数会收到错误码:-5.
*/
virtual bool load(const char* path) = 0;
/**
* 资源卸载
*
* 会在 uninit() 函数之前被调用。
*/
virtual bool unload() = 0;
/**
* 开启/关闭当前插件
*
* Javascript 层的 TRTCPluginInfo.enable/disable() 接口调用会触发该函数。
*
* @param enabled true: 开启插件,false: 关闭插件。
* @return true: 成功开启/关闭插件,false: 失败。
*/
virtual bool enable(bool enabled) = 0;
/**
* 设置插件参数
*
* Javascript 层的 TRTCPluginInfo.setParameter() 接口调用会触发该函数。
*
* @param param 插件参数,格式为 json 字符串。
* @return true: 设置成功,false: 设置失败。
*/
virtual bool setParameter(const char* param) = 0;
/**
* 获取插件类型
*
* 具体的插件子类中需要重写。
*/
virtual TRTC_PLUGIN_TYPE getPluginType() {
return TRTC_PLUGIN_TYPE::TRTC_PLUGIN_UNKNOWN;
}
/**
* 设置错误回调函数
*
* @param callback 回调函数。是对 Javascript 层 setPluginCallback() 接口设置回调函数的封装。
*/
void setErrorCallback(PluginErrorCallbackFunc callback, void* param) {
error_callback_ = callback;
param_ = param;
}
/**
* 错误码上报函数
*
* 该函数调用后,会触发 Javascript 层 setPluginCallback() 接口设置的回调函数,将错误码和错误信息透传给 Javascript 层,用户可以根据错误码做相应处理。
*
* @param error 错误码。
* @param msg 错误描述。
*/
void onError(int error, const char* msg) {
if (error_callback_) {
error_callback_(error, msg, param_);
}
}
private:
PluginErrorCallbackFunc error_callback_ = nullptr;
void* param_ = nullptr;
};
// 创建插件实例对象,Javascript 层 addPlugin() 接口最终会调用到该函数
extern "C" EXPORTS ITRTCPlugin* createTRTCPlugin();
// 销毁插件实例对象,Javascript 层 removePlugin() 接口最终会调用到该函数
extern "C" EXPORTS void destoryTRTCPlugin(ITRTCPlugin*);
IMediaEncryptDecryptPlugin.h
struct LiteAVBuffer {
uint8_t* data;
uint32_t size;
};
struct EncodedData {
// didEncodeVideo 和 didEncodeAudio 回调时,此字段为 null;
const char* userId;
// 视频流类型,参考 TRTCVideoStreamType,audio 时,此字段为0
int streamType;
// 原始数据
LiteAVBuffer originData;
// 写回处理后的数据
LiteAVBuffer processedData;
};
class IMediaEncryptDecryptPlugin : public ITRTCPlugin {
public:
~IMediaEncryptDecryptPlugin() override {}
virtual void setMallocMemoryCallback(MallocMemory callback) = 0;
/**
* 视频编码数据回调
*/
virtual bool didEncodeVideo(EncodedData& data) = 0;
/**
* 视频解码数据回调
*/
virtual bool willDecodeVideo(EncodedData& data) = 0;
/**
* 音频编码数据回调
*/
virtual bool didEncodeAudio(EncodedData& data) = 0;
/**
* 音频解码数据回调
*/
virtual bool willDecodeAudio(EncodedData& data) = 0;
};
使用自定义加解密插件(Javascript)
通过 SDK 提供的 addPlugin()
接口创建一个自定义加解密插件,返回一个 TRTCPluginInfo
对象,调用该对象的 enable()
接口开启自定义加解密。
import TRTCCloud, { TRTCPluginType, TRTCPluginInfo } from 'trtc-electron-sdk';
const trtcCloud = TRTCCloud.getTRTCShareInstance();
// 开启自定义加解密功能
trtcCloud.setPluginParams(TRTCPluginType.TRTCPluginTypeMediaEncryptDecrypt, {
enable: true // 设置为 false 后,会停止发送音视频数据到自定义加解密插件
});
// 注册插件回调监听
trtcCloud.setPluginCallback((pluginId, errorCode, msg) => {
console.log(`plugin callback: ${pluginId}, errorCode: ${errorCode}, msg: ${msg}`);
});
// 创建加解密插件
const plugin: TRTCPluginInfo = trtcCloud.addPlugin({
id: 'custom-encrypt-decrypt-plugi', // 用户必须保证 ID 的唯一性
path: '', // 构建好的加解密库文件,Windows 下是 ‘.dll’ 文件,MacOS 下是 ‘.dylib’ 文件
type: TRTCPluginType.TRTCPluginTypeMediaEncryptDecrypt // 音视频自定义加解密插件类型
});
// 启动插件
plugin.enable();
// 设置插件参数
plugin.setParameter(JSON.stringify({'key1':'value1', 'key2':123}));
-
TRTCCloud.setPluginParams() 接口
支持通过 enable 参数控制是否开启 SDK 的加解密功能。
-
TRTCCloud.addPlugin() 接口
添加自定义插件,依次触发 C++
ITRTCPlugin.h
类中的 createTRTCPlugin()、init()、load() 函数。 -
TRTCCloud.removePlugin() 接口
删除自定义插件,依次触发 C++
ITRTCPlugin.h
类中的 unload()、uninit()、destoryTRTCPlugin() 函数。 -
TRTCCloud.setPluginCallback() 接口
设置插件回调函数,监听插件创建、销毁、运行情况。设置的回调函数有两个触发源头:
- addPlugin/removePlugin() 时的处理结果通知;
- 插件内部 C++
ITRTCPlugin.h
类中的 onError() 函数触发的异常通知。
-
TRTCPluginInfo.enable/disable() 接口
开启/关闭当前插件,触发 C++
ITRTCPlugin.h
类中的 enable() 函数。 -
TRTCPluginInfo.setParameter() 接口
给当前插件设置参数,触发 C++
ITRTCPlugin.h
类中的 setParameter() 函数。