Meishe AR Face Filter
This topic describes how to integrate and use the Meishe AR Face Filter
plugin in Agroa WebRTC project.
Precondition
Before you begin, ensure that the following requirements are met:
- For Windows or macOS computers, the following requirements must be met:
- PC browser version: ipad and pad devices are not supported.
- Chrome,Opera,360 browser: the kernel is Chrome, version 75 includes more than support;
- Firefox browser: The kernel version is greater than 58, including the above support (special cases: version 72 is not supported);
- Safari browser: minimum 15.4, 17.0 and above the best performance, recommended to the latest version
- Physical audio and video acquisition equipment.
- Internet connection possible. If you have a firewall deployed in your network environment, see Dealing with Firewall restrictions to use the sound network service normally.
- Installed Node.js and npm。
Integration And Invocation
1. Integrate SDK and plugin
To get started, you need to integrate the Agora SDK
and Meishe AR Face Filter
plug-ins into your project.
tip:
The authentication files, template package files, model package files, and packet files in all the following examples can be obtained by contacting meishe Business.
1.1 Integration with Agora Video SDK
The Meishe AR Face Filter
plugin needs to work with the Agora Web SDK
4.x (v4.10.0 or later). Refer to the following documentation to integrate the Web SDK and implement basic video calling:
Implement audio and video calls
1.2 Integrated plugin
Follow these steps to integrate plug-ins:
Integrate the Meishe AR Face Filter
plugin into your project via npm.
Run the following command to install the plug-in:
typescriptnpm i agora-meishe-effect-sdk
Add the following code to your
.ts
file to import the plug-in module:typescriptimport { EffectSDKExtension, EffectSDKProcessor } from 'agora-meishe-effect-sdk'
2. Configure Meishe AR Face Filter plugin environment
The Meishe AR Face Filter
plugin needs to configure the response header to make the SharedArrayBuffer available.
2.1 Vite environment
The following configuration is added to the configuration plugins in vite.config.ts
:
plugins:[
{
name: 'configure-response-headers',
configureServer: (server) => {
server.middlewares.use((_req, res, next) => {
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin')
next()
})
},
configurePreviewServer: (server) => {
server.middlewares.use((_req, res, next) => {
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin')
next()
})
},
},
...
]
2.2 Webpack environment
Add the following configuration to webpack.config.ts
configuration plugins:
devServer:{
headers: {
'Cross-Origin-Opener-Policy':'same-origin',
'Cross-Origin-Embedder-Policy':'require-corp',
'Cross-Origin-Resource-Policy': 'cross-origin'
},
...
}
The purpose of adding the above configuration is to add the above setting to the request header to notify the browser to open the SharedArrayBuffer.
The above syntax is affected by webpack
and vite
versions, and the specific API can be configured according to their respective versions.
3. Register plugin
Follow these steps to register the plugin:
Create
effectSDKExtension
instance.typescriptconst effectSDKExtension = new EffectSDKExtension()
Call
AgoraRTC. RegisterExtensions
and to create aeffectSDKExtension
instance.AgoraRTC.registerExtensions([effectSDKExtension])
4. Initialize the Meishe AR Face Filter plugin
The purpose of initializing the smart beauty effects plugin is to load the sdk and a series of model packages and data packages. To realize the recognition/loading of beauty, makeup, face, avatar, portrait, stickers, subtitles, background segmentation, special effects props and other functions.
The specific configurations are as follows:
const effectSDKProcessor = effectSDKExtension.createProcessor()
// arSceneRenderer is the Meishe AR Face Filter instance and needs to be saved
const arSceneRenderer = await effectSDKProcessor.init({
faceModelUrl: 'https://xxx',
eyecontourModelUrl: 'https://xxx',
avatarModelUrl: 'https://xxx',
segmentationModelUrl: 'https://xxx',
makeupDataUrl: 'https://xxx',
fakefaceDataUrl: 'https://xxx',
faceCommonDataUrl: 'https://xxx',
advancedBeautyDataUrl: 'https://xxx',
detectionMode: 32768 | 32, //Flag,fixed configuration
ratio: width + ':' + height,
sdkCDNUrl: 'https://xxx', //CDN link
licFileUrl: 'xxx.lic', //Authorization file address
mirror: true, //or false
})
The type of arSceneRenderer
returned after initializing the Meishe AR Face Filter
plug-in is NveARSceneRenderer, and various attribute methods can be found from the type document.
5. Open Meishe AR Face Filter plugin special effects
Follow these steps to enable special effects:
Invoke the RTC SDK
AgoraRTC. CreateCameraVideoTrack
method to create local camera video track:typescript// Create a video using the RTC SDK const videoTrack = await AgoraRTC.createCameraVideoTrack()
Call
Meishe AR Face Filter
skin care effects plug-insEffectSDKExtension. CreateProcessor
create beauty plug-in processorprocessor
instances:typescript// Processor to create beauty plugin const effectSDKProcessor = EffectSDKExtension.createProcessor()
Invoke the RTC SDK
videoTrack. Pipe
method and specifyvideoTrack. ProcessorDestination
attribute, the plug-in into the SDK camera data stream processing pipeline:typescript// Set up the video processing pipeline videoTrack.pipe(effectSDKProcessor).pipe(videoTrack.processorDestination)
Invoke the
enableBeauty
method of theMeishe AR Face Filter
plugin to enable basic beauty functions:typescript// Enable basic beauty function arSceneRenderer.enableBeauty(true)
Sample code
A piece of code that implements the plug-in's functionality is listed below for your reference.
vite.config.ts
typescriptexport default defineConfig({ plugins: [ react(), { name: 'configure-response-headers', configureServer: (server) => { server.middlewares.use((_req, res, next) => { res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp') res.setHeader('Cross-Origin-Opener-Policy', 'same-origin') res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin') next() }) }, configurePreviewServer: (server) => { server.middlewares.use((_req, res, next) => { res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp') res.setHeader('Cross-Origin-Opener-Policy', 'same-origin') res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin') next() }) }, }, ], })
Function code
typescriptimport AgoraRTC from 'agora-rtc-sdk-ng' import { EffectSDKExtension, EffectSDKProcessor } from 'agora-meishe-effect-sdk' const effectSDKExtension = new EffectSDKExtension() AgoraRTC.registerExtensions([effectSDKExtension]) const effectSDKProcessor = effectSDKExtension.createProcessor() // arSceneRenderer is the Meishe AR Face Filter plugin instance and needs to be saved const arSceneRenderer = await effectSDKProcessor.init({ faceModelUrl: 'https://xxx', eyecontourModelUrl: 'https://xxx', avatarModelUrl: 'https://xxx', segmentationModelUrl: 'https://xxx', makeupDataUrl: 'https://xxx', fakefaceDataUrl: 'https://xxx', faceCommonDataUrl: 'https://xxx', advancedBeautyDataUrl: 'https://xxx', detectionMode: 32768 | 32, //Flag,fixed configuration ratio: width + ':' + height, sdkCDNUrl: 'https://xxx', //CDN link licFileUrl: 'xxx.lic', //Authorization file address mirror: true, //or false }) // Create a video using the RTC SDK const videoTrack = await AgoraRTC.createCameraVideoTrack() // Set up the video processing pipeline videoTrack.pipe(effectSDKProcessor).pipe(videoTrack.processorDestination) // Enable basic beauty function arSceneRenderer.enableBeauty(true) // Set beauty const effectList = [ { key: 'Advanced Beauty Intensity', intensity: 1, }, { key: 'Beauty Whitening', intensity: 1, }, ] // Set makeup effectList.push([ { url: 'https://xxx.makeup', //makeup package address licUrl: 'xxxx', intensity: 1, }, ]) // Set effectList.push([ { url: 'https://xxxx', licUrl: 'xxxx', intensity: 1, }, ]) arSceneRenderer.setEffectList(effectList) videoTrack.play(document.getElementById('video-container'))
API Reference
Meishe AR Face Filter API
EffectSDKExtension
new EffectSDKExtension()
Create an example of a plug-in extender. This method is an export method of a Meishe AR Face Filter
plug-in.
createProcessor
createProcessor()
Creates a plug-in processor, returning an instance of EffectSDKProcessor
. This method is located under the EffectSDKExtension
class.
init
effectSDKProcessor.init()
Initialize the plug-in and return the plug-in instance, whose class is NveARSceneRenderer. The init method is located under the EffectSDKProcessor
class.
enableBeauty
enableBeauty()
Turn on/off beauty effects to control only the built-in beauty effects. This method is located under the 'NveARSceneRenderer' plug-in instance
Turn on/off beauty effects to control only the built-in beauty effects. This method is located under the NveARSceneRenderer
plug-in instance.
setEffectList
setEffectList()
Set the list of effects. You can set beauty, beauty makeup, beauty type, filter, props, background. This method is located under the NveARSceneRenderer
plug-in instance.
getEffectList
getEffectList()
Gets a list of all the effects that have been set, including added beauty, filters, props, and more. This method is located under the NveARSceneRenderer
plug-in instance.
createExternalEffectInstance
createExternalEffectInstance()
Create extended effects instances for creating captions and stickers instances. This method is located under the NveARSceneRenderer
plug-in instance.
appendExternalEffectInstance
appendExternalEffectInstance()
Add an extended effects instance to the plugin instance. This method is located under the NveARSceneRenderer
plug-in instance.
setExternalEffectInstanceList
setExternalEffectInstanceList()
Gets a list of all added extension effects. This method is located under the NveARSceneRenderer
plug-in instance.
Special effect setting
Beauty
Built-in effects
Built-in special effects do not need special effects package, which belongs to the built-in ability of the smart beauty effects plug-in, but you need to know the key name. The specific content can be viewed in the Meishu SDK Web document, which is roughly as follows:
typescript// key is the built-in special effects keyword used to distinguish special effects functions // intensity indicates the specific intensity. The value ranges from [-1,1] to [0,1] // sdk built-in hundreds of built-in effects, range and key values can be found by yourself const beautyArray = [ { key:'Advanced Beauty Intensity', intensity:1 }, { key:'Beauty Whitening', intensity:1 }, { key:'Beauty Reddening', intensity:1 }, { key:'Face Mesh Face Width Degree', intensity:1 }, { key:'Face Mesh Face Length Degree', intensity:1 }, { key:'Face Mesh Face Size Degree', intensity:1 }, { key:'Face Mesh Forehead Height Degree', intensity:1 }, ... ] arSceneRenderer.setEffectList(beautyArray)
Beauty template
Unlike built-in effects, beauty templates need to be passed into the template package, not the key value. The code is as follows:
typescriptconst templateArray = [ { url: 'https://xxxx', licUrl: 'xxxx', intensity: 1, }, { url: 'https://xxxx', licUrl: 'xxxx', intensity: 1, }, ] arSceneRenderer.setEffectList(templateArray)
Makeup
normal package
Ordinary beauty bags have lipstick, eyeshadow, eyebrows, eyelashes, eyeliner, blush, shine, shadow, contact lenses, makeup and a series of categories. The configuration method is the same as the beauty template, and the code is as follows:
typescriptconst makeupArray = [ { url: 'https://xxx.makeup', licUrl: 'xxxx', intensity: 1, }, { url: 'https://xxx.makeup', licUrl: 'xxxx', intensity: 1, }, ] arSceneRenderer.setEffectList(makeupArray)
Complete package
The whole bag is the integration of a series of ordinary bags. The configuration method is as follows:
typescriptarSceneRenderer.setEffectList([ { url: 'https://xxx.zip', }, ])
Filter
Filters are configured in the same way as beauty bags, and the code is as follows:
const filterArray = [
{
url: 'https://xxxx',
licUrl: 'xxxx', // lic File url
intensity: 1,
},
]
arSceneRenderer.setEffectList(filterArray)
Virtual background
background blur
You need to specify the background blur special effects package, as follows:
typescriptarSceneRenderer.setEffectList([ { url: 'https://xxx.videofx', licUrl: '', }, ])
Background substitution
Background The replacement configuration is as follows:
typescriptarSceneRenderer.setEffectList([ { segmentationBackgroundUrl: 'https://xxx.png' }, //image url ])
AR scene
The configuration method is the same as the filter, and the code is as follows:
arSceneRenderer.setEffectList([
{
url: 'https://xxx.arscene', // AR scene package Url
licUrl: '', // AR scene license Url
},
])
Caption
1 common caption
Common subtitling categories include flower characters, dynamic subtitling, word-for-word subtitling, bubble subtitling and so on. The configuration method is not the same as beauty makeup.
createExternalEffectInstance
method parameter information table:
Parameter | Type | Must | Default | Description |
---|---|---|---|---|
modular | Boolean | no | false | Whether it is module captioning, the module captioning type can add effects such as bubbles and animations. |
text | String | yes | text | |
inPoint | Number | yes | begin time.The unit is microsecond | |
duration | Number | yes | The unit is microsecond,set to Number.MAX_SAFE_INTEGER indicates continuous display. | |
url | String | no | common caption package address | |
licUrl | String | no | Address of the ordinary package authorization file | |
fontFileUrl | String | no | If the font file address is not set, the non-English text will be displayed incorrectly because the corresponding font cannot be found. | |
captionRendererUrl | String | no | Floral effect style package address. | |
captionRendererLicUrl | String | no | The address of the license file corresponding to the flower effect style package. | |
captionContextUrl | String | no | Bubble effect style pack ground | |
captionContextLicUrl | String | no | Bubble effect style package address. | |
captionAnimationUrl | String | no | Animation effects style package address. | |
captionAnimationLicUrl | String | no | License file address corresponding to the animation effects style package. | |
animationPeriod | Number | no | License file address corresponding to the animation effects style package. Animation effect period, in milliseconds. | |
captionInAnimationUrl | String | no | Enter the license file address corresponding to the animation effects style package. | |
captionInAnimationLicUrl | String | no | Enter animation style package address. | |
inAnimationDuration | Number | no | Enter the duration of the animation effect in milliseconds. | |
captionOutAnimationUrl | String | no | Create animation style package address. | |
captionOutAnimationLicUrl | String | no | The address of the license file corresponding to the animation style package. | |
outAnimationDuration | Number | no | Duration of the animation, in milliseconds. | |
positionX | Number | no | Horizontal position, normalized value, range [-1, 1], center 0, positive direction to the right. | |
positionY | Number | no | Vertical position, normalized value, range [-1, 1], center is 0, upward is positive direction. | |
position | String | no | For orientation information, the values that can be set include top-left, top, top-right, left, center, right, bottom-left, bottom, and bottom-right. |
add
Subtitle creation method for
createExternalEffectInstance
, subtitles add methods forappendExternalEffectInstance
.In the following example, the various subtitle effects are created using the same API with different parameters. Refer to the above parameter table for specific parameters
typescript// common caption const caption = await arSceneRenderer.createExternalEffectInstance({ text: 'caption', inPoint: 0, duration: 5000000, }) // Create regular subtitles with subtitles style const caption = await arSceneRenderer.createExternalEffectInstance({ text: 'caption', inPoint: 0, duration: 5000000, url: 'https://xxx.captionstyle', licUrl: '', }) // Create regular captions with captioning styles and a splash effect const caption = await arSceneRenderer.createExternalEffectInstance({ text: 'caption', inPoint: 0, duration: 5000000, url: 'https://xxx.captionstyle', licUrl: '', captionRendererUrl: 'https://xxx.captionrenderer', captionRendererLicUrl: '', }) // Create regular captions with location information const caption = await arSceneRenderer.createExternalEffectInstance({ text: 'caption', inPoint: 0, duration: 5000000, positionX: -0.6, positionY: 0.9, }) // Create regular captions with orientation information const caption = await arSceneRenderer.createExternalEffectInstance({ text: 'caption', inPoint: 0, duration: 5000000, position: 'top-right', }) // Create plain subtitles with fonts const caption = await arSceneRenderer.createExternalEffectInstance({ text: 'caption', inPoint: 0, duration: 5000000, fontFileUrl: 'https://xxx.ttf', }) // Create unstyled module captions const caption = await arSceneRenderer.createExternalEffectInstance({ modular: true, text: 'modularCaption', inPoint: 0, duration: 5000000, }) // Create module captions with a splash effect const caption = await arSceneRenderer.createExternalEffectInstance({ modular: true, text: 'modularCaption', inPoint: 0, duration: 5000000, captionRendererUrl: 'https://xxx.captionrenderer', captionRendererLicUrl: '', }) // Create a module caption with a bubble effect const caption = await arSceneRenderer.createExternalEffectInstance({ modular: true, text: 'modularCaption', inPoint: 0, duration: 5000000, captionContextUrl: 'https://xxx.captioncontext', captionContextLicUrl: '', }) // Create module captions with animated effects const caption = await arSceneRenderer.createExternalEffectInstance({ modular: true, text: 'modularCaption', inPoint: 0, duration: 5000000, captionAnimationUrl: 'https://xxx.captionanimation', captionAnimationLicUrl: '', animationPeriod: 2500, }) // Use the interface of the caption instance to modify the other attributes of the caption caption.scaleCaption2(0.8) caption.setUnderline(true) // Adding a caption instance arSceneRenderer.appendExternalEffectInstance(caption)
The normal subtitle instance type is NveCaption, and various attributes and methods are configured. You can refer to the linked document.
get
To obtain a list of current setting all extension effects, use
getExternalEffectInstanceList
method. The code is as follows:typescript// Get a list of all expanded effects.Note that the expanded effects are not just captions.There may be other effects that need to be filtered // You can also maintain your own list of already set subtitle instances let instanceList = arSceneRenderer.getExternalEffectInstanceList() let captionInstanceList = instanceList.filter((instance) => instance instanceof NveCaption)
delete
Through
getExternalEffectInstanceList
access list, find the same as the current subtitle instance id item and delete. ThroughsetExternalEffectInstanceList
resetting list. The code is as follows:typescriptlet deleteInstanceId = 'xxxx' // The id of the subtitle instance to remove let instanceList = arSceneRenderer.getExternalEffectInstanceList() // Get a list of extended effects on deletion without filtering let index = instanceList.findIndex((instance) => instance.id !== deleteInstanceId) // Gets the index of the deleted child if (index !== -1) { instanceList[index].release() // release resource instanceList.splice(index, 1) arSceneRenderer.setExternalEffectInstanceList(instanceList) // Resets the list of extended effects }
2 Compound caption
createExternalEffectInstance
parameters listed in reference ordinary subtitles form.
The code is as follows:
const compoundCaption = await arSceneRenderer.createExternalEffectInstance({
inPoint: 0,
duration: 5000000,
url: 'https://xxx.compoundcaption',
licUrl: '',
})
// Create compound captions with location information
const compoundCaption = await arSceneRenderer.createExternalEffectInstance({
inPoint: 0,
duration: 5000000,
url: 'https://xxx.compoundcaption',
licUrl: '',
positionX: -0.6,
positionY: 0.9,
})
// Create a composite caption with location information Create a composite caption with orientation location information
const compoundCaption = await arSceneRenderer.createExternalEffectInstance({
inPoint: 0,
duration: 5000000,
url: 'https://xxx.compoundcaption',
licUrl: '',
position: 'top-right',
})
// Modify other properties using the interface of the composite caption instance
compoundCaption.scaleCaption2(0.8)
compoundCaption.setText(0, 'caption0')
// Add a composite caption instance
arSceneRenderer.appendExternalEffectInstance(compoundCaption)
The instance type of the combined caption is NveCompoundCaption, which can be configured in the same way as normal captions
Animated Sticker
Stickers are created in a similar way to captions, but the parameters are somewhat different.The table of parameters is as follows:
Parameter | Type | Must | Default | Description |
---|---|---|---|---|
inPoint | Number | yes | Start time of the animated sticker in microseconds. | |
duration | Number | yes | Duration of the animated sticker in microseconds, set to Number.MAX_SAFE_INTEGER to indicate continuous display. | |
url | String | no | Animated sticker pack address. | |
licUrl | String | no | The address of the license file corresponding to the animation sticker package. | |
animatedStickerAnimationUrl | String | no | Animation style package address. | |
animatedStickerAnimationLicUrl | String | no | The license file address for the animation style pack. | |
animationPeriod | Number | no | Animation effect period in milliseconds. | |
animatedStickerInAnimationUrl | String | no | Enter animation style package address. | |
animatedStickerInAnimationLicUrl | String | no | Enter the animation style package corresponding to the license file address. | |
inAnimationDuration | Number | no | Enter the duration of the animation effect in milliseconds. | |
animatedStickerOutAnimationUrl | String | no | Create animation style package address. | |
animatedStickerOutAnimationLicUrl | String | no | The address of the license file corresponding to the animation style package. | |
outAnimationDuration | Number | no | Duration of the animation, in milliseconds. | |
positionX | Number | no | Horizontal position, normalized value, range [-1, 1], center 0, positive direction to the right. | |
positionY | Number | no | Vertical position, normalized value, range [-1, 1], center is 0, upward is positive direction. | |
position | String | no | For orientation information, the values that can be set include top-left, top, top-right, left, center, right, bottom-left, bottom, and bottom-right. |
The code is as follows:
// Create stickers that don't animate
const sticker = await arSceneRenderer.createExternalEffectInstance({
inPoint: 0,
duration: 5000000,
url: 'https://xxx.animatedsticker',
licUrl: '',
})
// Create animated stickers
const sticker = await arSceneRenderer.createExternalEffectInstance({
inPoint: 0,
duration: 5000000,
url: 'https://xxx.animatedsticker',
licUrl: '',
animatedStickerAnimationUrl: 'https://xxx.animatedstickeranimation',
animatedStickerAnimationLicUrl: '',
animationPeriod: 5000,
})
// Create stickers with location information
const sticker = await arSceneRenderer.createExternalEffectInstance({
inPoint: 0,
duration: 5000000,
url: 'https://xxx.animatedsticker',
licUrl: '',
positionX: -0.6,
positionY: 0.9,
})
// Create stickers with orientation information
const sticker = await arSceneRenderer.createExternalEffectInstance({
inPoint: 0,
duration: 5000000,
url: 'https://xxx.animatedsticker',
licUrl: '',
position: 'top-right',
})
// Modify other properties using the interface of the animated sticker instance
sticker.scaleAnimatedSticker2(0.5)
// Add an instance of animated stickers
arSceneRenderer.appendExternalEffectInstance(sticker)
The instance type of the sticker is NveAnimatedSticker, which can be operated and configured according to the idea of subtitles.
RTC API
RTC Web SDK plugins related methods: