实时音视频
  • iOS : Objective-C
  • Android
  • macOS
  • Windows
  • HarmonyOS
  • Linux
  • Web
  • 小程序
  • Flutter
  • Electron
  • Unreal Engine
  • Unity3D
  • uni-app
  • React Native
  • Cocos Creator
  • 产品简介
  • 下载
  • 体验 App
  • 快速开始
    • 跑通示例源码
    • 集成 SDK
    • 实现视频通话
    • 场景化音视频配置
  • 通信能力
  • 房间能力
  • 音频能力
  • 视频能力
  • 直播能力
  • 其他能力
  • 最佳实践
  • 客户端 API
  • 服务端 API
  • 常见错误码
  • 常见问题
  • 文档中心
  • 实时音视频
  • 视频能力
  • 主体分割

主体分割

更新时间:2024-01-02 18:48

功能简介

主体分割是 Express SDK 提供的增值能力,通过 AI 算法识别视频画面中的内容,对每一个像素点设置透明度信息。其中,主体部分的像素点会被设置为“不透明”,主体部分之外的像素点会被设置为“透明”。开发者可以利用这些像素点的透明度信息,对画面中的主体和非主体部分做不同的处理,从而实现不同的功能。

  • 当前官网 SDK 不包含“主体分割”相关功能,如有需要,请联系 ZEGO 技术支持特殊编包,并提供您的 AppID,开通相关权限。
  • “主体分割”功能为付费功能,如需申请体验或咨询正式收费标准,请联系 ZEGO 商务人员。

主体分割对象

对身处不同环境的用户,ZEGO 提供“绿幕背景分割”和“任意背景分割”两种分割能力。

分割类型 绿幕背景分割 任意背景分割
能力描述
在用户自行架设了绿幕的情况下,可以将非绿幕区域的主体保留。

适用于电商直播、在线考试等场景。

多数用户不具备架设绿幕的条件,可以通过 ZEGO 提供的任意背景分割能力,在没有绿幕的情况下,识别画面中的主体。

适用于在线教育、视频会议等场景。

图示

功能场景

基于主体分割能力,开发者可以实现背景虚化、虚拟背景、演讲模式、多人实时同台互动等业务场景,打造更多样的互动体验。

功能点 背景虚化 虚拟背景 背景透明 主体分割与传输
功能描述
将主体外的画面做模糊处理。
将主体外的画面替换为自定义的图片、视频、颜色。
将主体的画面渲染在本端的其他视频内容上。

例如在屏幕共享或正在播放的视频等内容上,实现演讲模式等功能。

结合 Express SDK 提供的 Alpha 通道数据传输能力,将画面中分割出的主体传输到拉流端,在拉流端做主体渲染,实现多人异地实时同处于一个场景中的视觉效果
图示

硬件兼容性

平台 硬件要求
Android
  • 骁龙芯片:

    • 骁龙 6 系列:骁龙 675 及以上
    • 骁龙 7 系列:骁龙 730 及以上
    • 骁龙 8 系列:骁龙 835 及以上
  • 海思麒麟芯片:

    • 麒麟 8 系列:麒麟 820 及以上
    • 麒麟 9 系列:麒麟 980 及以上
  • 联发科芯片:

    • Helio P 系列:Helio P60 及以上
    • 天玑系列:天玑 820 及以上
  • 三星芯片:Exynos 1080 及以上
iOS
A 系列芯片:Apple A9 及以上,例如 iPhone 6s
macOS
M 系列芯片:Apple M1 及以上
Windows
Intel Core i5 及以上

示例源码

请参考 下载示例源码 获取源码。

相关源码请查看 “/ZegoExpressExample/Examples/Others/VideoObjectSegmentation” 目录下的文件。

前提条件

在使用主体分割功能前,请确保:

实现流程

开启主体分割功能会额外消耗系统资源,为了保证用户体验,目前仅支持对一路通道推流画面开启主体分割。

请注意,开发者可根据自己的业务场景需要,选择是否实现上图中的 (可选) 步骤。如需实现,请参考下文中的具体说明。

1 初始化和登录房间

初始化和登录房间的具体流程,请参考实现视频通话文档中的 “3.1 创建引擎”及“3.2 登录房间”。

2 对 view 进行特殊设置

在开启主体分割前,需要设置用于渲染的 view,即调用 setBackgroundColorbackgroundColor 属性设置为 clearColor

@property (weak, nonatomic) IBOutlet UIView *view;
[self.view setBackgroundColor:UIColor.clearColor];

3 (可选)实现自定义渲染类

实现自定义渲染类

开发者可根据实际情况进行自定义渲染,需要注意视频原始数据中包含 Alpha 通道,且原始数据没有经过 Alpha 预乘处理。以绘制 UIImage 方式渲染采集数据为例:

