Hey @caleb.bolton,
Ok I see why this interface is so confusing now. The startPreviewWithFrame method will begin the VirtualBackground preview view, however it will not show it until the previewView from MobileRTCMeetingService is added to your view hierarchy.
So try this:
- Get into a meeting that has VB’s enabled
- Turn on your camera
- Call startPreviewWithFrame and pass in the frame of the view where you want the preview to be rendered
- Add the previewView to your view hierarchy
- The previewView should now show your standard camera stream, as if you were just viewing yourself in a meeting
- At this point you can call the other VB functions and watch the previewView update
- The previewView does not have any buttons or anything like that
Here is a pseudo viewController class that implements this:
@interface VBViewController ()
@property(nonatomic, strong) UIButton *addButton;
@property(nonatomic, strong) UIButton *removeButton;
@property(nonatomic, strong) UIButton *closeButton;
@property(nonatomic, strong) UIButton *useButton;
@end
@implementation VBViewController
@synthesize addButton, removeButton, closeButton, useButton;
- (void)viewDidLoad {
[super viewDidLoad];
MobileRTCMeetingService *ms = [[MobileRTC sharedRTC] getMeetingService];
BOOL supportVB = [ms isSupportVirtualBG];
NSLog(@"[VB Test] isSupportVirtualBG : %@.", @(supportVB));
if (!supportVB) {
return;
}
BOOL ret = [ms startPreviewWithFrame:self.view.frame];
if (!ret) {
NSLog(@"[VB Test] startPreviewWithFrame, please check camera status.");
return;
}
NSLog(@"[VB Test] startPreviewWithFrame success.");
NSLog(@"[VB Test] ms.previewView : %@.", ms.previewView);
if (ms.previewView) {
[self.view addSubview:ms.previewView];
}
[self initSubViews];
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
addButton.frame = CGRectMake(marginLeft, startY, buttonW, buttonH);
removeButton.frame = CGRectMake(marginLeft + buttonW + intervalX, startY, buttonW, buttonH);
closeButton.frame = CGRectMake(marginLeft + 2*buttonW + 2*intervalX, startY, buttonW, buttonH);
useButton.frame = CGRectMake(marginLeft + 3*buttonW + 3*intervalX, startY, buttonW, buttonH);
}
- (void)initSubViews {
MobileRTCMeetingService *ms = [[MobileRTC sharedRTC] getMeetingService];
BOOL ret = [ms isUsingGreenVB];
BOOL smartVB = [ms isSupportSmartVirtualBG];
NSLog(@"[VB Test] isUsingGreenVB : %@, isSupportSmartVirtualBG : %@", @(ret), @(smartVB));
// smartVB = 0;
if (smartVB) {
addButton = [UIButton buttonWithType:UIButtonTypeCustom];
[addButton setTitle:NSLocalizedString(@"Add", @"") forState:UIControlStateNormal];
[addButton setBackgroundColor:RGBCOLOR(0x66, 0x66, 0x66)];
[addButton setTitleColor:RGBCOLOR(45, 140, 255) forState:UIControlStateNormal];
addButton.titleLabel.font = BUTTON_FONT;
[addButton addTarget:self action:@selector(onAddButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
removeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[removeButton setTitle:NSLocalizedString(@"Remove", @"") forState:UIControlStateNormal];
[removeButton setBackgroundColor:RGBCOLOR(0x66, 0x66, 0x66)];
[removeButton setTitleColor:RGBCOLOR(45, 140, 255) forState:UIControlStateNormal];
removeButton.titleLabel.font = BUTTON_FONT;
[removeButton addTarget:self action:@selector(onRemoveButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[closeButton setTitle:NSLocalizedString(@"Close", @"") forState:UIControlStateNormal];
[closeButton setBackgroundColor:RGBCOLOR(0x66, 0x66, 0x66)];
[closeButton setTitleColor:RGBCOLOR(45, 140, 255) forState:UIControlStateNormal];
closeButton.titleLabel.font = BUTTON_FONT;
[closeButton addTarget:self action:@selector(onCloseVBButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
useButton = [UIButton buttonWithType:UIButtonTypeCustom];
[useButton setTitle:NSLocalizedString(@"Use", @"") forState:UIControlStateNormal];
[useButton setBackgroundColor:RGBCOLOR(0x66, 0x66, 0x66)];
[useButton setTitleColor:RGBCOLOR(45, 140, 255) forState:UIControlStateNormal];
useButton.titleLabel.font = BUTTON_FONT;
[useButton addTarget:self action:@selector(onUseVBButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:addButton];
[self.view addSubview:removeButton];
[self.view addSubview:closeButton];
[self.view addSubview:useButton];
} else {
MobileRTCMeetError error = [ms enableGreenVB:YES];
NSLog(@"[VB Test] enableGreenVB : %@.", @(error));
// please select one point and use the "- (MobileRTCMeetError)selectGreenVBPoint:(CGPoint)point;" pass to sdk.
}
}
- (void)onAddButtonClicked:(id)sender
{
MobileRTCMeetingService *ms = [[MobileRTC sharedRTC] getMeetingService];
if ([ms isSupportSmartVirtualBG]) {
MobileRTCMeetError ret = [ms addBGImage:[UIImage imageNamed:@"zoom_intro3"]];
NSLog(@"[VB Test] addBGImage : %@.", @(ret));
}
}
- (void)onRemoveButtonClicked:(id)sender
{
MobileRTCMeetingService *ms = [[MobileRTC sharedRTC] getMeetingService];
NSArray *imgList = [ms getBGImageList];
if ([ms isSupportSmartVirtualBG]) {
MobileRTCMeetError ret = [ms removeBGImage:[imgList lastObject]];
NSLog(@"[VB Test] removeBGImage : %@.", @(ret));
}
}
- (void)onCloseVBButtonClicked:(id)sender
{
MobileRTCMeetingService *ms = [[MobileRTC sharedRTC] getMeetingService];
if ([ms isSupportSmartVirtualBG]) {
MobileRTCMeetError ret = [ms useNoneImage];
NSLog(@"[VB Test] useNoneImage : %@.", @(ret));
}
}
- (void)onUseVBButtonClicked:(id)sender
{
MobileRTCMeetingService *ms = [[MobileRTC sharedRTC] getMeetingService];
if ([ms isSupportSmartVirtualBG]) {
NSArray *imgList = [ms getBGImageList];
for (MobileRTCVirtualBGImageInfo *obj in imgList) {
if (!obj.isNone && !obj.isSelect) {
MobileRTCMeetError ret = [ms useBGImage:obj];
NSLog(@"[VB Test] useBGImage : %@.", @(ret));
return;
}
}
}
NSLog(@"[VB Test] onUseVBButtonClicked : not found any background image");
}
@end
You can also see how this looks/works in the MobileRTCSample application that is included with the SDK download.
- Set your domain and JWT in the AppDelegate.h file in the #define macros
- Set your own provisioning profile for both the main target and screenshare target
- Disable the appgroupID’s that are checked by default
- Remove the hardcoded provisioning profile in the Build Settings of the ScreenShare target
- Build and Run
- Click the settings button in the top right
- Click Meeting Settings → turn on custom meeting
- Navigate back to the home screen
- Join a meeting
- Once in the meeting, click the Virtual Background button from the meeting settings view
- The presented viewController will show your current camera stream with a virtual background (or without). This is the preview view. The buttons at the bottom call the virtual background functions. The code for this viewController is located in the file VBViewController.m
Thanks!
Michael