cordova-plugin-camera icon indicating copy to clipboard operation
cordova-plugin-camera copied to clipboard

Add support for recording video

Open jschillingApollo opened this issue 1 year ago • 8 comments

Feature Request

Motivation Behind Feature

Currently to build an app that can take pictures and record video, a user has to use a camera specific plugin such as this one and a separate video recording plugin such as @awesome-cordova-plugins/media-capture. These plugins do not operate in too similar a fashion when recording and storing media. It would be very convenient and useful to have both picture and video recording capabilities in one plugin and this camera plugin already has a lot of great configurable options.

Feature Description

  • Add a new method to the camera class called getVideo(successCallback, errorCallback, options) that accepts similar parameters to the getPicture method including the CameraOptions object.
  • Allow video to be stored to temporary app storage using the saveToPhotoAlbum boolean option.
  • Potentially extend the CameraOptions interface for video specific options if necessary.

Alternatives or Workarounds

Two plugins are required at this time to have both picture and video recording functionality (@awesome-cordova-plugins/camera and @awesome-cordova-plugins/media-capture for example).

This camera plugin gives great options for recording and storing pictures, particularly allowing the developer to save the image file to temporary app storage with the saveToPhotoAlbum camera option. Something to note, there is a mediaType for VIDEO in the cameraOptions but it does not do what it seems like it should do and captures/stores an image file.

The media-capture plugin is an option for recording video but it lacks a few of the useful features that the camera plugin offers. Namely it has less options and doesn't allow the user to store the video file anywhere other than the photo gallery.

jschillingApollo avatar Nov 09 '22 18:11 jschillingApollo

Something to note, there is a mediaType for VIDEO in the cameraOptions but it does not do what it seems like it should do and captures/stores an image file.

You mean captures/stores a video file? You expect that you'll be able to the camera plugin to record a video (instead of selecting an existing one) and the camera plugin currently does not allow that?

breautek avatar Nov 09 '22 19:11 breautek

You mean captures/stores a video file? You expect that you'll be able to the camera plugin to record a video (instead of selecting an existing one) and the camera plugin currently does not allow that?

That's correct. The plugin currently allows for capturing a picture and storing it as an image file as well as selecting image or video files from the device storage, but it would be very nice if it also had the functionality to capture a video and store it as a video file either to the gallery or temporary app storage (using the saveToPhotoAlbum boolean option).

I admit that I started from the Ionic plugin docs site for this Camera plugin and it mentions at the very top of the documentation that the plugin can be used to "Take a photo or capture video" but it seems like this may be a mistake or generalization of what the plugin actually supports in regards to video.

I see that the mediaType option allows for choosing the type of media file allowed to be selected and not necessarily which type to capture. However, I believe this would still be incredibly useful functionality to add to the plugin.

jschillingApollo avatar Nov 10 '22 20:11 jschillingApollo

I'm not stating this with full confidence but support may depend on the underlying Camera application on the device.

We utilise the Intent system, as recommended by Android to avoid declaring privacy "dangerous" permissions. This allows us to delegate the task to to the user's preferred application which already contains the aforementioned permissions. User may see an app list to select from if they have more than 1 app capable and no preferred configuration. Broadly speaking, the flow is that we delegate the task, the Camera application opens up, and the user uses the application to snap the picture or whatever, and the application provides the data back in some fashion, generally providing an URL to a locally saved file that the application can use.

But the drawback of this intent system is different applications have different UI, different settings and all of this is generally not configurable. So it is possible that support for recording video does exist, but is simply not exposed by the Camera application that the device is using. Again, not stating this with full confidence, but there have been similar issues observed in the past, e.g. Android's allowEdit quirk.

Honestly not familiar how iOS behaves at all on this. I've been assuming that you've been working with Android, but can you tell us which platforms you're seeing this current behavour?

breautek avatar Nov 10 '22 21:11 breautek

That makes sense to me. I am not incredibly familiar with Android or iOS native development either unfortunately, but I am aware of the Intent system on Android. I'd assume the functionality for video recording via the device's default camera app exists for both platforms, but that is pure conjecture.

The app that I am currently developing and maintaining is on both Android and iOS platforms. Currently my app makes use of both camera and media-capture plugins for taking photos and recording video respectively.

jschillingApollo avatar Nov 10 '22 23:11 jschillingApollo

Though this is terribly simplified and vague, I did locate some potentially useful documentation regarding the Android Intent that is used for opening the camera in video mode. The specific intent is called INTENT_ACTION_VIDEO_CAMERA.

And for iOS it looks like it is definitely possible using the AVFoundation framework.

jschillingApollo avatar Nov 11 '22 00:11 jschillingApollo

It may not be related, but I think the reason why there are two plugins instead of combining the functionality into one plugin is because of permissions.

The camera plugin only uses this permission:

  • android.permission.WRITE_EXTERNAL_STORAGE

The media capture plugin uses these permissions:

  • android.permission.RECORD_AUDIO
  • android.permission.READ_EXTERNAL_STORAGE
  • android.permission.WRITE_EXTERNAL_STORAGE

Ignoring READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE, I beleive the main difference was RECORD_AUDIO.

Generally, I think it is not recommended to request for permissions that are not needed. For example, a QR code app might need access to the camera, but it should not need permissions to record audio. End-users may be concered if they see the app requires recording audio when the believe it is privacy evasive.

It is true that there is an overlap between camera and media-capture plugin.

Some extra notes: READ_EXTERNAL_STORAGE is no longer used in API 33.

If your app accesses other apps' media files, request one or more of these permissions instead: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO.

This means there probally should be some updates to media-capture plugin. :D

erisu avatar Nov 11 '22 03:11 erisu

The media-capture plugin actually supports capturing images, video, and audio each separately and it only prompts for the required permissions when and if the app makes use of one of those methods. In our case we are using it for video and it only prompts for audio and camera permissions when we first open the camera in video mode using the related method.

I had looked through the issues for the media-capture plugin and it looks like there have been requests to add better storage options (specifically to allow temporary app storage, similar to cordova-plugin-camera) but there has been no movement on that for a long time. On that same note, I agree that the media-capture plugin definitely needs to update regarding the change in required permissions but I'm not confident that will happen in the near future 😅 .

jschillingApollo avatar Nov 14 '22 15:11 jschillingApollo

This is actually possible with current cordova-plugin-camera

Just have to change the following function in CDVCamera.m

+ (instancetype) createFromPictureOptions:(CDVPictureOptions*)pictureOptions;
{
    CDVCameraPicker* cameraPicker = [[CDVCameraPicker alloc] init];
    cameraPicker.pictureOptions = pictureOptions;
    cameraPicker.sourceType = pictureOptions.sourceType;
    cameraPicker.allowsEditing = pictureOptions.allowsEditing;

    if (cameraPicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
        // We only allow taking pictures (no video) in this API.
        cameraPicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:cameraPicker.sourceType];
        // We can only set the camera device if we're actually using the camera.
        cameraPicker.cameraDevice = pictureOptions.cameraDirection;
        cameraPicker.videoQuality = UIImagePickerControllerQualityTypeHigh;
    } else if (pictureOptions.mediaType == MediaTypeAll) {
        cameraPicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:cameraPicker.sourceType];
    } else {
        NSArray* mediaArray = @[(NSString*)(pictureOptions.mediaType == MediaTypeVideo ? kUTTypeMovie : kUTTypeImage)];
        cameraPicker.mediaTypes = mediaArray;
    }

    return cameraPicker;
}

escully27 avatar Apr 03 '24 01:04 escully27