save code

This commit is contained in:
xsl
2025-12-17 22:58:30 +08:00
parent 84cc693593
commit 9ee028248d
29 changed files with 115 additions and 80 deletions
+3
View File
@@ -80,4 +80,7 @@ dependencies {
implementation 'com.google.flogger:flogger-system-backend:0.7.4' implementation 'com.google.flogger:flogger-system-backend:0.7.4'
implementation 'com.google.guava:guava:31.1-android' implementation 'com.google.guava:guava:31.1-android'
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") // 提供 lifecycleScope
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+27 -2
View File
@@ -71,13 +71,38 @@
"7.png" "7.png"
], ],
"11": [ "11": [
"11.png" "002.png",
"003.png",
"004.png",
"005.png",
"006.png",
"007.png",
"008.png",
"009.png",
"010.png",
"011.png",
"11.png",
"012.png"
], ],
"12": [ "12": [
"12.png" "12.png"
], ],
"13": [ "13": [
"13.png" "001.png",
"002.png",
"003.png",
"004.png",
"005.png",
"006.png",
"007.png",
"008.png",
"009.png",
"010.png",
"011.png",
"012.png",
"013.png",
"13.png",
"014.png"
], ],
"14": [ "14": [
"14.png" "14.png"
@@ -7,11 +7,13 @@ import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
import android.view.KeyEvent.KEYCODE_BACK import android.view.KeyEvent.KEYCODE_BACK
import android.view.MotionEvent import android.view.MotionEvent
import android.widget.Toast import androidx.lifecycle.lifecycleScope
import androidx.activity.OnBackPressedCallback
import com.hmwl.face_sdk.FaceActivity import com.hmwl.face_sdk.FaceActivity
import com.hmwl.face_sdk.InitArg import com.hmwl.face_sdk.InitArg
import com.hmwl.face_sdk.Motion import com.hmwl.face_sdk.Motion
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.json.JSONObject import org.json.JSONObject
import java.io.BufferedReader import java.io.BufferedReader
import java.io.InputStreamReader import java.io.InputStreamReader
@@ -19,8 +21,43 @@ import java.io.InputStreamReader
class MakeupActivity : FaceActivity() class MakeupActivity : FaceActivity()
{ {
private var curIndex = 0 var isLoadFinished: Boolean = false;
private var pngFilesByFolder: List<FolderInfo>? = null var isMotionFinished: Boolean = true;
var _motionIndex : Int = 0
var animationFinishedFun = object : AnimationFinishedCallbackInterface {
override fun OnAnimationFinished() {
isMotionFinished = true;
}
}
var loadFinishedFun = object : CallbackInterface {
override fun OnLoadActionFinished(motion_type: String) {
isLoadFinished = true;
}
}
private val motionQueue: MutableList<String> = mutableListOf()
fun PlayMotionQueue(motions: List<String>)
{
for (m in motions) {
var motion = getMotionByName(m);
var motionJsonString = motion.toJson();
motionQueue.add(motionJsonString)
}
//开始播放动画的时候需要先加载第一个动画
isLoadFinished = false;
_motionIndex = 0;
PreLoadAction(motionQueue[_motionIndex], loadFinishedFun)
}
private var updateJob: Job? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -35,20 +72,37 @@ class MakeupActivity : FaceActivity()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
var motion = getMotionByIndex(0);
var motionJsonString = motion.toJson() // 启动一个生命周期感知的协程
val result = PreLoadAction(motionJsonString,object : CallbackInterface { updateJob = lifecycleScope.launch {
override fun OnLoadActionFinished(motion_type: String) { while (true) {
//加载完成后,切断到对应的动画 update()
Log.i("info","加载完成后,切换到对应的动画") delay(10) // 每 10 毫秒执行一次
ChangeMotion(motion_type, object : AnimationFinishedCallbackInterface{
override fun OnAnimationFinished(){
Log.i("info","动画播放完成,收到回调")
}
}, false)
} }
}) }
Toast.makeText(this, "开始加载动画: $result", Toast.LENGTH_SHORT).show()
}
private fun update()
{
//下一个动画加载完成,并且当前动画已经播放完了 (刚开始的时候当前动画初始化为播放完成)
if(isLoadFinished && isMotionFinished)
{
//切换到加载完成的动画
isMotionFinished = false
ChangeMotion(motionQueue[_motionIndex], animationFinishedFun, false)
isLoadFinished = false
//如果还有动画,则开始预先加载
if(_motionIndex + 1 < motionQueue.size)
{
_motionIndex += 1
PreLoadAction(motionQueue[_motionIndex], loadFinishedFun)
}
}
} }
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
@@ -66,70 +120,21 @@ class MakeupActivity : FaceActivity()
} }
private fun getMotionByIndex(index: Int): Motion { private fun getMotionByName(m: String): Motion {
pngFilesByFolder?.let { folders -> val motion = Motion().apply {
val motion = Motion().apply { type = m
type = folders[index].folderName png_names = pngFilesByFolder?.get(m)?.fileList
png_names = folders[index].fileList
}
return motion
} }
return Motion() return motion
} }
private fun getCurMotionState(index: Int): String {
pngFilesByFolder?.let { folders ->
val motion = Motion().apply {
type = folders[index].folderName
png_names = folders[index].fileList
}
return motion.toJson()
}
return ""
}
var nextMotionLoadFinished = false
var nextMotionType = ""
override fun onTouchEvent(event: MotionEvent): Boolean { override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) { when (event.action) {
MotionEvent.ACTION_DOWN -> {
pngFilesByFolder?.let { folders ->
if (curIndex > folders.size - 1) {
//动画播放完成,切换到主界面
curIndex = 0
Stop();
finish();
}
}
}
MotionEvent.ACTION_UP -> { MotionEvent.ACTION_UP -> {
if (!nextMotionLoadFinished) val motions: List<String> = listOf("4", "11", "13")
{ PlayMotionQueue(motions)
var nextMotion = getMotionByIndex(curIndex + 1);
var json_str = nextMotion.toJson()
PreLoadAction(json_str,object : CallbackInterface {
override fun OnLoadActionFinished(motion_type: String) {
Log.i("info","加载完成后,还会继续播放当前的动画,可以手动切换动画")
nextMotionLoadFinished = true;
nextMotionType = motion_type;
}
})
Toast.makeText(this, "开始加载下一个动画 ${nextMotion.type}", Toast.LENGTH_SHORT).show()
}
else
{
//手动切换动画
ChangeMotion(nextMotionType, object: AnimationFinishedCallbackInterface{
override fun OnAnimationFinished(){
Log.i("info","动画播放完成的回调")
}
}, false);
nextMotionLoadFinished = false;
curIndex++;
Toast.makeText(this, "切换到下一个动画 $nextMotionType", Toast.LENGTH_SHORT).show()
}
} }
} }
return true return true
@@ -140,8 +145,8 @@ class MakeupActivity : FaceActivity()
val fileList: List<String> val fileList: List<String>
) )
private fun readPngFilenamesFromAssets(context: Context, filename: String): List<FolderInfo> { private fun readPngFilenamesFromAssets(context: Context, filename: String): Map<String,FolderInfo> {
val folderList = mutableListOf<FolderInfo>() val folderMap = mutableMapOf<String, FolderInfo>()
try { try {
context.assets.open(filename).use { inputStream -> context.assets.open(filename).use { inputStream ->
@@ -164,7 +169,7 @@ class MakeupActivity : FaceActivity()
filesInFolder.add(fileArray.getString(i)) filesInFolder.add(fileArray.getString(i))
} }
folderList.add(FolderInfo(folderName, filesInFolder)) folderMap[folderName] = (FolderInfo(folderName, filesInFolder))
} }
} }
} }
@@ -172,9 +177,10 @@ class MakeupActivity : FaceActivity()
e.printStackTrace() e.printStackTrace()
} }
return folderList return folderMap
} }
private var pngFilesByFolder: Map<String, FolderInfo>? = null
private fun FaceInit(context: Context) { private fun FaceInit(context: Context) {
pngFilesByFolder = readPngFilenamesFromAssets(context, "pic/motion_data.json") pngFilesByFolder = readPngFilenamesFromAssets(context, "pic/motion_data.json")
} }
+1
View File
@@ -1401,6 +1401,7 @@ void FaceApp::changeMotion(const string motion_type, AnimationFinishedCallback c
_motionState = ready; _motionState = ready;
_animationFinishedCallback = callback; _animationFinishedCallback = callback;
_animationLoop = loop; _animationLoop = loop;
_curTexIndex = 0;
// for (int i = 0; i < _curMotion.png_names.size(); ++i) // for (int i = 0; i < _curMotion.png_names.size(); ++i)