本文将为用户介绍如何在实时音视频(ARTC)中使用阿里云自主研发的美颜SDK(Queen美颜SDK)。
美颜能力介绍
阿里视频云的美颜特效SDK提供人脸美化、滤镜、贴纸及多种个性化定制服务(如动作识别和AR互动),并具有良好的跨平台兼容性,满足多终端一致性的开发需求,适用于视频直播、会议和短视频制作,提升用户体验。
更多具体功能,参见美颜特效SDK简介。
集成概览
ARTC提供了详尽的接口文档,支持第三方画面处理功能。若需接入美颜特效能力,可借助阿里云自主研发的成熟美颜SDK(Queen美颜SDK),从而实现多样化的美颜特效功能,美颜特效SDK与ARTC-SDK采用独立演进和迭代的方式开发,能够单独进行升级,因此具备快速且灵活的接入方式。
接入美颜特效的具体流程分为两步:
需完成ARTC自定义画面处理接口的配置;
调用美颜特效相关功能。
通过这一流程,用户可以高效地实现美颜功能的集成。
ARTC自定义处理接口配置
注册监听
首先通过AliRtcEngine所提供的registerVideoSampleObserver接口来注册自定义处理观察类,然后实现这个抽象类AliRtcEngine.AliRtcVideoObserver的各方法。即可在AliRtcEngine全流程链路中,进行美颜处理。
注册监听接口AliRtcVideoObserver代码示例:
mAliRtcEngine.registerVideoSampleObserver(mAliRtcVideoObserver);
根据实际业务需要,实现抽象接口类。ARTC支持本地视频采集后、本地编码前、远程视频解码后三个阶段的自定义处理。
public enum AliRtcVideoObserPosition{
/*! 采集视频数据,对应输出回调 onLocalVideoSample */
AliRtcPositionPostCapture(1),
/*! 渲染视频数据,对应输出回调 onRemoteVideoSample */
AliRtcPositionPreRender(2),
/*! 编码前视频数据,对应输出回调 onPreEncodeVideoSample */
AliRtcPositionPreEncoder(4);
}
public static abstract class AliRtcVideoObserver {
// 订阅的本地采集视频数据回调
public boolean onLocalVideoSample(AliRtcVideoSourceType sourceType, AliRtcVideoSample videoSample){
// TODO: 如果需要本地视频采集环节,需要美颜特效处理,在此处处理。
}
// 订阅的远端视频数据回调
public boolean onRemoteVideoSample(String callId,AliRtcVideoSourceType sourceType, AliRtcVideoSample videoSample){
// TODO: 如果需要远端拉取后的画面在显示之前,需要美颜特效处理,在此处处理。
}
// 订阅的本地编码前视频数据回调
public boolean onPreEncodeVideoSample(AliRtcVideoSourceType sourceType, AliRtcVideoSample videoRawData){
// TODO: 如果需要在本地视频画面进行编码之前,需要美颜特效处理,在此处处理。
}
...
public int onGetObservedFramePosition(){
// TODO: 此处根据业务需要,参照上面定义的AliRtcVideoObserPosition值,指定需要回调的处理时机。
// 例如,需要在采集和预渲染前进行自定义处理,定义以下值。
// return AliRtcVideoObserPosition.AliRtcPositionPostCapture.getValue() | AliRtcVideoObserPosition.AliRtcPositionPreRender.getValue();
}
}
美颜SDK的引入使用,根据业务需要,分别在对应的接口处理视频流即可。
关闭监听
在不需要自定义处理的情况下,可通过关闭自定义处理监听,来减少SDK层对外调用传递,提升处理效率,避免内存泄漏。
mAliRtcEngine.unRegisterVideoSampleObserver(
// TODO:作资源释放相关工作
)
美颜功能使用介绍
美颜的使用,因为涉及到GL(Open Graphics Library)上下文的使用,需要确保所有调用均在同一个线程中进行。如果不是同一个线程中进行,会因为GL上下文错乱,导致未知问题。
以下代码,均需在同一个线程中进行。
美颜初始化
QueenEngine mQueenEngine;
long lastShareglContext = 0l;
private void ensureQueenEngine(boolean sharedContext, long glShareContext) {
if (glShareContext != lastShareglContext) {
if (mQueenEngine != null) {
mQueenEngine.release();
mQueenEngine = null;
}
}
if (mQueenEngine == null) {
try {
QueenConfig queenConfig = new QueenConfig();
// 纹理模式则需要内部新建一条线程处理,否则会导致闪屏
// buffer模式直接当前线程处理,并会在当前线程上直接构建上下文
queenConfig.withNewGlThread = glShareContext > 0;
queenConfig.withContext = true;
queenConfig.shareGlContext = glShareContext;
mQueenEngine = new QueenEngine(ChartActivity.this, queenConfig);
mQueenEngine.setPowerSaving(true);
lastShareglContext = glShareContext;
} catch (Exception ex) { ex.printStackTrace(); }
}
}
美颜参数设置
private void updateQueenEngineParams() {
// 磨皮&锐化,共用一个功能开关
mQueenEngine.enableBeautyType(BeautyFilterType.kSkinBuffing, true);//磨皮开关
mQueenEngine.setBeautyParam(BeautyParams.kBPSkinBuffing, 0.5f); //磨皮 [0,1]
mQueenEngine.setBeautyParam(BeautyParams.kBPSkinSharpen, 0.6f); //锐化 [0,1]
// 美白&红润,共用一个功能开关
mQueenEngine.enableBeautyType(BeautyFilterType.kSkinWhiting, true);//美白开关
mQueenEngine.setBeautyParam(BeautyParams.kBPSkinWhitening, 0.7f); //美白范围 [0,1]
// 其他高级美颜功能开关
mQueenEngine.enableBeautyType(BeautyFilterType.kFaceBuffing, true); //高级美颜开关
mQueenEngine.setBeautyParam(BeautyParams.kBPNasolabialFolds, 0.75f); //去法令纹[0,1]
mQueenEngine.setBeautyParam(BeautyParams.kBPPouch, 0.76); //去眼袋[0,1]
// 美型
mQueenEngine.enableBeautyType(BeautyFilterType.kFaceShape, true, false, BeautyFilterMode.kBMFaceShape_Main);
mQueenEngine.updateFaceShape(FaceShapeType.typeCutFace, 0.5f); // 削脸
...
// 绿幕抠图处理
mQueenEngine.setGreenScreen("", false, 3.0f, true, BackgroundProcessType.kBackgroundTransparent);
...
}
@Override
public boolean onRemoteVideoSample(String callId, AliRtcEngine.AliRtcVideoSourceType sourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
// 若为buffer模式解码,直接修改内容到buffer。
// 若为纹理模式解码,则更新纹理id回去,因为纹理一定是2DTexture类型,类型不用回传。
ensureQueenEngine(true, videoSample.glContex);
updateQueenEngineParams();
boolean result = false;
if (videoSample.glContex > 0 && videoSample.textureid > 0) {
// 纹理模式
mQueenEngine.setInputTexture((int)videoSample.textureid, videoSample.width, videoSample.height, true);
// 输出纹理id是否已生成
int outTextId = mQueenEngine.getAutoGenOutTextureId();
if (outTextId <= 0) {
// 是否让Queen保持原纹理方向输出
mQueenEngine.autoGenOutTexture(false);
}
mQueenEngine.updateInputTextureBufferAndRunAlg(0, 0, 0, false);
int queenResult = mQueenEngine.render();
if (queenResult == 0) {
// 修改纹理id
videoSample.textureid = mQueenEngine.getAutoGenOutTextureId();
result = true;
}
} else {
// buffer模式
int queenResult = mQueenEngine.processBufferData(videoSample.data, videoSample.data, ImageFormat.I420, videoSample.width, videoSample.height, 0, 0, 0, 0);
if (queenResult == 0) {
result = true;
}
}
return result;
}
美颜关闭
在销毁自定义处理对象AliRtcVideoObserver时,关闭美颜。
// 销毁自定义处理对象时,销毁engine
if (mQueenEngine != null) {
mQueenEngine.release();
mQueenEngine = null;
}
- 本页导读 (1)
- 美颜能力介绍
- 集成概览
- ARTC自定义处理接口配置
- 注册监听
- 关闭监听
- 美颜功能使用介绍
- 美颜初始化
- 美颜参数设置
- 美颜关闭