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

Record Videos with Custom Builder #385

Closed kyrill-bo closed 10 months ago

kyrill-bo commented 10 months ago

Hello, i need some help. I don't get it, how to start and stop recording Video with own Widgets.

What i mean is: I have a Button, if i hold press on it, i wan't to start recording a video. and if 5 seconds are over or the button is released it should stop it. After that i wan't to return it as a xfile.

how can i do that?

would be very thankful for any kind of help.

here is my code:

 CameraAwesomeBuilder.custom(
        progressIndicator: _skeleton(),
        builder: (cameraState, previewSize, previewRect) {
          return Stack(
            alignment: Alignment.center,
            children: [
              ...
              Positioned(
                bottom: 20,
                // child: AwesomeCaptureButton(
                //   state: cameraState,
                // ),
                child: inProcess
                    ? const CircularProgressIndicator()
                    : GestureDetector(
                        onTap: () {
                          setState(() {
                            inProcess = true;
                          });
                          cameraState.when(
                            onPhotoMode: (p0) {
                              shotPhoto(p0);
                            },
                          );
                        },
                        onLongPress: () {
                          if (cameraState.captureMode == CaptureMode.photo) {
                            cameraState.setState(CaptureMode.video);
                          }
                          setState(() {
                            videoRecording = true;
                          });
                          cameraState.when(
                            onVideoMode: (state) {
                              state.startRecording();
                            },
                          );
                          // after 5 stop record
                          timer = Timer(const Duration(seconds: 5), () {
                            setState(() {
                              videoRecording = false;
                            });
                          });
                        },
                        onLongPressEnd: (details) {
                          setState(() {
                            videoRecording = false;
                          });
                          timer!.cancel();
                          cameraState.when(
                            onVideoRecordingMode: (p0) {
                              p0.stopRecording();
                            },
                          );
                          if (cameraState.captureMode == CaptureMode.video) {
                            cameraState.setState(CaptureMode.photo);
                          }
                        },
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(45),
                          child: Shimmer(
                            duration: const Duration(seconds: 1),
                            interval: const Duration(seconds: 1),
                            color: Theme.of(context).colorScheme.primary,
                            child: Stack(
                              children: [
                                Container(
                                  width: 70,
                                  height: 70,
                                  decoration: BoxDecoration(
                                    color: Colors.black.withOpacity(0.15),
                                    borderRadius: BorderRadius.circular(45),
                                    // color: Theme.of(context).colorScheme.background,
                                  ),
                                  child: const Icon(
                                    Icons.camera_alt_outlined,
                                    color: Colors.white,
                                    size: 40,
                                  ),
                                ),
                                if (videoRecording)
                                  const SimpleCircularProgressBar(
                                    size: 70,
                                    animationDuration: 5,
                                    mergeMode: true,
                                    progressColors: [
                                      Colors.red,
                                    ],
                                  ),
                              ],
                            ),
                          ),
                        ),
                      ),
              ),
            ],
          );
        },
        ...

this is how i did it for photos:

shotPhoto(PhotoCameraState cameraState) async {
    photos.clear();
    if (both == false) {
      await cameraState.takePhoto().then((value) {
        value.when(
          single: (p0) async {
            photos.add(p0.file!);
          },
        );
      });
    } else {
      await cameraState.takePhoto().then((value) {
        value.when(
          single: (p0) async {
            photos.add(p0.file!);
          },
        );
      });
      await cameraState.switchCameraSensor().then((value) async {
        await cameraState.takePhoto().then((value) {
          value.when(single: (p0) async {
            photos.add(p0.file!);
          });
        });
      });
    }
    await finish().then((value) {
      setState(() {
        inProcess = false;
      });
    });
  }
g-apparence commented 10 months ago

Hi you should taking a look at our premade UI here

Just use the state.when to handle the use cases. You don't need to change from video state to recording state. That's all the beauty of using an orchestrator. We do that for you.

get onTap => () {
        widget.state.when(
          onPhotoMode: (photoState) => photoState.takePhoto(),
          onVideoMode: (videoState) => videoState.startRecording(),
          onVideoRecordingMode: (videoState) => videoState.stopRecording(),
        );
      };
kyrill-bo commented 10 months ago

@g-apparence ok. i removed the state change ...

onLongPress: () {
  setState(() {
    videoRecording = true;
  });
  cameraState.when(
    onVideoMode: (state) {
      state.startRecording();
    },
  );
  // after 5 stop record
  timer = Timer(const Duration(seconds: 5), () {
    setState(() {
      videoRecording = false;
    });
    cameraState.when(
      onVideoRecordingMode: (state) {
        state.stopRecording();
      },
    );
  });
},
onLongPressEnd: (details) {
  setState(() {
    videoRecording = false;
  });
  timer!.cancel();
  cameraState.when(
    onVideoRecordingMode: (p0) {
      p0.stopRecording();
    },
  );
},

how and where do i get the video now as xfile in return?

or is it handled in the save config?

saveConfig: SaveConfig.photoAndVideo(
          videoOptions: VideoOptions(
            enableAudio: true,
          ),
          videoPathBuilder: (sensors) async {
            final Directory? extDir = await getDownloadsDirectory();
            final testDir = await Directory('${extDir!.path}/camerawesome')
                .create(recursive: true);
            final String filePath =
                '${testDir.path}/${DateTime.now().millisecondsSinceEpoch}.mp4';
            return SingleCaptureRequest(filePath, sensors.first);
          },
        ),
g-apparence commented 10 months ago

That's it. You can handle that in the saveConfig

kyrill-bo commented 10 months ago

After stopRecording nothing happens there is no video stored, what could be the reason? (no, error logs)

pujakhalika commented 10 months ago

@kyrill-bo According to the documentation from path_provider, maybe you should replace getDownloadsDectory with getTemporaryDirectory when using an Android Device. The getDowloadsDirectory not supported for android platform. Check this : https://pub.dev/packages/path_provider

tiltmaster commented 5 months ago

After stopRecording nothing happens there is no video stored, what could be the reason? (no, error logs)

how did u let the user automatically pop from recording? meaning after 5 seconds are you automatically redirecting the user to a video preview page automatically ?