不能在回调中直接渲染,因为会阻塞回调线程,导致渲染异常。
- (void)onCapturedVideoFrameRawData:(unsigned char * _Nonnull *)data dataLength:(unsigned int *)dataLength param:(ZegoVideoFrameParam *)param flipMode:(ZegoVideoFlipMode)flipMode channel:(ZegoPublishChannel)channel {
    if (param.format == ZegoVideoFrameFormatBGRA32) {
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
        CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, data[0], dataLength[0], NULL);

        CGImageRef cgImageFromBytes = CGImageCreate((int)param.size.width, (int)param.size.height, 8, 32, param.strides[0], colorSpace, kCGImageByteOrder32Little|kCGImageAlphaFirst, dataProvider, NULL, NO, kCGRenderingIntentDefault);

        UIImage *image = [UIImage imageWithCGImage:cgImageFromBytes];

        // 将 image 绘制到渲染视图上
        dispatch_async(dispatch_get_main_queue(), ^{
            self.previewView.image = image;
            CGImageRelease(cgImageFromBytes);
        });
    }
}

4 (可选)开启自定义渲染

开启自定义渲染

调用 enableCustomVideoRender 接口,设置引擎进阶配置并开启自定义渲染,同时调用 setCustomVideoRenderHandler 接口设置自定义视频渲染回调,详情请参考 自定义视频渲染

使用自定义渲染进行主体分割时,bufferType 仅支持 ZegoVideoBufferType.RAW_DATA 类型。

ZegoCustomVideoRenderConfig *renderConfig = [[ZegoCustomVideoRenderConfig alloc] init];
renderConfig.bufferType = ZegoVideoBufferTypeRawData;// 选择 RAW_DATA 类型视频帧数据
renderConfig.frameFormatSeries = ZegoVideoFrameFormatSeriesRGB;// 选择 RGB 色系数据格式
[[ZegoExpressEngine sharedEngine] enableCustomVideoRender:YES config:renderConfig];//开始自定义视频渲染
[[ZegoExpressEngine sharedEngine] setCustomVideoRenderHandler:self];//设置自定义视频渲染回调

5 监听主体分割状态回调

调用 onVideoObjectSegmentationStateChanged 接口,监听主体分割状态回调。

主体分割的状态回调依赖于开启预览或者推流,即如需监听 onVideoObjectSegmentationStateChanged 回调,需要调用预览 startPreview 或推流 startPublishingStream

-(void)onVideoObjectSegmentationStateChanged:(ZegoObjectSegmentationState)state channel:(ZegoPublishChannel)channel errorCode:(int)errorCode{
    if(state == ZegoObjectSegmentationStateOn){
        //主体分割开启
    }else{
        //主体分割关闭
        //异常关闭,请查看错误码
    }
}

6 使用主体分割实现不同的业务功能

开发者如需更新主体分割类型、背景处理类型,需要修改 ZegoObjectSegmentationConfig 的配置,并再次调用 enableVideoObjectSegmentation 接口开启主体分割,即可更新主体分割效果;更新结果将通过 onVideoObjectSegmentationStateChanged 回调通知给开发者。

背景虚化

使用主体分割实现背景虚化

调用 enableVideoObjectSegmentation 接口,开启主体分割,并设置背景处理类型为“虚化”。

ZegoObjectSegmentationConfig *config = [[ZegoObjectSegmentationConfig alloc]init];
config.objectSegmentationType = ZegoObjectSegmentationTypeAnyBackground;//根据实际情况选择需要开启的主体分割类型
config.backgroundConfig.processType = ZegoBackgroundProcessTypeBlur;//设置背景处理方式为虚化
config.backgroundConfig.blurLevel = ZegoBackgroundBlurLevelMedium;//设置背景虚化级别为中
[[ZegoExpressEngine sharedEngine]enableVideoObjectSegmentation:YES config:config channel:ZegoPublishChannelMain];//开启主体分割

虚拟背景

使用主体分割实现虚拟背景

虚拟背景支持两种类型素材:

  • 图片。
  • 视频,限制如下:
    • 视频格式:MP4、FLV、MKV、AVI。
    • 视频源:本地视频。
    • 视频播放方式:循环播放。
    • 分辨率:最大不超过 4096 px,推荐 1920 px 以内。
    • 视频时长:最大不超过 30 秒,推荐 15 秒以内。
    • 视频大小:最大不超过 50 MB,推荐 10 MB 以内。

开发者在使用本功能时,请注意自定义图片、视频素材的宽高比,否则超出视图的部分会被裁减。

调用 enableVideoObjectSegmentation 接口,开启主体分割,并设置背景处理类型为“图片”或“视频”。

ZegoObjectSegmentationConfig *config = [[ZegoObjectSegmentationConfig alloc]init];
config.objectSegmentationType = ZegoObjectSegmentationTypeAnyBackground;//根据实际情况选择需要开启的主体分割类型

//设置背景处理方式为 图片
config.backgroundConfig.processType = ZegoBackgroundProcessTypeImage;
config.backgroundConfig.imageUrl= @"<image_path>";//设置背景图片路径
[[ZegoExpressEngine sharedEngine]enableVideoObjectSegmentation:YES config:config channel:ZegoPublishChannelMain];//开启主体分割

