Apparence-io / CamerAwesome

📸 Embedding a camera experience within your own app shouldn't be that hard. A flutter plugin to integrate awesome Android / iOS camera experience.
https://ApparenceKit.dev
MIT License
910 stars 199 forks source link

onMediatap not triggered (v2.0.0+1 ) #418

Closed millerf closed 7 months ago

millerf commented 7 months ago

Steps to Reproduce

Smaller issue: AwesomeZoomSelector is not displayed on iOS, but it is on Android...

Expected results

Actual results

About your device

CameraAwesome version

camerawesome 2.0.0+1 

Your flutter version

Run this in your command line

Flutter 3.16.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 7f20e5d18c (4 days ago) • 2023-11-27 09:47:30 -0800
Engine • revision 22b600f240
Tools • Dart 3.2.1 • DevTools 2.28.3

Test widget


class CameraAwesome extends StatelessWidget {
  Null Function(File file) onMediaTap;
  Null Function() onCloseButtonTapped;
  Null Function() onGalleryTapped;

  CameraAwesome(
      {super.key,
      required this.onMediaTap,
      required this.onGalleryTapped,
      required this.onCloseButtonTapped});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CameraAwesomeBuilder.awesome(
        saveConfig: SaveConfig.photo(),
        sensorConfig: SensorConfig.single(
            sensor: Sensor.position(SensorPosition.back),
            aspectRatio: CameraAspectRatios.ratio_16_9),
        previewFit: CameraPreviewFit.fitWidth,
        previewAlignment: Alignment.center,
        availableFilters: const [],
        onMediaTap: (MediaCapture mediaCapture) {
/// THIS IS NEVER TRIGGERED
          getLogger().w('MediaTap');
          mediaCapture.captureRequest.when(single: (single) {
            onMediaTap(File(single.file!.path));
          });
/// THIS IS NEVER TRIGGERED

        },
        topActionsBuilder: (state) {
          return const SizedBox.shrink();
        },
        middleContentBuilder: (state) {
          return Column(children: [
            const Spacer(),
            AwesomeZoomSelector(state: state),
            SizedBox(
              height: 5 * MARGIN_SIDE,
            )
          ]);
        },
        bottomActionsBuilder: (state) => AwesomeBottomActions(
          state: state,
          left: GestureDetector(
            child: AwesomeCircleWidget.icon(
              icon: Icons.close,
            ),
            onTap: onCloseButtonTapped,
          ),
          right:
              AwesomeFilterButton(state: state, onFilterTap: onGalleryTapped),
        ),
      ),
    );
    ;
  }
}
g-apparence commented 7 months ago

Hi, Could you add the "enablePhysicalButton: true," property and test again plz ?

millerf commented 7 months ago

Hi, Could you add the "enablePhysicalButton: true," property and test again plz ?

No difference. I actually tried before (and just tried again).

My logs from Android in debug, before/after clicking the "shutter" button (the big white "take a photo" button)

