Skip to content

Commit edc001a

Browse files
committed
feat: Add onShutter event
1 parent a66cdae commit edc001a

File tree

14 files changed

+60
-3
lines changed

14 files changed

+60
-3
lines changed

package/android/src/main/java/com/mrousavy/camera/CameraView+Events.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ fun CameraView.invokeOnStopped() {
3737
this.sendEvent(event)
3838
}
3939

40+
fun CameraView.invokeOnShutter() {
41+
Log.i(CameraView.TAG, "invokeOnShutter()")
42+
43+
val surfaceId = UIManagerHelper.getSurfaceId(this)
44+
val event = CameraShutterEvent(surfaceId, id)
45+
this.sendEvent(event)
46+
}
47+
4048
fun CameraView.invokeOnError(error: Throwable) {
4149
Log.e(CameraView.TAG, "invokeOnError(...):")
4250
error.printStackTrace()

package/android/src/main/java/com/mrousavy/camera/CameraView+TakeSnapshot.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ fun CameraView.takeSnapshot(options: SnapshotOptions): WritableMap {
1313
Log.i(TAG, "Capturing snapshot of Camera View...")
1414
val bitmap = previewView.bitmap ?: throw SnapshotFailedError()
1515

16+
onShutter()
17+
1618
val file = FileUtils.createTempFile(context, "jpg")
1719
FileUtils.writeBitmapTofile(bitmap, file, options.quality)
1820

package/android/src/main/java/com/mrousavy/camera/CameraView.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ class CameraView(context: Context) :
277277
invokeOnStopped()
278278
}
279279

280+
override fun onShutter() {
281+
invokeOnShutter()
282+
}
283+
280284
override fun onCodeScanned(codes: List<Barcode>, scannerFrame: CodeScannerFrame) {
281285
invokeOnCodeScanned(codes, scannerFrame)
282286
}

package/android/src/main/java/com/mrousavy/camera/CameraViewManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class CameraViewManager : ViewGroupManager<CameraView>() {
3232
.put("cameraInitialized", MapBuilder.of("registrationName", "onInitialized"))
3333
.put("cameraStarted", MapBuilder.of("registrationName", "onStarted"))
3434
.put("cameraStopped", MapBuilder.of("registrationName", "onStopped"))
35+
.put("cameraShutter", MapBuilder.of("registrationName", "onShutter"))
3536
.put("cameraError", MapBuilder.of("registrationName", "onError"))
3637
.put("cameraCodeScanned", MapBuilder.of("registrationName", "onCodeScanned"))
3738
.build()

package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
430430
photoOutput.targetRotation = outputOrientation.toDegrees()
431431
val playSound = enableShutterSound || CameraInfo.mustPlayShutterSound()
432432

433-
val image = photoOutput.takePicture(playSound, CameraQueues.cameraExecutor)
433+
val image = photoOutput.takePicture(playSound, callback, CameraQueues.cameraExecutor)
434434
val isMirrored = camera.cameraInfo.lensFacing == CameraSelector.LENS_FACING_FRONT
435435
return Photo(image, isMirrored)
436436
}
@@ -524,6 +524,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
524524
fun onInitialized()
525525
fun onStarted()
526526
fun onStopped()
527+
fun onShutter()
527528
fun onCodeScanned(codes: List<Barcode>, scannerFrame: CodeScannerFrame)
528529
}
529530
}

package/android/src/main/java/com/mrousavy/camera/extensions/ImageCapture+takePicture.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import android.media.MediaActionSound
44
import androidx.camera.core.ImageCapture
55
import androidx.camera.core.ImageCaptureException
66
import androidx.camera.core.ImageProxy
7+
import com.mrousavy.camera.core.CameraSession
78
import java.util.concurrent.Executor
89
import kotlin.coroutines.resume
910
import kotlin.coroutines.resumeWithException
1011
import kotlinx.coroutines.suspendCancellableCoroutine
1112

12-
suspend inline fun ImageCapture.takePicture(enableShutterSound: Boolean, executor: Executor): ImageProxy =
13+
suspend inline fun ImageCapture.takePicture(enableShutterSound: Boolean, callback: CameraSession.Callback, executor: Executor): ImageProxy =
1314
suspendCancellableCoroutine { continuation ->
1415
// Shutter sound
1516
val shutterSound = if (enableShutterSound) MediaActionSound() else null
@@ -23,6 +24,8 @@ suspend inline fun ImageCapture.takePicture(enableShutterSound: Boolean, executo
2324
if (enableShutterSound) {
2425
shutterSound?.play(MediaActionSound.SHUTTER_CLICK)
2526
}
27+
28+
callback.onShutter()
2629
}
2730

2831
override fun onCaptureSuccess(image: ImageProxy) {

package/android/src/main/java/com/mrousavy/camera/types/Events.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ class CameraStoppedEvent(surfaceId: Int, viewId: Int) : Event<CameraStoppedEvent
1919
override fun getEventData(): WritableMap = Arguments.createMap()
2020
}
2121

22+
class CameraShutterEvent(surfaceId: Int, viewId: Int) : Event<CameraShutterEvent>(surfaceId, viewId) {
23+
override fun getEventName() = "cameraShutter"
24+
override fun getEventData(): WritableMap = Arguments.createMap()
25+
}
26+
2227
class CameraErrorEvent(surfaceId: Int, viewId: Int, private val data: WritableMap) : Event<CameraErrorEvent>(surfaceId, viewId) {
2328
override fun getEventName() = "cameraError"
2429
override fun getEventData() = data

package/ios/CameraView+TakeSnapshot.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ extension CameraView {
3030
// capture was already aborted (timed out)
3131
return
3232
}
33+
34+
self.onCaptureShutter()
3335

3436
guard let imageBuffer = CMSampleBufferGetImageBuffer(buffer) else {
3537
promise.reject(error: .capture(.imageDataAccessError))

package/ios/CameraView.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public final class CameraView: UIView, CameraSessionDelegate {
6262
@objc var onError: RCTDirectEventBlock?
6363
@objc var onStarted: RCTDirectEventBlock?
6464
@objc var onStopped: RCTDirectEventBlock?
65+
@objc var onShutter: RCTDirectEventBlock?
6566
@objc var onViewReady: RCTDirectEventBlock?
6667
@objc var onCodeScanned: RCTDirectEventBlock?
6768
// zoom
@@ -328,6 +329,13 @@ public final class CameraView: UIView, CameraSessionDelegate {
328329
}
329330
onStopped([:])
330331
}
332+
333+
func onCaptureShutter() {
334+
guard let onShutter = onShutter else {
335+
return
336+
}
337+
onShutter([:])
338+
}
331339

332340
func onFrame(sampleBuffer: CMSampleBuffer) {
333341
#if VISION_CAMERA_ENABLE_FRAME_PROCESSORS

package/ios/CameraViewManager.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ @interface RCT_EXTERN_REMAP_MODULE (CameraView, CameraViewManager, RCTViewManage
5555
RCT_EXPORT_VIEW_PROPERTY(onInitialized, RCTDirectEventBlock);
5656
RCT_EXPORT_VIEW_PROPERTY(onStarted, RCTDirectEventBlock);
5757
RCT_EXPORT_VIEW_PROPERTY(onStopped, RCTDirectEventBlock);
58+
RCT_EXPORT_VIEW_PROPERTY(onShutter, RCTDirectEventBlock);
5859
RCT_EXPORT_VIEW_PROPERTY(onViewReady, RCTDirectEventBlock);
5960
// Code Scanner
6061
RCT_EXPORT_VIEW_PROPERTY(codeScannerOptions, NSDictionary);

0 commit comments

Comments
 (0)