//设置背景处理方式为 视频
config.backgroundConfig.processType = ZegoBackgroundProcessTypeVideo;
config.backgroundConfig.videoURL= @"<video_path>";//设置背景视频路径
[[ZegoExpressEngine sharedEngine]enableVideoObjectSegmentation:YES config:config channel:ZegoPublishChannelMain];//开启主体分割

透明背景

使用主体分割实现透明背景

如果开发者需要实现类似“演讲模式”的业务功能,需要在业务侧将“主体画面”与“要混合的视频源内容”混为一条视频流。

调用 enableVideoObjectSegmentation 接口,开启主体分割,并设置背景处理类型为“透明”。

ZegoObjectSegmentationConfig *config = [[ZegoObjectSegmentationConfig alloc]init];
config.objectSegmentationType = ZegoObjectSegmentationTypeAnyBackground;//根据实际情况选择需要开启的主体分割类型
config.backgroundConfig.processType = ZegoBackgroundProcessTypeTransparent;//设置背景处理方式为透明
[[ZegoExpressEngine sharedEngine]enableVideoObjectSegmentation:YES config:config channel:ZegoPublishChannelMain];//开启主体分割

7 (可选)使用 Alpha 通道传输分割出的主体

使用 Alpha 通道传输分割出的主体

如果推流端需要把分割后的主体画面通过 Alpha 通道传输到拉流端,在拉流端做主体渲染,需要先调用 enableAlphaChannelVideoEncoder 接口,设置编码器支持透明通道,然后调用 startPublishingStream 接口推流,使其顺利传输至拉流端。

目前仅支持透明通道数据排列在 RGB 或 YUV 数据下方。

  • 开启 Alpha 通道数据传输:

    ZegoAlphaLayoutType layoutType = ZegoAlphaLayoutTypeBottom; // 透明通道数据排列在 RGB 或 YUV 数据下方
    [[ZegoExpressEngine sharedEngine]enableAlphaChannelVideoEncoder:YES alphaLayout:layoutType channel:ZegoPublishChannelMain]; // 设置编码器支持透明通道
  • 关闭 Alpha 通道数据传输:

    ZegoAlphaLayoutType layoutType = ZegoAlphaLayoutTypeBottom; // 透明通道数据排列在 RGB 或 YUV 数据下方
    [[ZegoExpressEngine sharedEngine]enableAlphaChannelVideoEncoder:NO alphaLayout:layoutType channel:ZegoPublishChannelMain]; // 设置编码器支持透明通道

8 开始预览和推流

通过 enableVideoObjectSegmentation 接口开启主体分割功能后,可以进行预览。

开发者也可以先开启预览,再开启主体分割。本文以先开启主体分割,再进行预览为例进行介绍。

  • 方式 1:使用内部渲染

    若使用内部渲染,开启预览前,请设置 alphaBlend 为 YES。

    ZegoCanvas *previewCanvas = [ZegoCanvas canvasWithView:self.previewView];
    previewCanvas.alphaBlend = YES;//开启内部渲染 Alpha 混合,开启后支持分割后的主体与背景图层进行 Alpha 混合
    [[ZegoExpressEngine sharedEngine]startPreview:previewCanvas];
    [[ZegoExpressEngine sharedEngine] startPublishingStream:streamID];
  • 方式 2:使用自定义渲染

    若使用自定义渲染,可直接进行预览和推流。

    [[ZegoExpressEngine sharedEngine] startPreview:nil];
    [[ZegoExpressEngine sharedEngine] startPublishingStream:streamID];

9(可选)在拉流端设置 Alpha 通道渲染并拉流

在拉流端设置 Alpha 通道渲染,并开启拉流

推流端开启了 Alpha 通道传输的情况下,才需要在拉流端开启 Alpha 通道渲染。

  • 方式 1:使用内部渲染

    如果使用内部渲染,拉流端在调用 startPlayingStream 接口开启拉流前,需要将 ZegoCanvasalphaBlend 属性设置为 YES。

    ZegoCanvas *playCanvas = [ZegoCanvas canvasWithView:self.playView1];
    playCanvas.alphaBlend = YES;//开启内部渲染 Alpha 混合,开启后支持分割后的主体与背景图层进行 Alpha 混合
    [[ZegoExpressEngine sharedEngine]startPlayingStream:streamID  canvas:playCanvas];
  • 方式 2:使用自定义渲染

    若使用自定义渲染,可直接进行拉流。

    [[ZegoExpressEngine sharedEngine]startPlayingStream:streamID canvas:nil];

10 关闭主体分割

调用 enableVideoObjectSegmentation 接口,关闭主体分割。

ZegoObjectSegmentationType objectType = ZegoObjectSegmentationTypeAnyBackground;//根据实际情况选择需要关闭的主体分割类型
[[ZegoExpressEngine sharedEngine]enableVideoObjectSegmentation:NO type:objectType channel:ZegoPublishChannelMain];//关闭主体分割

11 销毁引擎

调用 destroyEngine 接口,销毁引擎。

[ZegoExpressEngine destroyEngine:nil];
本篇目录