iOS(3.3.0 and prior)

Integration Preparation

1. Download and unzip the Demo package, import the xmagic module (bundle, XmagicIconRes, Xmagic folder) from the Demo project into your actual project.
2. If the version of XMagic SDK used is 2.5.0 or earlier, import libpag.framework, Masonry.framework, XMagic.framework, YTCommonXMagic.framework from the SDK directory. If the version of XMagic SDK used is 2.5.1 or later, import libpag.framework, Masonry.framework, XMagic.framework, YTCommonXMagic.framework, Audio2Exp.framework, TEFFmpeg.framework (renamed to TECodec.framework after version 3.0.0) from the SDK directory.
3. For framework signature, select Embed & Sign for General > Masonry.framework and libpag.framework. For YTCommonXMagic.framework, select Do Not Embed for versions before 2.5.1, and select Embed & Sign for versions 2.5.1 and later.
4. Change the Bundle ID to match the applied test authorization.

Developer Environment Requirements

Developer tools XCode 14 and later: App Store or click Download link.
Recommended runtime environment:
Device requirements: iPhone 5 and above. For iPhone 6 and below, the front camera supports up to 720p, not 1080p.
System requirements: iOS 10.0 and above.

C/C++ Layer Development Environment

Xcode uses the C++ environment by default.
Type
Dependency Library
System dependent library
Accelerate
AssetsLibrary
AVFoundation
CoreMedia
CoreFoundation
CoreML
Foundation
JavaScriptCore
libc++.tbd
libz.b
libresolv.tbd
libsqlite3.0.tbd
MetalPerformanceShaders
MetalKit
MobileCoreServices
OpneAL
OpneGLES
Security
ReplayKit
SystemConfiguration
UIKit
Built-in library
YTCommon (static authentication library)
XMagic (static beauty filter library)
libpag (dynamic video decoding library)
Masonry (control layout library)
TXLiteAVSDK_Professional
TXFFmpeg (renamed TECodec.framework after version 3.0.0)
TXSoundTouch
Audio2Exp (included in xmagic sdk version 2.5.1 and later)
TEFFmpeg (included in xmagic sdk version 2.5.1 and later)

SDK API Integration

objective-c
swift
Step 1 and Step 2 can be referred to the viewDidLoad and buildBeautySDK methods of the ThirdBeautyViewController class in the Demo project; The application method in the AppDelegate class contains code for authenticating Xmagic.
From Step 4 to Step 7, please refer to the related sample code within the demo project's ThirdBeautyViewController, BeautyView class.
Step 1 can be referred to the viewDidLoad method in ThirdBeautyEnterViewController class is TE LicenseCheck.setTELicense of the Demo project.
Step 2 to Step 7 can be referred to related sample code of the ThirdBeautyViewController, BeautyView class in the Demo project.
Note
When integrating XMagic SDK into a Swift project, if the version of XMagic SDK is version3.0.0.3 and above, module referencing is supported.
import XMagic
If the version of XMagic SDK is before version3.0.0.3, the header file needs to be imported using a bridging file. The specific steps are as follows:
1. Create a bridging header file. For example, ***-Bridging-Header.h, and add the following code #import "XMagic.h".
2. Configure the BuildSetting of the project's Objective-c Bridging Header option. Set the path of the bridging file and add it to the Objective-c Bridging Header (e.g., $(SRCROOT)/SwiftCallOC/***-Bridging-Header.h, according to the specific project path), then compile and run.

Step 1. Initialize Authorization