D/ImageCapture( 7767): clearPipeline
D/ImageCapture( 7767): createPipeline(cameraId: 0, streamSpec: StreamSpec{resolution=1280x720, dynamicRange=DynamicRange@9649b9{encoding=SDR, bitDepth=8}, expectedFrameRateRange=[0, 0], implementationOptions=androidx.camera.camera2.impl.Camera2ImplConfig@fcbf2af})
D/SessionLifecycleClient( 7767): Sending lifecycle 2 to service
D/SessionLifecycleService( 7767): Activity backgrounding at 209886840
D/ImageCapture( 7767): clearPipeline
D/ImageCapture( 7767): createPipeline(cameraId: 0, streamSpec: StreamSpec{resolution=1280x720, dynamicRange=DynamicRange@9649b9{encoding=SDR, bitDepth=8}, expectedFrameRateRange=[0, 0], implementationOptions=androidx.camera.camera2.impl.Camera2ImplConfig@fb78833})
W/omad.park.front( 7767): Long monitor contention with owner CameraX-core_camera_0 (8096) at void android.hardware.camera2.impl.CameraDeviceImpl.close()(CameraDeviceImpl.java:1434) waiters=0 in void android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks.onCaptureStarted(android.hardware.camera2.impl.CaptureResultExtras, long) for 134ms
D/EGL_emulation( 7767): app_time_stats: avg=22.07ms min=0.84ms max=414.71ms count=38
D/com.apparence.camerawesome.cameraX.CameraPermissions( 7767): _onRequestPermissionsResult: received permissions but the EventSink is closed
D/SessionLifecycleClient( 7767): Sending lifecycle 1 to service
D/SessionLifecycleService( 7767): Activity foregrounding at 209888019.
D/EGL_emulation( 7767): app_time_stats: avg=389443.62ms min=0.94ms max=5841633.00ms count=15
D/SessionLifecycleClient( 7767): Sending lifecycle 2 to service
D/SessionLifecycleService( 7767): Activity backgrounding at 209888338
D/com.apparence.camerawesome.cameraX.CameraPermissions( 7767): _onRequestPermissionsResult: received permissions but the EventSink is closed
D/SessionLifecycleClient( 7767): Sending lifecycle 1 to service
D/SessionLifecycleService( 7767): Activity foregrounding at 209888486.
D/EGL_emulation( 7767): app_time_stats: avg=39.28ms min=2.06ms max=132.14ms count=25
D/EGL_emulation( 7767): app_time_stats: avg=33.33ms min=32.48ms max=34.16ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.88ms min=17.35ms max=49.71ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.89ms min=31.09ms max=49.90ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.90ms min=18.20ms max=49.81ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.88ms min=31.83ms max=49.47ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.89ms min=31.81ms max=50.46ms count=30
D/ImageCapture( 7767): takePictureInternal
D/TakePictureManager( 7767): Issue the next TakePictureRequest.
D/TakePictureManager( 7767): Issue the next TakePictureRequest.
D/TakePictureManager( 7767): No new request.
D/EGL_emulation( 7767): app_time_stats: avg=28.68ms min=1.62ms max=103.68ms count=31
D/EGL_emulation( 7767): app_time_stats: avg=33.87ms min=31.50ms max=50.51ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.88ms min=19.14ms max=65.46ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.88ms min=31.33ms max=50.94ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.87ms min=17.95ms max=51.03ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.87ms min=10.83ms max=55.94ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.89ms min=32.28ms max=50.69ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.89ms min=31.55ms max=50.59ms count=30
D/EGL_emulation( 7767): app_time_stats: avg=33.90ms min=31.78ms max=50.24ms count=30

Screenshot:

Screenshot 2023-12-01 at 15 09 53
g-apparence commented 7 months ago

PLease try this on a real device. Emulator is quite buggy with cameraX

millerf commented 7 months ago

I found the "issue"... I tried with a minimal setup:

Scaffold(
      body: CameraAwesomeBuilder.awesome(
        enablePhysicalButton: true,
        saveConfig: SaveConfig.photo(),
        onMediaTap: (MediaCapture mediaCapture) {
          getLogger().w('MediaTap');
          mediaCapture.captureRequest.when(single: (single) {
            onMediaTap(File(single.file!.path));
          });
        },
  )
);

And got it to trigger when "tapping on the small media preview" 😅

Screenshot 2023-12-01 at 15 16 11

I guess I got confused before.

So how can I retrieve the captured file if I do not want the preview to be displayed?

millerf commented 7 months ago

Found it. For the record, the data is in the state.captureState$ stream...

CameraAwesomeBuilder.custom(
  saveConfig: SaveConfig.photo(),
  builder: (state, previewSize, previewRect) {
    state.captureState$.listen(
      /// Do stuff here 
   )
  },
)
millerf commented 7 months ago

Please try this on a real device. Emulator is quite buggy with cameraX

I also tried on IOS simulator and real iOS device. Same issue. I believe you should trigger onMediaTap if AwesomeMediaPreview is not displayed...

Do you want to do it that way? If so, I am happy to do a PR... There is some great work in this lib!