File tree Expand file tree Collapse file tree 7 files changed +51
-10
lines changed
src/main/java/com/amplifyframework/ui/liveness Expand file tree Collapse file tree 7 files changed +51
-10
lines changed Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ public final class com/amplifyframework/ui/liveness/BuildConfig {
22 public static final field BUILD_TYPE Ljava/lang/String;
33 public static final field DEBUG Z
44 public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String;
5+ public static final field LIVENESS_VERSION_NAME Ljava/lang/String;
56 public static final field VERSION_NAME Ljava/lang/String;
67 public fun <init> ()V
78}
Original file line number Diff line number Diff line change @@ -12,6 +12,11 @@ android {
1212 arguments + = " -DCMAKE_VERBOSE_MAKEFILE=ON"
1313 }
1414 }
15+ buildConfigField(
16+ " String" ,
17+ " LIVENESS_VERSION_NAME" ,
18+ " \" ${project.properties[" VERSION_NAME" ]} \" "
19+ )
1520 testInstrumentationRunner = " androidx.test.runner.AndroidJUnitRunner"
1621 }
1722
Original file line number Diff line number Diff line change @@ -20,6 +20,7 @@ import android.graphics.Bitmap
2020import android.util.Size
2121import androidx.camera.core.ImageAnalysis
2222import androidx.camera.core.ImageProxy
23+ import com.amplifyframework.core.Amplify
2324import com.amplifyframework.ui.liveness.ml.FaceDetector
2425import com.amplifyframework.ui.liveness.ml.FaceOval
2526import com.amplifyframework.ui.liveness.state.LivenessState
@@ -42,7 +43,20 @@ internal class FrameAnalyzer(
4243 private var cachedBitmap: Bitmap ? = null
4344 private var faceDetector = FaceDetector (livenessState)
4445
46+ private val logger = Amplify .Logging .forNamespace(" Liveness" )
47+
4548 override fun analyze (image : ImageProxy ) {
49+ try {
50+ attemptAnalyze(image)
51+ } catch (e: Exception ) {
52+ // We've seen a few instances of exceptions thrown by copyPixelsFromBuffer.
53+ // This indicates the image received may have been in an unexpected format.
54+ // We discard this frame, in hopes that the next frame is readable.
55+ logger.error(" Failed to analyze frame" , e)
56+ }
57+ }
58+
59+ private fun attemptAnalyze (image : ImageProxy ) {
4660 if (cachedBitmap == null ) {
4761 cachedBitmap = Bitmap .createBitmap(
4862 image.width,
Original file line number Diff line number Diff line change @@ -180,7 +180,7 @@ internal class LivenessCoordinator(
180180 sessionId,
181181 faceLivenessSessionInformation,
182182 faceLivenessSessionOptions,
183- BuildConfig .VERSION_NAME ,
183+ BuildConfig .LIVENESS_VERSION_NAME ,
184184 { livenessState.onLivenessSessionReady(it) },
185185 {
186186 disconnectEventReceived = true
Original file line number Diff line number Diff line change @@ -19,6 +19,7 @@ import android.media.MediaCodec
1919import android.media.MediaFormat
2020import android.media.MediaMuxer
2121import androidx.annotation.WorkerThread
22+ import com.amplifyframework.core.Amplify
2223import java.io.File
2324import java.io.RandomAccessFile
2425import java.nio.ByteBuffer
@@ -48,6 +49,8 @@ internal class LivenessMuxer(
4849 currentVideoStartTime = System .currentTimeMillis()
4950 }
5051
52+ private val logger = Amplify .Logging .forNamespace(" Liveness" )
53+
5154 /*
5255 Attempt to notify listener that chunked data is available if minimum chunk interval has exceeded
5356 Write new frame to muxer
@@ -61,7 +64,13 @@ internal class LivenessMuxer(
6164 }
6265 }
6366
64- muxer.writeSampleData(videoTrack, byteBuf, bufferInfo)
67+ try {
68+ muxer.writeSampleData(videoTrack, byteBuf, bufferInfo)
69+ } catch (e: Exception ) {
70+ // writeSampleData can throw for various reasons, such as an empty byte buffer.
71+ // If this happens, we discard the frame, in hopes that future frames are valid.
72+ logger.error(" Failed to write encoded chunk to muxer" , e)
73+ }
6574 }
6675
6776 @WorkerThread
Original file line number Diff line number Diff line change @@ -24,6 +24,7 @@ import android.os.Handler
2424import android.os.HandlerThread
2525import android.util.Log
2626import androidx.annotation.WorkerThread
27+ import com.amplifyframework.core.Amplify
2728import com.amplifyframework.ui.liveness.util.isKeyFrame
2829import java.io.File
2930
@@ -124,6 +125,7 @@ internal class LivenessVideoEncoder private constructor(
124125
125126 private var encoding = false
126127 private var livenessMuxer: LivenessMuxer ? = null
128+ private val logger = Amplify .Logging .forNamespace(" Liveness" )
127129
128130 init {
129131 encoder.start()
@@ -152,11 +154,18 @@ internal class LivenessVideoEncoder private constructor(
152154
153155 if (info.isKeyFrame()) {
154156 if (livenessMuxer == null ) {
155- livenessMuxer = LivenessMuxer (
156- outputFile,
157- encoder.outputFormat,
158- onMuxedSegment
159- )
157+ try {
158+ val muxer = LivenessMuxer (
159+ outputFile,
160+ encoder.outputFormat,
161+ onMuxedSegment
162+ )
163+ livenessMuxer = muxer
164+ } catch (e: Exception ) {
165+ // This is likely an unrecoverable error, such as file creation failing.
166+ // However, if it fails, we will allow another attempt at the next keyframe.
167+ logger.error(" Failed to create liveness muxer" , e)
168+ }
160169 }
161170 framesSinceSyncRequest = 0 // reset keyframe request on keyframe receipt
162171 } else {
Original file line number Diff line number Diff line change @@ -134,9 +134,12 @@ fun FaceLivenessDetector(
134134 },
135135 onChallengeFailed = {
136136 scope.launch {
137- isFinished = true
138- resetOrientation()
139- currentOnError.accept(it)
137+ // if we are already finished, we already provided a result in complete or failed
138+ if (! isFinished) {
139+ isFinished = true
140+ resetOrientation()
141+ currentOnError.accept(it)
142+ }
140143 }
141144 }
142145 )
You can’t perform that action at this time.
0 commit comments