XMagic Authorization: Set the URL and KEY in the initialization code of the related business module to trigger the License download, avoiding downloading it just before use. You can also trigger the download in the AppDelegate's didFinishLaunchingWithOptions method. Where the LicenseURL and LicenseKey are the authorization information generated when binding the License in the console. For SDK version before 2.5.1, TELicenseCheck.h is within XMagic.framework; For SDK version 2.5.1 and later, TELicenseCheck.h is within YTCommonXMagic.framework.
objective-c
swift
[TELicenseCheck setTELicense:LicenseURL key:LicenseKey completion:^(NSInteger authresult, NSString * _Nonnull errorMsg) {
if (authresult == TELicenseCheckOk) {
NSLog(@"success");
} else {
NSLog(@"failed");
}
}];
TELicenseCheck.setTELicense(LicenseURL, key: LicenseKey) { authresult, errorMsg in
if authresult == 0{
print("success")
}else{
print("failed")
}
}
Authentication errorCode Description:
Error code
Description
0
Successful
-1
Invalid input parameters. URL, KEY, etc. is empty.
-3
Download stage failed. Please check your network settings.
-4
The TE authorization information read from local is empty. It may be caused by IO failure.
-5
Content of VCUBE TEMP License file is empty. It may be caused by IO failure.
-6
JSON fields in the v_cube.license file are incorrect. Please contact the Tencent Cloud team for assistance.
-7
Signature verification failed. Please contact the Tencent Cloud team for assistance.
-8
Decryption failed. Please contact the Tencent Cloud team for assistance.
-9
JSON fields in the TELicense field are incorrect. Please contact the Tencent Cloud team for assistance.
-10
The TE authorization information parsed from the network is empty. Please contact the Tencent Cloud team for assistance.
-11
Failed to write TE authorization information to local file. It may be caused by IO failure.
-12
Download failed. Local asset parsing also failed.
-13
Authentication failed.
Other
Please contact the Tencent Cloud team for assistance.

Step 2. Set the SDK Material Resource Path

objective-c
swift
- (void)buildBeautySDK:(int)width and:(int)height texture:(unsigned)textureID {
NSDictionary *assetsDict = @{@"core_name":@"LightCore.bundle",
@"root_path":[[NSBundle mainBundle] bundlePath]};
// Initialize SDK: 'width' and 'height' are respectively the width and height of the texture.
self.xMagicKit = [[XMagic alloc] initWithRenderSize:CGSizeMake(width,height) assetsDict:assetsDict];
}
///Initialize SDK
func buildBeautySDK(width:UInt32,height:UInt32,texture:GLuint){
let assetsDict:[String:String] = ["core_name":"LightCore.bundle", "root_path":Bundle.main.bundlePath]
let sise = CGSize(width: CGFloat(width), height: CGFloat(height))
xMagic = XMagic.init(renderSize: sise, assetsDict: assetsDict)
}


Step 3. Add the Log and Event Listener

objective-c
swift
// Register log
[self.xMagicKit registerSDKEventListener:self];
[self.xMagicKit registerLoggerListener:self withDefaultLevel:YT_SDK_ERROR_LEVEL];
xMagic?.register(self)
xMagic?.registerLoggerListener(self, withDefaultLevel: YtSDKLoggerLevel.YT_SDK_DEBUG_LEVEL)

Step 4. Configure Effects (For detailed configuration instruction, please refer to Effect Parameters and Demo) .

// @brief Configure effects
// @param propertyType Effect type character string: beauty, lut, motion
// @param propertyName Effect name
// @param propertyValue Effect value
// @param extraInfo Reserved for expansion and additional dict configuration
// @return Returns 0 if successful, others if failed
- (int)configPropertyWithType:(NSString *_Nonnull)propertyType withName:(NSString *_Nonnull)propertyName withData:(NSString*_Nonnull)propertyValue withExtraInfo:(id _Nullable)extraInfo;

Step 5. Render Videos

