Skip to content

Commit bdbceba

Browse files
authored
Merge pull request #432 from AgoraIO/dev/4.5.0_android
sync beauty sdk to 1.0.7 for api example 4.5.0
2 parents b26a881 + 0eda633 commit bdbceba

19 files changed

Lines changed: 853 additions & 150 deletions

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/ByteDanceBeauty.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import android.view.View;
77
import android.view.ViewGroup;
88
import android.view.ViewParent;
9+
import android.widget.Toast;
910

1011
import androidx.annotation.NonNull;
1112
import androidx.annotation.Nullable;
@@ -82,7 +83,15 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
8283
ByteDanceBeautySDK.INSTANCE.getRenderManager(),
8384
new EventCallback(beautyStats -> null,
8485
() -> {
85-
ByteDanceBeautySDK.INSTANCE.initEffect(requireContext());
86+
boolean authSuccess = ByteDanceBeautySDK.INSTANCE.initEffect(requireContext());
87+
if(!authSuccess){
88+
runOnUIThread(new Runnable() {
89+
@Override
90+
public void run() {
91+
Toast.makeText(getContext(), "auth failed", Toast.LENGTH_SHORT).show();
92+
}
93+
});
94+
}
8695
return null;
8796
},
8897
() -> {

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/ByteDanceBeautySDK.kt

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package io.agora.api.example.examples.advanced.beauty
33
import android.content.Context
44
import android.util.Log
55
import com.effectsar.labcv.effectsdk.RenderManager
6-
import io.agora.api.example.utils.FileUtils
6+
import io.agora.api.example.examples.advanced.beauty.utils.FileUtils
77
import io.agora.beautyapi.bytedance.ByteDanceBeautyAPI
88
import java.io.File
99

@@ -37,21 +37,20 @@ object ByteDanceBeautySDK {
3737
assetsPath = "beauty_bytedance"
3838

3939
// copy license
40-
licensePath = "$storagePath/beauty_bytedance/LicenseBag.bundle"
41-
FileUtils.copyFilesFromAssets(context, "$assetsPath/LicenseBag.bundle", licensePath)
42-
licensePath += "/$LICENSE_NAME"
40+
licensePath = "$storagePath/beauty_bytedance/LicenseBag.bundle/$LICENSE_NAME"
41+
FileUtils.copyAssets(context, "$assetsPath/LicenseBag.bundle/$LICENSE_NAME", licensePath)
4342
if (!File(licensePath).exists()) {
4443
return false
4544
}
4645

4746
// copy models
4847
modelsPath = "$storagePath/beauty_bytedance/ModelResource.bundle"
49-
FileUtils.copyFilesFromAssets(context, "$assetsPath/ModelResource.bundle", modelsPath)
48+
FileUtils.copyAssets(context, "$assetsPath/ModelResource.bundle", modelsPath)
5049

5150
// copy beauty node
5251
beautyNodePath =
5352
"$storagePath/beauty_bytedance/ComposeMakeup.bundle/ComposeMakeup/beauty_Android_lite"
54-
FileUtils.copyFilesFromAssets(
53+
FileUtils.copyAssets(
5554
context,
5655
"$assetsPath/ComposeMakeup.bundle/ComposeMakeup/beauty_Android_lite",
5756
beautyNodePath
@@ -60,7 +59,7 @@ object ByteDanceBeautySDK {
6059
// copy beauty 4items node
6160
beauty4ItemsNodePath =
6261
"$storagePath/beauty_bytedance/ComposeMakeup.bundle/ComposeMakeup/beauty_4Items"
63-
FileUtils.copyFilesFromAssets(
62+
FileUtils.copyAssets(
6463
context,
6564
"$assetsPath/ComposeMakeup.bundle/ComposeMakeup/beauty_4Items",
6665
beauty4ItemsNodePath
@@ -69,27 +68,27 @@ object ByteDanceBeautySDK {
6968
// copy resharp node
7069
reSharpNodePath =
7170
"$storagePath/beauty_bytedance/ComposeMakeup.bundle/ComposeMakeup/reshape_lite"
72-
FileUtils.copyFilesFromAssets(
71+
FileUtils.copyAssets(
7372
context,
7473
"$assetsPath/ComposeMakeup.bundle/ComposeMakeup/reshape_lite",
7574
reSharpNodePath
7675
)
7776

7877
// copy stickers
7978
stickerPath = "$storagePath/beauty_bytedance/StickerResource.bundle/stickers"
80-
FileUtils.copyFilesFromAssets(context, "$assetsPath/StickerResource.bundle/stickers", stickerPath)
79+
FileUtils.copyAssets(context, "$assetsPath/StickerResource.bundle/stickers", stickerPath)
8180

8281
return true
8382
}
8483

8584
// GL Thread
86-
fun initEffect(context: Context) {
85+
fun initEffect(context: Context) : Boolean{
8786
val ret = renderManager.init(
8887
context,
8988
modelsPath, licensePath, false, false, 0
9089
)
9190
if (!checkResult("RenderManager init ", ret)) {
92-
return
91+
return false
9392
}
9493
renderManager.useBuiltinSensor(true)
9594
renderManager.set3Buffer(false)
@@ -99,6 +98,7 @@ object ByteDanceBeautySDK {
9998
)
10099
renderManager.loadResourceWithTimeout(-1)
101100
beautyConfig.resume()
101+
return true
102102
}
103103

104104
// GL Thread
@@ -139,7 +139,7 @@ object ByteDanceBeautySDK {
139139
}
140140

141141
internal fun setBeautyAPI(beautyAPI: ByteDanceBeautyAPI?) {
142-
this.beautyAPI = beautyAPI
142+
ByteDanceBeautySDK.beautyAPI = beautyAPI
143143
}
144144

145145
private fun runOnBeautyThread(run: () -> Unit) {
@@ -411,7 +411,7 @@ object ByteDanceBeautySDK {
411411
if (value != null) {
412412
val nodePath =
413413
"$storagePath/beauty_bytedance/ComposeMakeup.bundle/ComposeMakeup/style_makeup/${value.style}"
414-
FileUtils.copyFilesFromAssets(
414+
FileUtils.copyAssets(
415415
value.context,
416416
"$assetsPath/ComposeMakeup.bundle/ComposeMakeup/style_makeup/${value.style}",
417417
nodePath

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/FaceUnityBeautySDK.kt

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ object FaceUnityBeautySDK {
3131

3232
private var beautyAPI: FaceUnityBeautyAPI? = null
3333

34+
private var authSuccess = false
35+
3436
fun initBeauty(context: Context): Boolean {
3537
val auth = try {
3638
getAuth()
@@ -45,13 +47,14 @@ object FaceUnityBeautySDK {
4547
override fun onSuccess(code: Int, msg: String) {
4648
Log.i(TAG, "FURenderManager onSuccess -- code=$code, msg=$msg")
4749
if (code == OPERATE_SUCCESS_AUTH) {
48-
faceunity.fuSetUseTexAsync(1)
50+
authSuccess = true
51+
faceunity.fuSetUseTexAsync(0)
4952
FUAIKit.getInstance()
5053
.loadAIProcessor(BUNDLE_AI_FACE, FUAITypeEnum.FUAITYPE_FACEPROCESSOR)
51-
FUAIKit.getInstance().loadAIProcessor(
52-
BUNDLE_AI_HUMAN,
53-
FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR
54-
)
54+
// FUAIKit.getInstance().loadAIProcessor(
55+
// BUNDLE_AI_HUMAN,
56+
// FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR
57+
// )
5558

5659
}
5760
}
@@ -63,9 +66,14 @@ object FaceUnityBeautySDK {
6366
return true
6467
}
6568

69+
fun isAuthSuccess(): Boolean {
70+
return authSuccess
71+
}
72+
6673
fun unInitBeauty() {
6774
beautyAPI = null
6875
beautyConfig.reset()
76+
authSuccess = false
6977
FUAIKit.getInstance().releaseAllAIProcessor()
7078
FURenderKit.getInstance().release()
7179
}
@@ -77,8 +85,9 @@ object FaceUnityBeautySDK {
7785
return aMethod.invoke(null) as? ByteArray
7886
}
7987

80-
internal fun setBeautyAPI(beautyAPI: FaceUnityBeautyAPI) {
81-
this.beautyAPI = beautyAPI
88+
internal fun setBeautyAPI(beautyAPI: FaceUnityBeautyAPI?) {
89+
FaceUnityBeautySDK.beautyAPI = beautyAPI
90+
beautyConfig.resume()
8291
}
8392

8493
private fun runOnBeautyThread(run: () -> Unit) {
@@ -312,6 +321,28 @@ object FaceUnityBeautySDK {
312321
sticker = null
313322
}
314323

324+
fun resume(){
325+
smooth = smooth
326+
whiten = whiten
327+
thinFace = thinFace
328+
enlargeEye = enlargeEye
329+
redden = redden
330+
shrinkCheekbone = shrinkCheekbone
331+
shrinkJawbone = shrinkJawbone
332+
whiteTeeth = whiteTeeth
333+
hairlineHeight = hairlineHeight
334+
narrowNose = narrowNose
335+
mouthSize = mouthSize
336+
chinLength = chinLength
337+
brightEye = brightEye
338+
darkCircles = darkCircles
339+
nasolabialFolds = nasolabialFolds
340+
faceThree = faceThree
341+
342+
makeUp = makeUp
343+
sticker = sticker
344+
}
345+
315346
}
316347

317348
data class MakeUpItem(

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/beauty/SenseTimeBeautySDK.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import com.softsugar.stmobile.STMobileEffectNative
88
import com.softsugar.stmobile.STMobileEffectParams
99
import com.softsugar.stmobile.STMobileHumanActionNative
1010
import com.softsugar.stmobile.params.STEffectBeautyType
11-
import io.agora.api.example.utils.FileUtils
11+
import io.agora.api.example.examples.advanced.beauty.utils.FileUtils
1212
import io.agora.beautyapi.sensetime.SenseTimeBeautyAPI
1313

1414
object SenseTimeBeautySDK {
@@ -55,16 +55,25 @@ object SenseTimeBeautySDK {
5555

5656
private var beautyAPI: SenseTimeBeautyAPI? = null
5757

58+
private var authSuccess = false
59+
5860
fun initBeautySDK(context: Context): Boolean {
5961
if (checkLicense(context)) {
6062
initHumanAction(context)
63+
authSuccess = true
6164
return true
6265
}
66+
initHumanAction(context)
6367
return false
6468
}
6569

70+
fun isAuthSuccess(): Boolean {
71+
return authSuccess
72+
}
73+
6674
fun unInitBeautySDK() {
6775
beautyAPI = null
76+
authSuccess = false
6877
unInitHumanActionNative()
6978
beautyConfig.reset()
7079
}
@@ -78,6 +87,7 @@ object SenseTimeBeautySDK {
7887
_mobileEffectNative?.createInstance(context, STMobileEffectNative.EFFECT_CONFIG_NONE)
7988
_mobileEffectNative?.setParam(STMobileEffectParams.EFFECT_PARAM_QUATERNION_SMOOTH_FRAME, 5f)
8089
Log.d(TAG, "SenseTime >> STMobileEffectNative create result : $result")
90+
beautyConfig.resume()
8191
}
8292

8393
fun unInitMobileEffect() {
@@ -98,8 +108,8 @@ object SenseTimeBeautySDK {
98108
license,
99109
license.length
100110
)
101-
Log.d(TAG, "SenseTime >> checkLicense successfully! activeCode=$activeCode")
102-
return true
111+
Log.d(TAG, "SenseTime >> checkLicense activeCode=$activeCode")
112+
return activeCode.isNotEmpty()
103113
}
104114

105115
private fun initHumanAction(context: Context) {
@@ -147,8 +157,8 @@ object SenseTimeBeautySDK {
147157
}
148158

149159

150-
internal fun setBeautyAPI(beautyAPI: SenseTimeBeautyAPI){
151-
this.beautyAPI = beautyAPI
160+
internal fun setBeautyAPI(beautyAPI: SenseTimeBeautyAPI?){
161+
SenseTimeBeautySDK.beautyAPI = beautyAPI
152162
beautyConfig.resume()
153163
}
154164

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2023 Agora Community
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package io.agora.api.example.examples.advanced.beauty.utils
26+
27+
import android.content.Context
28+
import android.util.Log
29+
import java.io.BufferedInputStream
30+
import java.io.BufferedOutputStream
31+
import java.io.BufferedReader
32+
import java.io.File
33+
import java.io.FileOutputStream
34+
import java.io.IOException
35+
import java.io.InputStream
36+
import java.io.InputStreamReader
37+
import java.io.OutputStream
38+
39+
object FileUtils {
40+
val TAG = "FileUtils"
41+
42+
fun getAssetsString(context: Context, path: String): String {
43+
val sb = StringBuilder()
44+
var isr: InputStreamReader? = null
45+
var br: BufferedReader? = null
46+
try {
47+
isr = InputStreamReader(context.resources.assets.open(path))
48+
br = BufferedReader(isr)
49+
var line: String? = null
50+
while (br.readLine().also { line = it } != null) {
51+
sb.append(line).append("\n")
52+
}
53+
} catch (e: IOException) {
54+
Log.e(TAG, "getAssetsString error: $e")
55+
} finally {
56+
if (isr != null) {
57+
try {
58+
isr.close()
59+
} catch (e: IOException) {
60+
e.printStackTrace()
61+
}
62+
}
63+
if (br != null) {
64+
try {
65+
br.close()
66+
} catch (e: IOException) {
67+
e.printStackTrace()
68+
}
69+
}
70+
}
71+
return sb.toString()
72+
}
73+
74+
fun copyAssets(context: Context, assetsPath: String, targetPath: String) {
75+
val fileNames = context.resources.assets.list(assetsPath)
76+
if (fileNames?.isNotEmpty() == true) {
77+
val targetFile = File(targetPath)
78+
if (!targetFile.exists() && !targetFile.mkdirs()) {
79+
return
80+
}
81+
for (fileName in fileNames) {
82+
copyAssets(
83+
context,
84+
"$assetsPath/$fileName",
85+
"$targetPath/$fileName"
86+
)
87+
}
88+
} else {
89+
copyAssetsFile(context, assetsPath, targetPath)
90+
}
91+
}
92+
93+
private fun copyAssetsFile(context: Context, assetsFile: String, targetPath: String) {
94+
val dest = File(targetPath)
95+
dest.parentFile?.mkdirs()
96+
var input: InputStream? = null
97+
var output: OutputStream? = null
98+
try {
99+
input = BufferedInputStream(context.assets.open(assetsFile))
100+
output = BufferedOutputStream(FileOutputStream(dest))
101+
val buffer = ByteArray(1024)
102+
var length = 0
103+
while (input.read(buffer).also { length = it } != -1) {
104+
output.write(buffer, 0, length)
105+
}
106+
} catch (e: Exception) {
107+
Log.e(TAG, "copyAssetsFile", e)
108+
} finally {
109+
output?.close()
110+
input?.close()
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)