Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync beauty sdk to 1.0.7 for api example 4.5.0 #432

Merged
merged 3 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -82,7 +83,15 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
ByteDanceBeautySDK.INSTANCE.getRenderManager(),
new EventCallback(beautyStats -> null,
() -> {
ByteDanceBeautySDK.INSTANCE.initEffect(requireContext());
boolean authSuccess = ByteDanceBeautySDK.INSTANCE.initEffect(requireContext());
if(!authSuccess){
runOnUIThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "auth failed", Toast.LENGTH_SHORT).show();
}
});
}
return null;
},
() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.agora.api.example.examples.advanced.beauty
import android.content.Context
import android.util.Log
import com.effectsar.labcv.effectsdk.RenderManager
import io.agora.api.example.utils.FileUtils
import io.agora.api.example.examples.advanced.beauty.utils.FileUtils
import io.agora.beautyapi.bytedance.ByteDanceBeautyAPI
import java.io.File

Expand Down Expand Up @@ -37,21 +37,20 @@ object ByteDanceBeautySDK {
assetsPath = "beauty_bytedance"

// copy license
licensePath = "$storagePath/beauty_bytedance/LicenseBag.bundle"
FileUtils.copyFilesFromAssets(context, "$assetsPath/LicenseBag.bundle", licensePath)
licensePath += "/$LICENSE_NAME"
licensePath = "$storagePath/beauty_bytedance/LicenseBag.bundle/$LICENSE_NAME"
FileUtils.copyAssets(context, "$assetsPath/LicenseBag.bundle/$LICENSE_NAME", licensePath)
if (!File(licensePath).exists()) {
return false
}

// copy models
modelsPath = "$storagePath/beauty_bytedance/ModelResource.bundle"
FileUtils.copyFilesFromAssets(context, "$assetsPath/ModelResource.bundle", modelsPath)
FileUtils.copyAssets(context, "$assetsPath/ModelResource.bundle", modelsPath)

// copy beauty node
beautyNodePath =
"$storagePath/beauty_bytedance/ComposeMakeup.bundle/ComposeMakeup/beauty_Android_lite"
FileUtils.copyFilesFromAssets(
FileUtils.copyAssets(
context,
"$assetsPath/ComposeMakeup.bundle/ComposeMakeup/beauty_Android_lite",
beautyNodePath
Expand All @@ -60,7 +59,7 @@ object ByteDanceBeautySDK {
// copy beauty 4items node
beauty4ItemsNodePath =
"$storagePath/beauty_bytedance/ComposeMakeup.bundle/ComposeMakeup/beauty_4Items"
FileUtils.copyFilesFromAssets(
FileUtils.copyAssets(
context,
"$assetsPath/ComposeMakeup.bundle/ComposeMakeup/beauty_4Items",
beauty4ItemsNodePath
Expand All @@ -69,27 +68,27 @@ object ByteDanceBeautySDK {
// copy resharp node
reSharpNodePath =
"$storagePath/beauty_bytedance/ComposeMakeup.bundle/ComposeMakeup/reshape_lite"
FileUtils.copyFilesFromAssets(
FileUtils.copyAssets(
context,
"$assetsPath/ComposeMakeup.bundle/ComposeMakeup/reshape_lite",
reSharpNodePath
)

// copy stickers
stickerPath = "$storagePath/beauty_bytedance/StickerResource.bundle/stickers"
FileUtils.copyFilesFromAssets(context, "$assetsPath/StickerResource.bundle/stickers", stickerPath)
FileUtils.copyAssets(context, "$assetsPath/StickerResource.bundle/stickers", stickerPath)

return true
}

// GL Thread
fun initEffect(context: Context) {
fun initEffect(context: Context) : Boolean{
val ret = renderManager.init(
context,
modelsPath, licensePath, false, false, 0
)
if (!checkResult("RenderManager init ", ret)) {
return
return false
}
renderManager.useBuiltinSensor(true)
renderManager.set3Buffer(false)
Expand All @@ -99,6 +98,7 @@ object ByteDanceBeautySDK {
)
renderManager.loadResourceWithTimeout(-1)
beautyConfig.resume()
return true
}

// GL Thread
Expand Down Expand Up @@ -139,7 +139,7 @@ object ByteDanceBeautySDK {
}

internal fun setBeautyAPI(beautyAPI: ByteDanceBeautyAPI?) {
this.beautyAPI = beautyAPI
ByteDanceBeautySDK.beautyAPI = beautyAPI
}

private fun runOnBeautyThread(run: () -> Unit) {
Expand Down Expand Up @@ -411,7 +411,7 @@ object ByteDanceBeautySDK {
if (value != null) {
val nodePath =
"$storagePath/beauty_bytedance/ComposeMakeup.bundle/ComposeMakeup/style_makeup/${value.style}"
FileUtils.copyFilesFromAssets(
FileUtils.copyAssets(
value.context,
"$assetsPath/ComposeMakeup.bundle/ComposeMakeup/style_makeup/${value.style}",
nodePath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ object FaceUnityBeautySDK {

private var beautyAPI: FaceUnityBeautyAPI? = null

private var authSuccess = false

fun initBeauty(context: Context): Boolean {
val auth = try {
getAuth()
Expand All @@ -45,13 +47,14 @@ object FaceUnityBeautySDK {
override fun onSuccess(code: Int, msg: String) {
Log.i(TAG, "FURenderManager onSuccess -- code=$code, msg=$msg")
if (code == OPERATE_SUCCESS_AUTH) {
faceunity.fuSetUseTexAsync(1)
authSuccess = true
faceunity.fuSetUseTexAsync(0)
FUAIKit.getInstance()
.loadAIProcessor(BUNDLE_AI_FACE, FUAITypeEnum.FUAITYPE_FACEPROCESSOR)
FUAIKit.getInstance().loadAIProcessor(
BUNDLE_AI_HUMAN,
FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR
)
// FUAIKit.getInstance().loadAIProcessor(
// BUNDLE_AI_HUMAN,
// FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR
// )

}
}
Expand All @@ -63,9 +66,14 @@ object FaceUnityBeautySDK {
return true
}

fun isAuthSuccess(): Boolean {
return authSuccess
}

fun unInitBeauty() {
beautyAPI = null
beautyConfig.reset()
authSuccess = false
FUAIKit.getInstance().releaseAllAIProcessor()
FURenderKit.getInstance().release()
}
Expand All @@ -77,8 +85,9 @@ object FaceUnityBeautySDK {
return aMethod.invoke(null) as? ByteArray
}

internal fun setBeautyAPI(beautyAPI: FaceUnityBeautyAPI) {
this.beautyAPI = beautyAPI
internal fun setBeautyAPI(beautyAPI: FaceUnityBeautyAPI?) {
FaceUnityBeautySDK.beautyAPI = beautyAPI
beautyConfig.resume()
}

private fun runOnBeautyThread(run: () -> Unit) {
Expand Down Expand Up @@ -312,6 +321,28 @@ object FaceUnityBeautySDK {
sticker = null
}

fun resume(){
smooth = smooth
whiten = whiten
thinFace = thinFace
enlargeEye = enlargeEye
redden = redden
shrinkCheekbone = shrinkCheekbone
shrinkJawbone = shrinkJawbone
whiteTeeth = whiteTeeth
hairlineHeight = hairlineHeight
narrowNose = narrowNose
mouthSize = mouthSize
chinLength = chinLength
brightEye = brightEye
darkCircles = darkCircles
nasolabialFolds = nasolabialFolds
faceThree = faceThree

makeUp = makeUp
sticker = sticker
}

}

data class MakeUpItem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.softsugar.stmobile.STMobileEffectNative
import com.softsugar.stmobile.STMobileEffectParams
import com.softsugar.stmobile.STMobileHumanActionNative
import com.softsugar.stmobile.params.STEffectBeautyType
import io.agora.api.example.utils.FileUtils
import io.agora.api.example.examples.advanced.beauty.utils.FileUtils
import io.agora.beautyapi.sensetime.SenseTimeBeautyAPI

object SenseTimeBeautySDK {
Expand Down Expand Up @@ -55,16 +55,25 @@ object SenseTimeBeautySDK {

private var beautyAPI: SenseTimeBeautyAPI? = null

private var authSuccess = false

fun initBeautySDK(context: Context): Boolean {
if (checkLicense(context)) {
initHumanAction(context)
authSuccess = true
return true
}
initHumanAction(context)
return false
}

fun isAuthSuccess(): Boolean {
return authSuccess
}

fun unInitBeautySDK() {
beautyAPI = null
authSuccess = false
unInitHumanActionNative()
beautyConfig.reset()
}
Expand All @@ -78,6 +87,7 @@ object SenseTimeBeautySDK {
_mobileEffectNative?.createInstance(context, STMobileEffectNative.EFFECT_CONFIG_NONE)
_mobileEffectNative?.setParam(STMobileEffectParams.EFFECT_PARAM_QUATERNION_SMOOTH_FRAME, 5f)
Log.d(TAG, "SenseTime >> STMobileEffectNative create result : $result")
beautyConfig.resume()
}

fun unInitMobileEffect() {
Expand All @@ -98,8 +108,8 @@ object SenseTimeBeautySDK {
license,
license.length
)
Log.d(TAG, "SenseTime >> checkLicense successfully! activeCode=$activeCode")
return true
Log.d(TAG, "SenseTime >> checkLicense activeCode=$activeCode")
return activeCode.isNotEmpty()
}

private fun initHumanAction(context: Context) {
Expand Down Expand Up @@ -147,8 +157,8 @@ object SenseTimeBeautySDK {
}


internal fun setBeautyAPI(beautyAPI: SenseTimeBeautyAPI){
this.beautyAPI = beautyAPI
internal fun setBeautyAPI(beautyAPI: SenseTimeBeautyAPI?){
SenseTimeBeautySDK.beautyAPI = beautyAPI
beautyConfig.resume()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* MIT License
*
* Copyright (c) 2023 Agora Community
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package io.agora.api.example.examples.advanced.beauty.utils

import android.content.Context
import android.util.Log
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.BufferedReader
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.io.OutputStream

object FileUtils {
val TAG = "FileUtils"

fun getAssetsString(context: Context, path: String): String {
val sb = StringBuilder()
var isr: InputStreamReader? = null
var br: BufferedReader? = null
try {
isr = InputStreamReader(context.resources.assets.open(path))
br = BufferedReader(isr)
var line: String? = null
while (br.readLine().also { line = it } != null) {
sb.append(line).append("\n")
}
} catch (e: IOException) {
Log.e(TAG, "getAssetsString error: $e")
} finally {
if (isr != null) {
try {
isr.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
if (br != null) {
try {
br.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
return sb.toString()
}

fun copyAssets(context: Context, assetsPath: String, targetPath: String) {
val fileNames = context.resources.assets.list(assetsPath)
if (fileNames?.isNotEmpty() == true) {
val targetFile = File(targetPath)
if (!targetFile.exists() && !targetFile.mkdirs()) {
return
}
for (fileName in fileNames) {
copyAssets(
context,
"$assetsPath/$fileName",
"$targetPath/$fileName"
)
}
} else {
copyAssetsFile(context, assetsPath, targetPath)
}
}

private fun copyAssetsFile(context: Context, assetsFile: String, targetPath: String) {
val dest = File(targetPath)
dest.parentFile?.mkdirs()
var input: InputStream? = null
var output: OutputStream? = null
try {
input = BufferedInputStream(context.assets.open(assetsFile))
output = BufferedOutputStream(FileOutputStream(dest))
val buffer = ByteArray(1024)
var length = 0
while (input.read(buffer).also { length = it } != -1) {
output.write(buffer, 0, length)
}
} catch (e: Exception) {
Log.e(TAG, "copyAssetsFile", e)
} finally {
output?.close()
input?.close()
}
}
}
Loading
Loading