Setting up the video data callback for third-party effect in the TRTC SDK: After setting up this callback, the TRTC SDK will return the captured video frames through the delegate you've set, allowing third-party effect components to perform secondary processing.
objective-c
swift
[self.trtcCloud setLocalVideoProcessDelegete:self pixelFormat:TRTCVideoPixelFormat_Texture_2D bufferType:TRTCVideoBufferType_Texture];
trtcCloud.setLocalVideoProcessDelegete(self, pixelFormat: TRTCVideoPixelFormat._Texture_2D, bufferType:.texture)
In the video frame callback interface onProcessVideoFrame:(TRTCVideoFrame _Nonnull)srcFrame dstFrame:(TRTCVideoFrame _Nonnull)dstFrame
construct YTProcessInput for rendering in the SDK. See ThirdBeautyViewController in the Demo.
objective-c
swift
#pragma mark - TRTCVideoFrameDelegate
- (uint32_t)onProcessVideoFrame:(TRTCVideoFrame *_Nonnull)srcFrame dstFrame:(TRTCVideoFrame *_Nonnull)dstFrame {
if (srcFrame.width != _renderSize.width || srcFrame.height != _renderSize.height) {
_renderSize = CGSizeMake(srcFrame.width, srcFrame.height);
if (!_xMagicKit) {
[self buildBeautySDK:srcFrame.width and:srcFrame.height];
} else {
[_xMagicKit setRenderSize:_renderSize];
}
}
YTProcessInput *input = [[YTProcessInput alloc] init];
input.textureData = [[YTTextureData alloc] init];
input.textureData.texture = srcFrame.textureId;
input.textureData.textureWidth = srcFrame.width;
input.textureData.textureHeight = srcFrame.height;
input.dataType = kYTTextureData;
YTProcessOutput *output = [self.xMagicKit process:input withOrigin:YtLightImageOriginTopLeft withOrientation:YtLightCameraRotation0];
dstFrame.textureId = output.textureData.texture;
return 0;
}
#pragma mark - TRTCVideoFrameDelegate

func onProcessVideoFrame(_ srcFrame: TRTCVideoFrame, dstFrame: TRTCVideoFrame) -> UInt32 {
if xMagic == nil {
buildBeautySDK(width: srcFrame.width, height: srcFrame.height, texture: srcFrame.textureId)
}
if xMagic != nil && (heightF != srcFrame.height || widthF != srcFrame.width) {
widthF = srcFrame.width
heightF = srcFrame.height
let rendersize = CGSize(width: CGFloat(srcFrame.width), height: CGFloat(srcFrame.height))
xMagic?.setRenderSize(rendersize)
}
let input = YTProcessInput.init()
input.textureData = YTTextureData.init()
input.textureData?.texture = Int32(srcFrame.textureId)
input.textureData?.textureWidth = Int32(srcFrame.width)
input.textureData?.textureHeight = Int32(srcFrame.height)
input.dataType = kYTTextureData
let output = xMagic?.process(input, with: YtLightImageOrigin(rawValue: 0)!, with: YtLightDeviceCameraOrientation(rawValue: 0)!)
dstFrame.textureId = GLuint((output?.textureData?.texture)!)
return 0
}

Step 6: Pause/Resume/Destroy SDK

objective-c
swift
//Pause SDK
[self.xMagicKit onPause];
//Resume SDK
[self.xMagicKit onResume];
//Destroy SDK
[self.xMagicKit clearListeners];
[self.xMagicKit deinit];
self.xMagicKit = nil;
//Pause SDK
xMagic?.onPause()
//Resume SDK
xMagic?.onResume()
//Destroy SDK
xMagic?.clearListeners()
xMagic?.deinit()
xMagic = nil

Step 7. Add the SDK Effect Panel to the Layout

objective-c
swift
UIEdgeInsets gSafeInset;
#if __IPHONE_11_0 && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
if(gSafeInset.bottom > 0){
}
if (@available(iOS 11.0, *)) {
gSafeInset = [UIApplication sharedApplication].keyWindow.safeAreaInsets;
} else
#endif
{
gSafeInset = UIEdgeInsetsZero;
}

dispatch_async(dispatch_get_main_queue(), ^{
// Effect option UI
self.beautyContainer = [[BeautyView alloc] init];
[self.view addSubview:self.beautyContainer];
[self.beautyContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(self.view);
make.centerX.mas_equalTo(self.view);
make.height.mas_equalTo(254);
if(gSafeInset.bottom > 0.0){ // Adapt to full-view screen
make.bottom.mas_equalTo(self.view.mas_bottom).mas_offset(0);
} else {
make.bottom.mas_equalTo(self.view.mas_bottom).mas_offset(-10);
}
}];
});
// After initializing xMagic, pass the xMagic object to beautyView
beautyView.beautyKitRef = xMagic
view.addSubview(beautyView)
beautyView.snp.makeConstraints { make in
make.height.equalTo(200)
make.bottom.equalTo(switchCamButton.snp.top).offset(10)
make.left.right.equalTo(view)
}